What have you found for these years?

2009-11-02

git merge partial

git merge 其實同時做了兩件事,一個是記錄 branch 與
branch 之間的 merge 資訊,另一個才是真正地執行 "merge"

前者不在乎程式碼之間的差異,只有 true or false.
後者才真正使用 three-way merge 進行程式碼改寫。

然而這兩件事是可以分開的:

1. fast-forward 的情況下,不記錄 merge commit

2. cherry-pick 不記錄 merge commit, 比較像是:
git show COMMIT | git apply; git commit -a
因此 SHA1 會不同,而且沒有 merge commit.

3. rebase 同上,不過可以看成大量的 cherry-pick

以上三者都沒有 merge commit (rebase 不是非常確定),
因此在重跑 merge 時,很可能會再檢查一次 merge 狀況。
有時候也會希望在 merge 時,排除某些 commit,
直接把那些 commit 視為已經 merge 過了,
例如是某個 branch 特定的 config. 如 OS path 設定?

這種時候可以這樣做:

> git merge COMMIT-before-skip
> git merge COMMIT-skip -s ours
> git merge COMMIT-after-skip

中間要 skip 掉的 commit, merge strategy 用 ours,
表示合併時,我們只考慮 HEAD 上的程式,直接捨棄 remote.

這也就是只做一開始提到的前者,和 cherry-pick 正好相反。
以後再 merge 時也不用擔心不小心把那段程式混進去。

這也是為什麼:

> git checkout A; git merge B
Already up-to-date.

> git checkout B; git merge A
Already up-to-date.

> git diff A..B
還是可以生出一堆 diff 出來的緣故..
這種時候如果需要裡面已經被 merge 過的,重新 merge 呢?
cherry-pick 或 rebase 試試....

所以 git 亂玩確實是會玩壞的,要小心啊。
看起來是一樣的東西並不見得會一樣。

0 retries:

Post a Comment

All texts are licensed under CC Attribution 3.0