參考:Fix conflicts only once with git rerere
下載初始化倉庫-百度云耸别,直接開始操作幔摸,不寫太多理論啦拒迅,沒毛用件舵。
打開rerere
功能
$ git config --global rerere.enabled true
- 也可以在自己的倉庫的創(chuàng)建
.git/rr-cache
文件夾來開啟該功能卸察,但是用命令開啟的話,全局都開啟铅祸。創(chuàng)建文件夾只對當(dāng)前git repository有效坑质。
初始化倉庫(下載倉庫默認(rèn)的樣子就是這樣)
倉庫的三個文件
master的hello.txt
test的hello.txt
$ git log --oneline --all --graph --decorate
此時倉庫中兩個分支
merge合并hello.txt并記錄沖突解決方式
$ git merge master
沖突,第三行表示 rerere記錄一個preimage
上面輸出顯示記錄到preimage临梗,就是指在.gti/rr-cache下生成啦一個preimage
preimage的內(nèi)容涡扼,跟下面的沖突hello.txt差不多
hello.txt沖突
解決hello.txt沖突
git add hello.txt
git commit --no-edit
解決沖突后,添加到index并commit盟庞,第一行顯示 記錄(resolution)吃沪,就是記錄啦本次解決沖突的方式,提交后什猖,merge操作完成
上面輸出顯示票彪,記錄解決辦法,在.git/rr-cache下生成啦postimage
postimage就是我們修改沖突后hello.txt的內(nèi)容不狮,一樣的
$ git log --oneline --all --graph --decorate
查看log,合并后的倉庫分支結(jié)構(gòu)
$ git reset --hard HEAD^
重置掉這次merge操作,HEAD^代表當(dāng)前commit的parent
$ git log --oneline --all --graph --decorate
分支結(jié)構(gòu)又變回來啦
修改morning.txt
修改第一行為((modified test))
將修改的morning提交
$ git add morning.txt
$ git commit -am '修改morning 第一行為(modified test)'
切換回master
$ git checkout master
image.png
將修改的morning提交
$ git add morning.txt
$ git commit -am '修改morning 第一行為(modified master)'
$ git log --oneline --all --graph --decorate
分支結(jié)構(gòu)
繼續(xù)將master合并到test
$ git checkout test
$ git merge master
輸出第5行降铸,表示生成‘morning.txt’的preimage,輸出第6行表示用已經(jīng)記錄的解決方式自動解決啦hello.txt的沖突
$ git rerere remaining
輸出顯示摇零,moring.txt還有沖突沒解決
hello.txt的沖突是自動解決的推掸,之前已經(jīng)存儲啦解決方式
hello.txt文件已經(jīng)自動解決啦,把hello.txt添加到index
$ git add hello.txt
如果已經(jīng)在merge之前開啟啦下面的選項,那么自動解決沖突的hello.txt會被自動添加到index,這樣就不用上面的add啦终佛,推薦開啟俊嗽。
$ git config --global rerere.autoupdate true
morning.txt仍然有沖突未解決
沖突的morning.txt文件改成這樣子
提交修改完成merge操作,
-a
就是自動添加修改過的文件铃彰,--no-edit
就是使用默認(rèn)commit message绍豁,不修改
$ git commit -a --no-edit
重點仍然在第一行,記錄用于‘morning .txt’的沖突解決方式
然后牙捉,.git/rr-cache文件夾下就有啦用于解決morning.txt中這個沖突的兩個文件
preimage是沖突之前的樣子
postimage是沖突解決之后的樣子
$ git reset --hard HEAD^
像之前一樣竹揍,重置掉這次merge
$ git log --oneline --all --graph --decorate
分支結(jié)構(gòu)又變回來啦
最后一次在test分支上工作并提交,將test合并到master
修改hello.txt最后一行
$ git commit -am '修改hello.txt第10行為(test10)'
$ git log --oneline --all --graph --decorate
分支結(jié)構(gòu)圖
$ git checkout master
$ git merge test
第5邪铲、6行顯示芬位,兩個文件的沖突都通過之前存儲的方式自動解決啦,而最新修改的第10行是沒有沖突的带到,直接合并昧碉。合并后,直接自動staged啦兩個文件揽惹,因為我們之前開啟啦rerere.autoupdate
下面命令執(zhí)行后被饿,也沒有顯示有剩余的沖突文件,證明merge干凈利落搪搏,雖然輸出結(jié)果最后還是有一句自動合并失敗狭握,直接無視。
git rerere remaining
$ git diff --staged
三個地方的修改都正確合并啦疯溺,一切正常论颅。
$ git commit --no-edit
$ git log --oneline --all --graph --decorate
最終的結(jié)果就是這樣的,歷史記錄非常干凈
rerere的作用就是防止歷史記錄被圖中的control merges給污染掉囱嫩,只有最后一個merge操作
注意事項:
如果最后一次hello.txt修改第2行恃疯,而不是第10行,那么git rerere的自動解決沖突不會生效墨闲,修改的行離第一行太近啦今妄。仍然需要手動解決沖突的
并且,如果morning里面也分別是(test)和(master)
rerere會自動用解決hello.txt中兩個
(test)
(master)
沖突的方法來解決morning文件中的沖突损俭,所以rerere存儲的解決方式是基于沖突的內(nèi)容的,而不是基于沖突文件名中的某個區(qū)域潘酗。