天天看點

代碼合并:Merge、Rebase 的選擇

圖解 Git 指令

基本用法

代碼合并:Merge、Rebase 的選擇

上面的四條指令在工作目錄、stage 緩存(也叫做索引)和 commit 曆史之間複制檔案。

  • git add files 把工作目錄中的檔案加入 stage 緩存
  • git commit 把 stage 緩存生成一次 commit,并加入 commit 曆史
  • git reset -- files 撤銷最後一次 git add files,你也可以用 git reset 撤銷所有 stage 緩存檔案
  • git checkout -- files 把檔案從 stage 緩存複制到工作目錄,用來丢棄本地修改
代碼合并:Merge、Rebase 的選擇
  • git commit -a 相當于運作 git add 把所有目前目錄下的檔案加入 stage 緩存再運作 git commit。
  • git commit files 進行一次包含最後一次送出加上工作目錄中檔案快照的送出,并且檔案被添加到 stage 緩存。
  • git checkout HEAD -- files 復原到複制最後一次送出

代碼合并:Merge、Rebase 的選擇

概述

git rebase

git merge

做的事其實是一樣的。它們都被設計來将一個分支的更改并入另一個分支,隻不過方式有些不同

Merge

#将 master 分支合并到 feature 分支最簡單的辦法就是用下面這些指令
git checkout feature
git merge master

#或者,你也可以把它們壓縮在一行裡。
git merge master feature
           
代碼合并:Merge、Rebase 的選擇

Rebase

#将 feature 分支并入 master 分支
git checkout feature
git rebase master
           

它會把整個 feature 分支移動到 master 分支的後面,有效地把所有 master 分支上新的送出并入過來。但是,rebase 為原分支上每一個送出建立一個新的送出,重寫了項目曆史,并且不會帶來合并送出。

代碼合并:Merge、Rebase 的選擇

rebase最大的好處是你的項目曆史會非常整潔。首先,它不像 git merge 那樣引入不必要的合并送出.

這種簡單的送出曆史會帶來兩個後果:安全性和可跟蹤性。如果你違反了 rebase 黃金法則,重寫項目曆史可能會給你的協作工作流帶來災難性的影響。此外,rebase 不會有合并送出中附帶的資訊——你看不到 feature 分支中并入了上遊的哪些更改.

互動式的 rebase

git checkout feature
git rebase -i master
#它會打開一個文本編輯器,顯示所有将被移動的送出:
pick 33d5b7a Message for commit #1
pick 9480b3d Message for commit #2
pick 5c67e61 Message for commit #3
#這個清單定義了 rebase 将被執行後分支會是什麼樣的。更改 pick 指令或者重新排序,這個分支的曆史就能如你所願了。比如說,如果第二個送出修複了第一個送出中的小問題,你可以用 fixup 指令把它們合到一個送出中:
pick 33d5b7a Message for commit #1
fixup 9480b3d Message for commit #2
pick 5c67e61 Message for commit #3
           

儲存後關閉檔案,Git 會根據你的指令來執行 rebase,項目曆史看上去會是這樣

代碼合并:Merge、Rebase 的選擇

忽略不重要的送出會讓你的 feature 分支的曆史更清晰易讀。這是 git merge 做不到的。

Rebase 的黃金法則

最重要的就是什麼時候 不能 用 rebase。git rebase 的黃金法則便是,絕不要在公共的分支上使用它。

比如說,如果你把 master 分支 rebase 到你的 feature 分支上會發生什麼:

代碼合并:Merge、Rebase 的選擇

這次 rebase 将 master 分支上的所有送出都移到了 feature 分支後面。問題是它隻發生在你的代碼倉庫中,其他所有的開發者還在原來的 master 上工作。因為 rebase 引起了新的送出,Git 會認為你的 master 分支和其他人的 master 已經分叉了

是以,在你運作 git rebase 之前,一定要問問你自己「有沒有别人正在這個分支上工作?」。如果答案是肯定的,那麼把你的爪子放回去,重新找到一個無害的方式(如git revert)來送出你的更改。不然的話,你可以随心所欲地重寫曆史。

#撤銷送出
git revert 送出id
           

将上遊分支上的更改并入feature分支

merge 是保留你完整曆史的安全選擇,

rebase 将你的 feature 分支移動到 master 分支後面,建立一個線性的曆史。

預設情況下,git pull 指令會執行一次merge,但你可以傳入--rebase 來強制它通過rebase來整合遠端分支。

用 Pull Request 進行審查

如果你将 Pull Request 作為你代碼審查過程中的一環,你需要避免在建立 Pull Request 之後使用 git rebase。隻要你發起了 Pull Request,其他開發者能看到你的代碼,也就是說這個分支變成了公共分支。重寫曆史會造成 Git 和你的同僚難以找到這個分支接下來的任何送出

來自其他開發者的任何更改都應該用 git merge 而不是 git rebase 來并入。

是以,在送出 Pull Request前用互動式的 rebase 進行代碼清理通常是一個好的做法。

可以在一個臨時分支中執行 rebase。這樣的話,如果你意外地弄亂了你 feature 分支的曆史,你還可以檢視原來的分支然後重試

git checkout feature
git checkout -b temporary-branch
git rebase -i master
# [清理目錄]
git checkout master
git merge temporary-branch
           

總結

如果你想要一個幹淨的、線性的送出曆史,沒有不必要的合并送出,你應該使用 git rebase 而不是 git merge 來并入其他分支上的更改。

另一方面,如果你想要儲存項目完整的曆史,并且避免重寫公共分支上的 commit, 你可以使用 git merge。兩種選項都很好用,但至少你現在多了 git rebase 這個選擇。

轉載于:https://www.cnblogs.com/zhangjianbin/p/7775022.html

git