①②③Git 版本控制入門(5)
Beginning Git: Ep. 11 ~ 13 — Syncing with a Remote,Pull Requests,Conclusion
接續上一篇:
線上課程資源:
以下跟著課程實做用 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 有多遠:
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.md
與 git commit -m “Completed the vision framework article”
將變更 commit:
接著 vim books/book_ideas.md
把 CVS by tutorials 的 x 刪掉:
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 證書!