git作為時下最流行的代碼管理工具,Git權(quán)威指南總結(jié)了十條喜歡Git的理由:
- 異地協(xié)同工作;
- 現(xiàn)場版本控制;
- 重寫提交說明;
- 無盡的后悔藥;
- 更好用的提交列表;
- 更好的差異比較;
- 工作進(jìn)度保存;
- 作為SVN前端實(shí)現(xiàn)移動辦公;
- 無處不在的分頁器;
- 快。
其中:
git作為分布式代碼管理工具,每個運(yùn)行節(jié)點(diǎn)都保存有代碼倉庫的所有內(nèi)容,都可以用來恢復(fù)服務(wù)器上的代碼倉庫;
git保存了所有代碼倉庫的操作記錄,因此對本地代碼倉庫的操作都不需要進(jìn)行任何備份,都可以無限回退。
1. 概述
1.1 git客戶端安裝
- 官方Windows客戶端:主要使用Git Bash以命令行模式操作,但也支持GUI(gitk/git GUI),使用方法參見官方使用說明;
- 官方Linux客戶端:服務(wù)器已默認(rèn)安裝;
- 更多圖形工具,建議使用Source Tree。
1.2 git客戶端配置
遠(yuǎn)程倉庫可以通過網(wǎng)頁方式訪問,但通常情況下仍然需要創(chuàng)建本地倉庫:
-
創(chuàng)建本地 SSH key:
- Windows下打開Git Bash,Linux下打開終端;
- 執(zhí)行
ssh-keygen,所有提示均回車確認(rèn),生成私鑰和公鑰:<當(dāng)前用戶根目錄>/.ssh/id_rsa
<當(dāng)前用戶根目錄>/.ssh/id_rsa.pub - 查看公鑰文件內(nèi)容并復(fù)制,注意不要復(fù)制命令本身
cat <當(dāng)前用戶根目錄>/.ssh/id_rsa.pub
-
添加遠(yuǎn)程倉庫訪問權(quán)限,不同的服務(wù)器會有不同的配置方法:
- GitHub需要從右上角頭像右側(cè)的向下箭頭進(jìn)入settings->SSH and GPG keys來添加或者直接通過GitHub客戶端自動添加;
- gitolite需要將SSH公鑰拷貝到gitolite-admin目錄下的keydir目錄中,并需要gitolite.conf已配置合適的訪問權(quán)限。
注意:
- 本機(jī)SSH 私鑰id_rsa不能刪除。
- 本機(jī)SSH key只需要創(chuàng)建一對,不需要為每個服務(wù)器都創(chuàng)建一對。
-
創(chuàng)建本地倉庫并配置
- 回到Git Bash/終端;
- 執(zhí)行
git clone ssh://xxx.git
- 執(zhí)行本地配置(更多配置參見自定義-Git-配置-Git)
git config --global core.filemode falsegit config --global user.name “姓名”
git config --global user.email “郵箱”
git config --global color.ui auto
git config --global core.ignorecase false
git config --global core.autocrlf input
git config --global core.safecrlf true
git config --global push.default simple
git config --global rerere.enabled true - 配置完成后可顯示本地配置信息
git config -l --global
注意:
- 自動補(bǔ)齊: Windows客戶端默認(rèn)支持命令補(bǔ)齊,服務(wù)器上Linux已經(jīng)配置自動補(bǔ)齊,自行安裝的Linux需要參考Git基礎(chǔ)-技巧和竅門進(jìn)行配置;
- 命令別名:git允許為常用操作設(shè)置別名,以簡化操作(參見Git-基礎(chǔ)-Git-別名):
git config --global alias.ci commit
git config --global alias.unstage 'reset HEAD --'
2. git基礎(chǔ)
2.1 基本工作流程
2.2 獲取幫助信息
-
聯(lián)機(jī)幫助
git help
git help <命令名稱>
2.3 合并比較結(jié)果閱讀
git支持外部比較/合并工具(參見外部的合并與比較工具配置說明),但通常使用更為直接的命令行方式:
- diff結(jié)果閱讀
--- a/src/test.txt :原始文件(以---開頭)
+++ b/src/test.txt :目標(biāo)文件(以+++開頭)
@@ -1,3 +1,3 @@ :當(dāng)前差異塊的比較對象為原始文件的第1行開始的3行與目標(biāo)文件的地1行開始的3行
-orign :只存在于原始文件(以-開頭)
+modified :只存在于目標(biāo)文件(以+開頭)
以空格開頭 : 同時存在于原始文件和目標(biāo)文件
- merge結(jié)果閱讀
<<<<<<<
當(dāng)前分支代碼
=======_
其他分支合并進(jìn)來的代碼
>>>>>>>
2.4 提交(commit)消息格式
git提交消息是日志回溯/代碼審查/二分法問題查找的基礎(chǔ),建議參考thoughtbot規(guī)范:
50-character subject line
1. Why was this change necessary?
2. How does it address the problem?
3. Are there any side effects?
建議將模板保存在根目錄下,使用如下命令配置為模板,這樣在提交時就會自動顯示:
git config --global commit.template <模板文件>
3. git倉庫構(gòu)成及訪問路徑

3.1 遠(yuǎn)程倉庫
遠(yuǎn)程倉庫是服務(wù)器上的git倉庫,支持如下常用操作(更多操作參見Git-基礎(chǔ)-遠(yuǎn)程倉庫的使用):
3.1.1 基本操作
-
查看本地倉庫遠(yuǎn)程倉庫列表
git remote -v
如下所示:
$ git remote -v origin ssh://xxx.git (fetch) origin ssh://xxx.git (push)注意:每個本地倉庫可以從多個遠(yuǎn)程倉庫獲取代碼,當(dāng)前僅包含一個遠(yuǎn)程倉庫origin。
-
查看遠(yuǎn)程倉庫概況
git remote show <遠(yuǎn)程倉庫名稱>
如下所示:

該操作可用于查看遠(yuǎn)程倉庫的地址,分支情況,與本地分支的差別等等。
3.1.2 從遠(yuǎn)程倉庫到本地倉庫
-
創(chuàng)建新的本地倉庫
git clone <遠(yuǎn)程倉庫路徑> <可選的本地倉庫目錄名稱>
-
從遠(yuǎn)程倉庫獲取最新內(nèi)容,包括新的分支以及原有分支上的改動
git fetch
-
從遠(yuǎn)程倉庫獲取最新內(nèi)容,并合并到當(dāng)前分支
git pull
注意:
- 該操作相當(dāng)于
git fetch+git merge origin/<當(dāng)前分支名稱>,因此出現(xiàn)沖突時可以使用git merge --abort來終止; - 如果發(fā)生沖突,應(yīng)當(dāng)順序執(zhí)行如下操作:
- 使用
git merge --abort終止本次操作; - 使用
git checkout -b temp創(chuàng)建并切換到1個臨時分支; - 使用
git branch -D <當(dāng)前分支名稱>刪除當(dāng)前分支; - 使用
git checkout <當(dāng)前分支名稱>重新從遠(yuǎn)程分支創(chuàng)建本地分支; - 使用
git branch -D temp刪除臨時分支。
- 使用
- ?。?!請勿使用--rebase選項(xiàng),除非你知道你在干什么?。?!。
- 該操作相當(dāng)于
3.1.3 從本地倉庫到遠(yuǎn)程倉庫
-
本地倉庫更新到遠(yuǎn)程倉庫
git push
注意:
- 若本地分支在遠(yuǎn)程倉庫中沒有對應(yīng)的分支,則本操作會在遠(yuǎn)程倉庫中創(chuàng)建同名分支并自動關(guān)聯(lián);
-
若與遠(yuǎn)程倉庫代碼沖突且確認(rèn)本地倉庫沒有問題,例如使用
git rebase與master分支同步后,則可以使用git push --force來強(qiáng)制推送到服務(wù)器,從而使用本地倉庫覆蓋遠(yuǎn)程倉庫;此時,遠(yuǎn)程倉庫中的修改日志將會丟失。
3.2 本地倉庫
本地倉庫是當(dāng)前工作機(jī)器上的git倉庫,支持如下常用操作:
3.2.1 查看本地倉庫狀態(tài)
- 查看總體狀態(tài)
git status

命令結(jié)果中注釋如下:
- 注1: 本地倉庫當(dāng)前分支名稱;
- 注2: 本地倉庫當(dāng)前分支與遠(yuǎn)程倉庫同名分支之間的差異;
- 注3: 推薦執(zhí)行的操作;
- 注4: 暫存區(qū)(stage)內(nèi)容;
- 注5: 工作區(qū)內(nèi)容,對倉庫中文件的修改;
- 注6: 工作區(qū)內(nèi)容,未加入到倉庫中的文件。
3.2.2 查看本地倉庫日志(參見Git-工具-選擇修訂版本)
-
查看所有或某個文件的修改記錄
git log <可選文件路徑>
-
查看所有或某個文件的修改記錄的概要(修改文件列別行數(shù)等)
git log --stat <可選文件路徑>
-
圖形化簡略模式查看倉庫日志
git log --oneline --graph
注意:在提交pull request之前,建議使用該命令確認(rèn)需要合入主線的分支上沒有重疊區(qū)域,例如下圖中紅圈所示的重疊線條,否則出現(xiàn)問題時難以定位錯誤提交:

-
查看本地分支與遠(yuǎn)程倉庫master分支的差別,即本地分支對應(yīng)的pull request包含的內(nèi)容
git log --oneline --left-right origin/master...<本地分支名稱>
對于未與遠(yuǎn)程倉庫master分支同步即rebase的分支:
$ git log --oneline --left-right origin/master...feature/KTOS-573-add-i2c-subsystem-2 < deb713e Merge pull request #568 to master > be27660 XXXX ... < a674652 XXXX ... > c1a52d3 XXXX ...其中,
<代表僅存在于遠(yuǎn)程分支上的提交,>代表僅存在于本地分支上的提交。而已經(jīng)與遠(yuǎn)程倉庫master分支同步即rebase的分支,則只包含>,即即僅存在于本地分支上的提交。 -
查看某次提交中所有或某個文件的具體修改內(nèi)容
git show <提交ID> <可選文件路徑>
-
查看文件的歷史版本
git show <提交ID>:<文件路徑>
-
查看某個文件中所有或指定行的修改記錄
git blame <文件路徑>
git blame -L <起始行>,<結(jié)束行> <文件路徑>
git blame -L <起始行>,<+行數(shù)> <文件路徑>
3.2.3 查看本地倉庫的git操作記錄并無限回退
- 查看操作記錄
git reflog

-
回退到某次操作后的狀態(tài)
git reset HEAD@{序號}
注意:
- 沒有提到到倉庫中的代碼無法恢復(fù);
- 暫存區(qū)的代碼會受影響,如需要保留可先提交到本地倉庫進(jìn)行備份。
3.3 分支
分支是指向提交的的可變指針(參見Git-分支-分支簡介),每個git倉庫都有一個默認(rèn)創(chuàng)建的master分支和若干其他分支,支持如下常用操作:
3.3.1 查看分支信息
-
查看本地分支信息
git branch
注意:當(dāng)前分支名稱之前會有
*標(biāo)志。 -
查看本地分支詳細(xì)信息
git branch -v

- 查看包含分支標(biāo)簽的本地倉庫日志
git log --oneline --decorate

- 查看遠(yuǎn)程倉庫分支信息
git branch -r

- 查看所有分支(包含本地和遠(yuǎn)程倉庫)信息
git branch -a

3.3.2 從當(dāng)前分支到其他分支
-
切換到本地倉庫或遠(yuǎn)程倉庫已有分支
git checkout <分支名稱>
-
從當(dāng)前分支創(chuàng)建一個新分支并切換到新分支
git checkout -b <新分支名稱>
-
從某個提交創(chuàng)建一個新分支并切換到新分支(用于查看內(nèi)容或者查找問題)
git checkout <提交ID> -b <新分支名稱>
-
刪除某個分支
git branch -D <分支名稱>
3.3.3 從其他分支到當(dāng)前分支
-
合并其他分支到當(dāng)前分支,
git merge <其他分支名稱>
注意:
- 該操作有可能造成提交交錯,影響問題定位,因此不建議使用,除非你知道自己在干什么!?。?/strong>;
- 如果合并過程中有沖突,需要順序執(zhí)行如下操作:
- 編輯沖突文件,或刪除不需要的文件;
- 使用
git add -u將修改添加到暫存區(qū); - 使用
git commit提交修改。
-
終止當(dāng)前合并操作
git merge --abort
-
將其他分支的某個提交合并到當(dāng)前分支
git cherry-pick <提交ID>
3.4 工作區(qū)和暫存區(qū)
工作區(qū)是工作目錄的形象化稱呼,實(shí)際上就是當(dāng)前分支最新版本的本地副本;暫存區(qū)(stage)則是包含將要提交到本地倉庫中的文件的索引列表(參見Git權(quán)威指南-git暫存區(qū))。
3.4.1 查看工作區(qū)和暫存區(qū)內(nèi)容
-
查看工作區(qū)中文件的修改內(nèi)容,即比較工作區(qū)與暫存區(qū)中的文件
git diff <可選路徑或文件名>
-
查看暫存區(qū)中文件的修改內(nèi)容,即比較暫存區(qū)與HEAD的文件
git diff --cached <文件名>
-
比較工作區(qū)與某個提交中的文件
git diff <提交ID> <可選路徑或文件名>
-
比較暫存區(qū)與某個提交中的文件
git diff --cached <提交ID> <可選路徑或文件名>
-
比較2個提交中的文件
git diff <提交ID1> <提交ID2> <可選路徑或文件名>
git diff --name-only <提交ID1> <提交ID2> <可選路徑或文件名>注意:
- 2個提交中必須包含對要比較的文件的修改,且
提交ID1更舊; -
--name-only用于只顯示文件名。
- 2個提交中必須包含對要比較的文件的修改,且
3.4.2 從工作區(qū)到暫存區(qū)
-
將工作區(qū)中的所有或某個文件放到暫存區(qū)
git add <文件或目錄路徑>
-
將工作區(qū)中所有對倉庫中已有代碼的修改放到暫存區(qū)
git add -u
-
以交互方式暫存文件
git add -i
注意:
- 該操作可以每一個被修改的文件和被修改的文件中的每一處修改都作出是否提交到暫存區(qū)的選擇;
- 詳細(xì)操作參見Git-工具-交互式暫存。
-
刪除文件和目錄
git rm
git rm -r -
移動文件和目錄
git mv
3.4.3 從暫存區(qū)到工作區(qū)
- 將暫存區(qū)中對倉庫中所有或某個文件的修改恢復(fù)到工作區(qū)
git reset HEAD <可選的文件或目錄路徑>
3.4.4 從暫存區(qū)到本地倉庫
-
將暫存區(qū)中的內(nèi)容提交到本地倉庫(簡單注釋)
git commit -m "注釋信息"
-
將暫存區(qū)中的內(nèi)容提交到本地倉庫(復(fù)雜注釋,將會進(jìn)入文本編輯界面,默認(rèn)使用vi)
git commit
-
修改上次提交的注釋信息
git commit --amend -m "注釋信息"
3.4.5 從本地倉庫到暫存區(qū)即清除暫存區(qū)
-
使用本地倉庫中某個提交的代碼覆蓋暫存區(qū)并更新HEAD指針
git reset <提交ID>
注意,工作區(qū)的內(nèi)容不受影響,但是暫存區(qū)中未提交到本地倉庫中的修改會被覆蓋。
3.4.6 從本地倉庫到工作區(qū)
-
使用本地倉庫中的最新代碼覆蓋工作區(qū)中的內(nèi)容,即撤銷工作區(qū)內(nèi)的所有或某個文件的修改
git checkout .
git checkout -- <文件或者目錄名>注意:本操作實(shí)質(zhì)上是用本地倉庫中的數(shù)據(jù)覆蓋工作區(qū)中的內(nèi)容。
-
使用本地倉庫中某個提交的內(nèi)容覆蓋工作區(qū)中的某個文件或所有內(nèi)容
git checkout <提交ID> <可選的文件或者目錄名>
-
使用本地倉庫中某個提交的內(nèi)容覆蓋工作區(qū)和暫存區(qū)并更新HEAD指針
git reset --hard <提交ID>
3.4.7 從工作區(qū)到本地倉庫
-
直接將文件提交到本地倉庫
git commit -a -m "注釋信息"
注意,該操作不經(jīng)過暫存區(qū),務(wù)必慎用!!!
3.4.8 清除工作區(qū)
- 清除工作區(qū)
git clean -fd
3.5 臨時緩沖區(qū)
臨時緩沖區(qū)(stash)是保存臨時修改內(nèi)容的各個分支共享的全局緩沖區(qū),支持如下常用操作(參見Git-工具-儲藏與清理):
3.5.1 查看臨時緩沖區(qū)
-
顯示臨時緩沖區(qū)內(nèi)保存的工作進(jìn)度
git stash list
如下所示:
$ git stash list stash@{0}: On bugfix/KTOS-499-pci-decouple: pci review其中,第1個
:之前的部分是每個工作進(jìn)度的標(biāo)簽,2個:之間的部分是保存該工作進(jìn)度時所在的分支,第2個:之后的部分是該工作進(jìn)度的描述信息。 -
顯示臨時緩沖區(qū)某個工作進(jìn)度的內(nèi)容
git stash show stash@{序號}
3.5.2 從工作區(qū)和暫存區(qū)到臨時緩沖區(qū)
-
將工作區(qū)和暫存區(qū)中對本地倉庫中已有代碼的修改備份到臨時緩沖區(qū)
git stash save "緩沖區(qū)描述"
-
將工作區(qū)和暫存區(qū)中的所有修改(包括不在本地倉庫中的文件)備份到臨時緩沖區(qū)
git stash save -u "緩沖區(qū)描述"
3.5.3 從臨時緩沖區(qū)到工作區(qū)
-
將臨時緩沖區(qū)中對倉庫中代碼的修改彈出到工作區(qū)
git stash pop stash@{序號}
-
將臨時緩沖區(qū)中對倉庫中代碼的修改應(yīng)用到工作區(qū)(保留緩存區(qū)中的工作進(jìn)度)
git stash apply stash@{序號}
4. git進(jìn)階
4.1 變基(參見Git權(quán)威指南-改變歷史)
-
該操作的基本語法為:
git rebase --onto <目的提交> <起始提交> <結(jié)束提交>
變基操作會為切換到 <目的提交>,然后把<起始提交>和<結(jié)束提交>之間的提交逐條疊加到<目的提交>之后;如果
--onto <目的提交>未指定,則使用<起始提交>;如果<結(jié)束提交>未指定,則使用當(dāng)前分支;變基操作通常用于當(dāng)前任務(wù)分支跟主線同步,例如
git rebase master;變基操作中出現(xiàn)問題時,需要根據(jù)對沖突的文件提示進(jìn)行修改,完成后使用
git add -u提交到暫存區(qū),并使用git rebase --continue繼續(xù)或git rebase --skip跳過當(dāng)前提交繼續(xù)同步;變基操作可以被
git rebase --abort終止以恢復(fù)到操作前狀態(tài);變基操作結(jié)束以后,推送到服務(wù)器時,如果報(bào)錯,需要使用
git push --force強(qiáng)制推送。-
如果修改內(nèi)容較多,且長時間未同步,可能會出現(xiàn)同一文件多次沖突,因此強(qiáng)烈建議打開Rerere功能:
git config --global rerere.enabled true
使能后,沖突解決方案會被記錄,并在再次遇到時自動應(yīng)用,不需要再吃手工編輯文件解決,只需要
git add -u即可。
4.2 二分法查找錯誤版本(參考Git權(quán)威指南-二分查找)
該方法用于快速定位問題,但是需要如下條件作為前提才能高效工作:
- 提交線性排序,不存在下圖所示的重疊部分:

- 每個關(guān)鍵提交最好都能編譯通過或運(yùn)行。
該操作具體步驟如下(使用簡單實(shí)例,具體使用時根據(jù)需要調(diào)整):
-
查看當(dāng)前日志
$ git log --oneline** ebc659b second bad 2fe7f29 first bad abfcfbc second good 84ec8c3 first good -
啟動查找
$ git bisect start -
標(biāo)志當(dāng)前版本為壞版本
$ git bisect bad -
標(biāo)志某個好版本作為起點(diǎn)
$ git bisect good 84ec8c3 Bisecting: 0 revisions left to test after this (roughly 1 step) [2fe7f29987123abe3fa0cb3429c07b597f86594c] first bad此時會自動跳轉(zhuǎn)到中間版本:
$ git log --oneline 2fe7f29 first bad abfcfbc second good 84ec8c3 first good -
如果當(dāng)前版本為壞版本,標(biāo)志他
$ git bisect bad Bisecting: 0 revisions left to test after this (roughly 0 steps) [abfcfbc361beb42551b4219d6d70ccb1fe3ac103] second good此時會自動跳轉(zhuǎn)到中間版本:
$ git log --oneline abfcfbc second good 84ec8c3 first good -
如果當(dāng)前版本為好版本,標(biāo)志他
$ git bisect good 2fe7f29987123abe3fa0cb3429c07b597f86594c is the first bad commit commit 2fe7f29987123abe3fa0cb3429c07b597f86594c Author: Matt Zu<matt.zu@pc.com> Date: Tue Dec 20 20:36:56 2016 +0800 first bad :100644 100644 0cfbf08886fca9a91cb753ec8734c84fcbe52c9f c9c6af7f78bc47490dbf3e822cf2f3c24d4b9061 M test.c找到第一個壞版本時,自動結(jié)束,不再跳轉(zhuǎn)到中間版本:
$ git log --oneline abfcfbc second good 84ec8c3 first good -
切換到第一個壞版本
$ git checkout bisect/bad Previous HEAD position was abfcfbc... second good HEAD is now at 2fe7f29... first bad日志如下:
$ git log --oneline 2fe7f29 first bad abfcfbc second good 84ec8c3 first good
4.3 壓縮提交(參見Git-工具-重置揭密#壓縮)
每個pull request中應(yīng)當(dāng)包含盡可能少的提交,因此在推送到服務(wù)器之前,每個功能點(diǎn)或者修改點(diǎn)包含的所有提交都應(yīng)當(dāng)壓縮成一個提交,并編譯通過,最好能夠通過基本測試。
該操作具體步驟如下(使用簡單實(shí)例,具體使用時根據(jù)需要調(diào)整):
-
查看當(dāng)前日志
$ git log --oneline f0fd7c9 commit msg 2 335067c commit msg 1 abfcfbc second good 84ec8c3 first good -
查看文件修改記錄
$ git blame test.c abfcfbc3 (Matt Zu 2016-12-20 20:36:35 +0800 1) 2 335067c5 (Matt Zu 2016-12-27 14:28:33 +0800 2) 3 f0fd7c9b (Matt Zu 2016-12-27 14:28:48 +0800 3) 4 -
將HEAD指針回退到需要合并的提交之前
$ git reset --soft 335067c^
注意:^用于回退到上一次提交,等價于~1;也可以疊加使用以回退到N次提交之前,等價于~N。
-
查看日志
$ git log --oneline abfcfbc second good 84ec8c3 first good -
查看修改內(nèi)容
$ git status On branch msg Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: test.c $ git diff --cached diff --git a/test.c b/test.c index 0cfbf08..dcf37cd 100644 --- a/test.c +++ b/test.c @@ -1 +1,3 @@ 2 +3 +4 -
再次提交代碼以合并提交
git commit -m "combine commit msg" -
查看日志
$ git log --oneline a1fadaf combine commit msg abfcfbc second good 84ec8c3 first good -
查看修改內(nèi)容
$ git log --oneline -p -1 a1fadaf combine commit msg diff --git a/test.c b/test.c index 0cfbf08..dcf37cd 100644 --- a/test.c +++ b/test.c @@ -1 +1,3 @@ 2 +3 +4
4.4 拆分提交(參見Git-工具-重寫歷史#拆分提交)
該操作用于對不合理的提交壓縮進(jìn)行拆分,以方便cherry-pick和二分法查找等后續(xù)操作。
注意:該操作也可以用于調(diào)整提交的順序,參見Git-工具-重寫歷史#重新排序提交。
該操作具體步驟如下(使用簡單實(shí)例,具體使用時根據(jù)需要調(diào)整):
-
查看日志
$ git log --oneline 0b22507 add aditional number abc373f update number and insert lines abfcfbc second good 84ec8c3 first good假定
abc373f為需要拆分的提交。 -
查看修改內(nèi)容
$ git log --oneline -p -2 0b22507 add aditional number diff --git a/test.c b/test.c index 2ff46c8..ab7998f 100644 --- a/test.c +++ b/test.c @@ -1,3 +1,3 @@ -3 +3 4 5 abc373f update number and insert lines diff --git a/test.c b/test.c index 0cfbf08..2ff46c8 100644 --- a/test.c +++ b/test.c @@ -1 +1,3 @@ -2 + +3 + -
變基到需要拆分的提交(
abc373f)之前$ git rebase -i abc373f^此時會進(jìn)入vim界面,顯示如下內(nèi)容:
pick abc373f update number and insert lines pick 0b22507 add aditional number # Rebase abfcfbc..0b22507 onto abfcfbc (2 commands) # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # d, drop = remove commit # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out ~根據(jù)提示,將需要拆分的提交前面的
pick修改為edit(此處可以調(diào)整提交順序):edit abc373f update number and insert lines pick 0b22507 add aditional number然后保存并退出,顯示如下提示:
$ git rebase -i abc373f^ warning: Stopped at abc373f... update number and insert lines You can amend the commit now, with git commit --amend Once you are satisfied with your changes, run git rebase --continue -
查看日志
$ git log --oneline abc373f update number and insert lines abfcfbc second good 84ec8c3 first good -
回退HEAD指針到上一次提交
$ git reset HEAD^ Unstaged changes after reset: M test.c -
查看修改內(nèi)容
$ git diff diff --git a/test.c b/test.c index 0cfbf08..2ff46c8 100644 --- a/test.c +++ b/test.c @@ -1 +1,3 @@ -2 + +3 + -
將修改內(nèi)容保存到臨時緩沖區(qū)
$ git stash save "msg split" Saved working directory and index state On (no branch): msg split HEAD is now at abfcfbc second good -
將修改內(nèi)容應(yīng)用到工作區(qū)并保留緩沖區(qū)中的進(jìn)度
$ git stash apply stash@{0} -
移除不需要的修改并提交(此處僅保留數(shù)字更新)
$ git diff diff --git a/test.c b/test.c index 0cfbf08..00750ed 100644 --- a/test.c +++ b/test.c @@ -1 +1 @@ -2 +3 $ git add -u $ git commit -m "update number" [detached HEAD c2b7f71] update number 1 file changed, 1 insertion(+), 1 deletion(-) -
查看日志
$ git log --oneline c2b7f71 update number abfcfbc second good 84ec8c3 first good -
查看修改內(nèi)容
$ git log --oneline -p -1 c2b7f71 update number diff --git a/test.c b/test.c index 0cfbf08..00750ed 100644 --- a/test.c +++ b/test.c @@ -1 +1 @@ -2 +3 -
將修改內(nèi)容彈出到工作區(qū),修改沖突后再次提交
$ git stash pop stash@{0} Auto-merging test.c CONFLICT (content): Merge conflict in test.c Recorded preimage for 'test.c' $ vim test.c $ git commit -m "insert lines" Recorded resolution for 'test.c'. [detached HEAD 13a6963] insert lines 1 file changed, 2 insertions(+) -
查看日志
$ git log --oneline 13a6963 insert lines c2b7f71 update number abfcfbc second good 84ec8c3 first good -
查看修改內(nèi)容
$ git log --oneline -p -2 13a6963 insert lines diff --git a/test.c b/test.c index 00750ed..2ff46c8 100644 --- a/test.c +++ b/test.c @@ -1 +1,3 @@ + 3 + c2b7f71 update number diff --git a/test.c b/test.c index 0cfbf08..00750ed 100644 --- a/test.c +++ b/test.c @@ -1 +1 @@ -2 +3 -
繼續(xù)變基
$ git rebase --continue Successfully rebased and updated refs/heads/msg_split. -
查看日志
$ git log --oneline dc4e8fa add aditional number 13a6963 insert lines c2b7f71 update number abfcfbc second good 84ec8c3 first good -
查看修改內(nèi)容
$ git log --oneline -p -3 dc4e8fa add aditional number diff --git a/test.c b/test.c index 2ff46c8..ab7998f 100644 --- a/test.c +++ b/test.c @@ -1,3 +1,3 @@ -3 +3 4 5 13a6963 insert lines diff --git a/test.c b/test.c index 00750ed..2ff46c8 100644 --- a/test.c +++ b/test.c @@ -1 +1,3 @@ + 3 + c2b7f71 update number diff --git a/test.c b/test.c index 0cfbf08..00750ed 100644 --- a/test.c +++ b/test.c @@ -1 +1 @@ -2 +3
4.5 補(bǔ)丁操作(參見分布式-Git-向一個項(xiàng)目貢獻(xiàn)#r_project_over_email和分布式 Git - 維護(hù)項(xiàng)目)
該操作用于創(chuàng)建和應(yīng)用patch。
-
標(biāo)準(zhǔn)格式補(bǔ)丁創(chuàng)建
每個標(biāo)準(zhǔn)格式補(bǔ)丁就是1個包含提交消息、修改文件概述和修改文件細(xì)節(jié)的mbox格式文件:
$ cat 0001-test1.patch From 0d57e1ea1a27c54c7ec62cacfccb7d037923150a Mon Sep 17 00:00:00 2001 From: matt <matt@pc.com> Date: Mon, 28 May 2018 16:29:57 +0800 Subject: [PATCH 1/2] test1 --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) !!!此處可以增加自定義信息以方便閱讀,應(yīng)用補(bǔ)丁時會被忽略。!!! diff --git a/README b/README index df1d5d6..3409f8c 100644 --- a/README +++ b/README @@ -5,7 +5,7 @@ Summary: ======== - +1111111111111111111111111111111 This directory contains the source code for U-Boot, a boot loader for Embedded boards based on PowerPC, ARM, MIPS and several other processors, which can be installed in a boot ROM and used to -- 2.10.1.windows.1操作命令如下所示:
-
git format-patch -M master
為主線上不存在的每個提交創(chuàng)建一個標(biāo)準(zhǔn)格式補(bǔ)丁文件,同時查找重命名操作。注意,該操作需要切換到當(dāng)前工作分支,并與主線同步后執(zhí)行,即
git checkout <工作分支>和git rebase master之后。 -
git format-patch <起始提交ID或者標(biāo)簽>...<結(jié)束提交ID或者標(biāo)簽>
為當(dāng)前分支上起始提交ID或者標(biāo)簽與結(jié)束提交ID或者標(biāo)簽之間的每個提交創(chuàng)建一個標(biāo)準(zhǔn)格式補(bǔ)丁文件,不包括起始提交ID或者標(biāo)簽,但是包含結(jié)束提交ID或者標(biāo)簽。
注意:
-
--cover-letter選項(xiàng)用于創(chuàng)建郵一個額外的mbox格式文件,包含所有提交的信息,而不只是某一個提交的信息。$ cat 0000-cover-letter.patch From 89d4c523ebf5bb6c700bcbf8e2c899c3f1d345fe Mon Sep 17 00:00:00 2001 From: matt <matt@pc.com> Date: Tue, 29 May 2018 09:28:44 +0800 Subject: [PATCH 0/2] *** SUBJECT HERE *** *** BLURB HERE *** matt (2): test1 test2 README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -- 2.10.1.windows.1 -
結(jié)束提交ID或者標(biāo)簽可以省略,默認(rèn)為HEAD。
-
-
git am <標(biāo)準(zhǔn)格式補(bǔ)丁文件>
從標(biāo)準(zhǔn)格式補(bǔ)丁文件中讀取補(bǔ)丁內(nèi)容并應(yīng)用到當(dāng)前分支。注意,補(bǔ)丁文件應(yīng)用沖突時,該操作會停下來,提示手工解決沖突,并在沖突解決后使用
git am --resolved繼續(xù)應(yīng)用下一個補(bǔ)丁:$ vim README $ git add ticgit.gemspec $ git am --resolved Applying: test1當(dāng)然,也可以跳過(
git am --skip)或者終止(git am --abort)本次操作。
-
-
diff格式補(bǔ)丁
diff格式補(bǔ)丁使用diff命令創(chuàng)建,就是一個包含修改內(nèi)容的文本文件,不包含提交消息和修改文件概述,但是可已經(jīng)將多個提交的修改合并到一個文件中,方便閱讀,但是應(yīng)用補(bǔ)丁時只有補(bǔ)丁內(nèi)容全部應(yīng)用和完全不應(yīng)用兩種可能。
$ cat patch.txt diff --git a/README b/README index df1d5d6..3409f8c 100644 --- a/README +++ b/README @@ -5,7 +5,7 @@ Summary: ======== - +1111111111111111111111111111111 This directory contains the source code for U-Boot, a boot loader for Embedded boards based on PowerPC, ARM, MIPS and several other processors, which can be installed in a boot ROM and used to-
git diff -c -p <起始提交ID或者標(biāo)簽>...<結(jié)束提交ID或者標(biāo)簽> > <補(bǔ)丁文件名稱>
將當(dāng)前分支上起始提交ID或者標(biāo)簽與結(jié)束提交ID或者標(biāo)簽之間的所有修改創(chuàng)建一個diff格式補(bǔ)丁,不包括起始提交ID或者標(biāo)簽,但是包含結(jié)束提交ID或者標(biāo)簽。注意,
結(jié)束提交ID或者標(biāo)簽可以省略,默認(rèn)為HEAD,例如:git diff -c -p HEAD^ > patch.txt
-
git apply <補(bǔ)丁文件名稱>
讀取補(bǔ)丁內(nèi)容并應(yīng)用到當(dāng)前分支。注意,本操作只修改當(dāng)前分支文件,不會自動創(chuàng)建提交。
-