①②③Git 版本控制入門(5)

Beginning Git: Ep. 11 ~ 13 — Syncing with a Remote,Pull Requests,Conclusion

Min
16 min readJan 11, 2024

接續上一篇:

線上課程資源:

以下跟著課程實做用 zsh 練習 git。

Ep. 11 Syncing with a Remote

通過將 local repo push 到 remote ,或將 remote pull 到 Local 編輯,可以同步本機跟雲端的 repo。但有個情況可能無法這麼順利,就是我們在local 有了新的 Commit 之後,卻有人在 remote 裡也新增了 Commit。

該怎麼辦?

將別人新增的 Remote commit 一到 local 內,作為自己上次從 remote pull 下來時間點上的 commit 的分支。因此自己的新 commit 在 master branch 上,別人的 local commit 屬於 origin/master 分支。將這兩個分支 merge,再 push 回 remote repo。

Push

先從 push 開始。

git remote -v 顯示 Git repository 配置的所有remote repo 的列表:

git branch -vv 顯示 repository 中所有 branch 的詳細資訊,包含每個 branch 的最新 commit:

git branch -vv

可看到目前位於 master 中,它跟蹤的是 origin/master 的 remote branch。master 分支在 local 有 16 個 commit 尚未被 push 到 remote branch:

加上--all 顯示包含 remote branch 的所有 branch:

git branch -vv --all

git log --oneline 看到 master 已經離 origin/master 有多遠:

數了一下還真的是 16 個 commit

git push origin master 將 master 分支 push 到 origin master:

成功!

git log --oneline 可看到最新一行的 HEAD 指向 master 與 origin/master,他們在同一個位置:

git branch -vv — all 則看到 master 正在追蹤 origin/master,並沒有超前:

回到 github 專案,點擊 Commit 看紀錄,可以看到最近的 commit 都更新上去:

Pull

Pulling 其實是 fetch 與 merge 的集合。 fetch 獲取 remote branch 上的更改,並將它們 merge 到 local branch。

如果我們的 branch 追蹤著 remote branch,那 pulling 的動作會自動完成 fetch 與 merge 這兩件事。

But,總是有個 but,有一些情況是無法這樣運作的。我們可以有不只一個 remote 跟 repo 關聯。預設的情況與我們通常只有一個,就是 origin。但當多人在開發同一個東西,而我們想在某人的 commits push 到 origin 之前使用它,我們可以 fork 當作另一個 remote。每次增加一個 remote,只是增加一個額外的 remote branch 到我們已存在的 Repo 中。

等會會看到我們如何在 local repo 中增加額外的 remote,與 merge 從其他 remote 來的額外的改變。

先加入新的 remote:

git remote add 名稱 網址

git remote -v 確認現有的 remote:

使用 git log --oneline --decorate --all --graph 檢查 commits,發現沒有變化:

原來我們只加了 remote,但還沒有請求 fetch 它的任何 commit。

使用 git fetch iwantmyrealname 獲取 iwantmyrealname 最新的 commit 與 Branch 資訊:

git fetch remote名稱

看到新增了兩個 branches:

再次使用 git log --oneline --decorate --all --graph ,看到畫面中除了原本的 commits ,多了兩個分支, 中段有 iwantmyrealname/master,下方不遠有 iwantmyrealname/clickbait。

目標是將這些 commits merge 到 local repository 中。

git remote show origin 提供關於 origin 的細節:

git remote show origin

git remote show iwantmyrealname :

由於先前已經刪除了 clickbait,用 git checkout --track origin/clickbait 新建一個追蹤 origin/clickbait 的 local 分支 clickbait。

git checkout - track origin/clickbait

在合併 iwantmyrealname 到 local clickbait 分支前,先 git log --oneline --graph --all 查看目前分支狀態。

git merge iwantmyrealname/clickbait merge branch,遇到 fix merge conflict,修改檔案內容。

git log --oneline --graph --all 查看剛剛完成的解決 merge 衝突:

git checkout master 回到 master branch,git merge clickbait 將 clickbait 合併到 Master,出現文字編輯畫面:

加上說明後儲存退出:

git log --oneline --graph --all 可看到 local clickbait 現在 merge 到 local master 分支上,並包含了之前的 iwantmyrealname/clickbait 的合併:

本課挑戰

將 iwantmyrealname remote merge 到 master branch,並 push 到 origin。

git fetch iwantmyrealname 之後,git merge iwantmyrealname/master 出現文字編輯,不寫後關上:

git log --oneline --graph --all 可看到又多一條支線進來 master

git push 上傳到 Github:

看到 commit 的資料:

Ep. 11 重點 git 指令

git branch -vv     顯示repository 中所有 branch 的詳細資訊,包含每個 branch 的最新 commit
git branch -vv --all 顯示所有本地分支和遠端分支,以及它們之間的追蹤關係。包括所有的名稱、最後一次提交的哈希值和註解,以及本地分支是否與遠端分支有追蹤關係。

git fetch remote 名稱 獲取 remote 最新的 commit 與 Branch 資訊
git remote show 名稱 提供關於特定 remote 的細節
git checkout - track 遠端分支名稱 新建一個追蹤遠端分支的 local branch

Ep. 12 Pull Requests

Pull Requests 是 GitHub 發明的,像是圍繞著 merge 的 review process,一堆東西捆綁在 merge 上面,同捆包(?)的概念。可以在 branch 之間 merge,也可以在 fork 之間 merge。如果想要提交自己的補丁到 GitHub,會發現流程中包含 fork repo,製造改變,commit 它們到自己的 fork,然後創造一個 pull request 從 fork 拉回 original repo。

這個 pull request 只是將 code 合併回 origin。我們也可以使用 pull request 在同個 repo 中從一個分支 merge 另一個分支。pull request 提供了討論改變、加上持續的整合、測試與 code review 的討論空間。

雖然 pull request 是 GitHub 的發明,但在 GitLab 與 Bitbucket 也可使用。

接著要創建一個新的 branch,push 到 remote 並創建一個 pull request 合併回 master。

git checkout master先確保自己在 master 裡。

使用 git checkout -b status_update 創造一個新的分支 status_update:

vim tutorials/ios_article_ideas.md 打開並編輯:

儲存後離開

git add tutorials/ios_article_ideas.mdgit commit -m “Completed the vision framework article” 將變更 commit:

接著 vim books/book_ideas.md 把 CVS by tutorials 的 x 刪掉:

:wq 儲存後離開

git add books/book_ideas.md 後再 git commit -m “Haven’t actrally written the CVS book” commit 這變化:

現在將這 branch push 到 origin,並在 origin 中新增一個名為 status_update 的分支:

git push --set-upstream origin status_update

查看包含 remote branch 的所有 branch,並顯示詳細 commit 資訊,-vv-v 更多的是,還會顯示與 remote branch 關聯的資訊:

git branch --all -vv

接著轉移到 GitHub 網站,選擇第二個 Pull requests 後,點擊右邊綠色按鈕“New pull request“:

出現 Comparing changes,顯示所有 commit 的更動:

選擇要 merge 進去的 Base Repo ,這邊選自己的 rwTODOs:

compare 選擇 status_update:

出現一頁總結 master 與 status_update 的差異,確認無誤點選綠色按鈕:

輸入標題:

輸入詳細資訊:

右側欄可選擇其他選項,Assignees 選擇自己,其他 configuration 之後也能選擇。確認無誤後按下方綠色按鈕:

出現這個 Pull request:

可以在 Add a comment 跟團隊成員討論:

提交後,還可以按 emoji:

看看有哪些 commits 會被 merge:

再次看看更動的概要:

如果有團隊,可以按綠色按鈕給回饋

如果都沒問題,回到 conversation,點擊 Merge pull request,

Confirm merge 確定合併:

Pull request 成功之後,提供刪除 branch 的選項。因為我們已經 merge 到 master,不再需要這個分支,因此可以刪除它:

想反悔可以 restore:

可以看到上面的 Pull requests 變成 0 了:

Commits 顯示剛剛的 Merge pull request:

回到 terminal:

git checkout master 切回 master。

git fetch 查看 remote 最新的 commit 與 branch 資訊,可看到已從 remote 得到最新的資訊:

git status 看到 master 比 origin/master 落後三個 commit,可以 fast toward

git log --oneline --decorate --graph --all 可看到 master 比 origin/master 些微落後:

git pull 下載 origin/master 的變更並 merge 到 master 中:

再次 git log --oneline --decorate --graph --all 可看到 master 跟 origin/master 同步了:

git branch -d status_update 刪除 local branch:

但在 git log --oneline --decorate --graph --all 裡看到 remote 的status_update 依然存在:

這是因為我們還沒跟 local repo 說,請它檢查有沒有任何分支被刪除。

使用git remote prune origin 清理 local repo 中已經不存在於 remote repo origin的 branch:

git remote prune origin

git log --oneline --decorate --graph --all 裡,status_update 消失的無影無蹤:

本章挑戰

為了能從同一個 repo 中的不同 branch 進行 pull request,我們也可以從 fork 進行一個 pull request 到 origin。

從自己的 fork 創造一個 pull request 回到原先的 Ray Wenderlich。

回到 Github,可以看到自己的 fork 目前已經超前 kodecocodes/rwTODOs:master 有 28 個 commits:

點選 Contribute,有 Open pull request 可以選擇:

點擊 Open pull request,跳出跟 pull request local branch 一樣的 Comparing changes。base repository 是 Kodecocodes/rwTODOs,head repository 是自己的 rwTODOs。按下綠色按鈕:

填寫標題與描述,但右側沒有可以添加 reviewer 的地方?沒辦法 cue 講者了…

看到自己也成為眾多 Pull requests 的一員:

Ep. 12 重點 git 指令

git branch --all -vv     查看包含 remote branch 的所有 branch,並顯示 remote branch 的關聯訊息
git pull 將 Github 的 repo 下載下來
git remote prune remote 名稱 清理 local repo 中已經不存在於 remote repo 的 branch

Ep. 13 Conclusion

講師 Sam 重述了所有課程中經歷過的痛苦(誤),其實是為介紹進階的 Git 課程: Mastering Git Course 鋪陳!先緩緩吧!先把這 12 章的東西好好消化,用出來試試看囉!

謝謝收看。

後話:Sam 的回信

因為 pull request 被 Sam 看到了,收到他誠摯的回信(並繼續推銷 Mastering Git Course XD)得到一張 Git Warrior 證書!

--

--