git整理commit的基本方法

覺得整理commit還是非常重要的一種技能,看到有人已經(jīng)很好地整理過了,也搬運(yùn)到自己的博客中,以備不時(shí)之需。本文轉(zhuǎn)載自:Git整理Patch的一些經(jīng)驗(yàn)。

U-Boot升級到了最后,需要將之前比較雜亂的commit重新整理,有的需要整合,有的需要拆分。在這個(gè)過程中深刻的體會(huì)到了git的強(qiáng)大和靈活性。這里總結(jié)一下大的步驟和中間用到的各種小技巧。

步驟

commands usage
git checkout –b <new_branch> 新建一個(gè)branch來做整理的工作,保持原來的branch作為工作記錄
git rebase –i <working_base> 在新建的branch上,用rebase -i接squash的方法,將所有零碎的commit合成一個(gè)
git reset –soft HEAD~1 這一步只將object store還原到working_base上。所有需要整理的改動(dòng)都留在index上,以備下一步做stash
git stash save “stash message” 將所有的改動(dòng)放進(jìn)stash中

至此,我們有了一個(gè)工作的基礎(chǔ),所有雜亂的commit被合成一個(gè),并被放進(jìn)stash中,以備后面一點(diǎn)點(diǎn)的commit進(jìn)去。

接下來,最好過一遍所有的改動(dòng)。記錄下每個(gè)文件的改動(dòng)包含了那些內(nèi)容。以備后一步的按照不同的改動(dòng)內(nèi)容來合并commit。

git diff stash

舉個(gè)簡單的例子,假如總共有5個(gè)改動(dòng)的文件ae,分析它們的改動(dòng)內(nèi)容包含了四個(gè)不同的目的IIV,如下所示:

文件a --- 目的I
文件b --- 目的II
文件c --- 目的II, 目的III
文件d --- 目的II, 目的IV
文件e --- 目的III

現(xiàn)在考慮按照不同的目的來組織不同的commit:

commit 1 - 目的I   - 文件a
commit 2 - 目的II  - 文件b,文件c和文件d的一部分
commit 3 - 目的III - 文件c的一部分,文件e
commit 4 - 目的IV  - 文件d的一部分

commit 1

commands usage
git checkout stash <file_a> 將stash中的文件a checkout出來,此時(shí)改動(dòng)已放入index,我們可以直接commit
git commit –s 完成commit 1

commit 2

commands usage
git checkout stash . 將stash中的所有文件checkout出來。這里不能用git stash pop,因?yàn)橐坏﹑op了,stash也就消失了,也就無法進(jìn)行后續(xù)的工作。也不能用git stash apply,因?yàn)閍pply是嘗試merge,有時(shí)候反而會(huì)引起conflict,這不是我們想要的結(jié)果
git reset HEAD 將所有改動(dòng)移出index,但保留在working目錄中
git add b 將b的所有改動(dòng)放入index
git add -p c interactive的方式,將c的部分改動(dòng)放進(jìn)index
git add -p d 同前
git commit -s 完成commit 2
git clean -dfx 由于工作目錄是dirty的,所以這一步用以清空空座目錄,與object store保持嚴(yán)格一致,用來進(jìn)行測試。很容易想到git reset –hard HEAD,但是這個(gè)命令不會(huì)將add的文件清空,比如這個(gè)例子中的文件e,所以用clean -dfx是最徹底的,但運(yùn)行前請確保目錄中沒有需要保存而未保存的文件。

git add -p的用法

    * add -p 會(huì)逐個(gè)顯示文件中的每組改動(dòng),并詢問是否要加入index
        – y : 放入index
        – n : 不要放入index
        – e : 手動(dòng)編輯需要加入index的部分,常用來拆分一個(gè)改動(dòng)塊
            – “+”行,增加
            – “-”行,刪除
            – “ “行,保持原樣

第三個(gè)commit和第二個(gè)類似。不贅述。到第四個(gè)commit時(shí),只剩下文件d,并且雖說d只有一部分與commit 4的目的相關(guān),但由于d的其他部分在之前的commit已經(jīng)放入object store了,所以又退化成和第一個(gè)commit類似的情況。

錯(cuò)誤及補(bǔ)救措施

1. Commit到某個(gè)點(diǎn)以后,需要增減

  • git rebase -i <targetCommit>~1: 對出錯(cuò)的commit,用e來表示需要更改
  • 修改:
這里常用的git命令有
    git checkout stash <file> 增加一個(gè)文件
    git diff stash <file> 某個(gè)文件需要改動(dòng)
    git reset HEAD~1 <file> 將某個(gè)文件移出這次commit

無論如何,保證最后index中是修改過的正確改動(dòng)。

  • git rebase –continue: 結(jié)束修改。

2. Commit到某個(gè)點(diǎn)后,發(fā)現(xiàn)前面某個(gè)commit需要拆分

  • git rebase -i <targetCommit>~1: 回到拆分點(diǎn),用e來表示需要更改
  • git reset –mixed HEAD~1: 將這個(gè)targetCommit的改動(dòng)放回working directory,object store和index都還原成這個(gè)commit尚未放入的狀態(tài)。
  • 拆分進(jìn)行commit: 將這些改動(dòng)拆分的進(jìn)行commit。
  • git rebase –continue : 結(jié)束修改。

3. rebase -i遇到conflict

  • 手動(dòng)修改: 通常是先改成A,后改成B,此時(shí)改成B。也有先加上A,后加上B,這時(shí)需要取并集。有時(shí)A和B有相同的代碼段時(shí),這個(gè)代碼段會(huì)被吃掉,修改的時(shí)候需要重新加上。
  • git add <file>: 將修改完的文件放入index。
  • git rebase –continue : 繼續(xù)rebase。

4. <path>在git command中的運(yùn)用

  • git log <path>: 只顯示修改了某個(gè)文件commits。
  • git log -p <path> : 同上,并且顯示這個(gè)文件被修改的內(nèi)容。commit中其他文件的修改則不被顯示。
  • git diff … <path>: 只比較某個(gè)文件的改動(dòng)。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容