git作為時下最流行的代碼管理工具,Git權威指南總結了十條喜歡Git的理由:
- 異地協同工作;
- 現場版本控制;
- 重寫提交說明;
- 無盡的后悔藥;
- 更好用的提交列表;
- 更好的差異比較;
- 工作進度保存;
- 作為SVN前端實現移動辦公;
- 無處不在的分頁器;
- 快。
其中:
git作為分布式代碼管理工具,每個運行節點都保存有代碼倉庫的所有內容,都可以用來恢復服務器上的代碼倉庫;
git保存了所有代碼倉庫的操作記錄,因此對本地代碼倉庫的操作都不需要進行任何備份,都可以無限回退。
1. 概述
1.1 git客戶端安裝
- 官方Windows客戶端:主要使用Git Bash以命令行模式操作,但也支持GUI(gitk/git GUI),使用方法參見官方使用說明;
- 官方Linux客戶端:服務器已默認安裝;
- 更多圖形工具,建議使用Source Tree。
1.2 git客戶端配置
遠程倉庫可以通過網頁方式訪問,但通常情況下仍然需要創建本地倉庫:
-
創建本地 SSH key:
- Windows下打開Git Bash,Linux下打開終端;
- 執行
ssh-keygen
,所有提示均回車確認,生成私鑰和公鑰:<當前用戶根目錄>/.ssh/id_rsa
<當前用戶根目錄>/.ssh/id_rsa.pub - 查看公鑰文件內容并復制,注意不要復制命令本身
cat <當前用戶根目錄>/.ssh/id_rsa.pub
-
添加遠程倉庫訪問權限,不同的服務器會有不同的配置方法:
- GitHub需要從右上角頭像右側的向下箭頭進入settings->SSH and GPG keys來添加或者直接通過GitHub客戶端自動添加;
- gitolite需要將SSH公鑰拷貝到gitolite-admin目錄下的keydir目錄中,并需要gitolite.conf已配置合適的訪問權限。
注意:
- 本機SSH 私鑰id_rsa不能刪除。
- 本機SSH key只需要創建一對,不需要為每個服務器都創建一對。
-
創建本地倉庫并配置
- 回到Git Bash/終端;
- 執行
git clone ssh://xxx.git
- 執行本地配置(更多配置參見自定義-Git-配置-Git)
git 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
注意:
- 自動補齊: Windows客戶端默認支持命令補齊,服務器上Linux已經配置自動補齊,自行安裝的Linux需要參考Git基礎-技巧和竅門進行配置;
- 命令別名:git允許為常用操作設置別名,以簡化操作(參見Git-基礎-Git-別名):
git config --global alias.ci commit
git config --global alias.unstage 'reset HEAD --'
2. git基礎
2.1 基本工作流程
2.2 獲取幫助信息
-
聯機幫助
git help
git help <命令名稱>
2.3 合并比較結果閱讀
git支持外部比較/合并工具(參見外部的合并與比較工具配置說明),但通常使用更為直接的命令行方式:
- diff結果閱讀
--- a/src/test.txt :原始文件(以---開頭)
+++ b/src/test.txt :目標文件(以+++開頭)
@@ -1,3 +1,3 @@ :當前差異塊的比較對象為原始文件的第1行開始的3行與目標文件的地1行開始的3行
-orign :只存在于原始文件(以-開頭)
+modified :只存在于目標文件(以+開頭)
以空格開頭 : 同時存在于原始文件和目標文件
- merge結果閱讀
<<<<<<<
當前分支代碼
=======_
其他分支合并進來的代碼
>>>>>>>
2.4 提交(commit)消息格式
git提交消息是日志回溯/代碼審查/二分法問題查找的基礎,建議參考thoughtbot規范:
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倉庫構成及訪問路徑
3.1 遠程倉庫
遠程倉庫是服務器上的git倉庫,支持如下常用操作(更多操作參見Git-基礎-遠程倉庫的使用):
3.1.1 基本操作
-
查看本地倉庫遠程倉庫列表
git remote -v
如下所示:
$ git remote -v origin ssh://xxx.git (fetch) origin ssh://xxx.git (push)
注意:每個本地倉庫可以從多個遠程倉庫獲取代碼,當前僅包含一個遠程倉庫origin。
-
查看遠程倉庫概況
git remote show <遠程倉庫名稱>
如下所示:
該操作可用于查看遠程倉庫的地址,分支情況,與本地分支的差別等等。
3.1.2 從遠程倉庫到本地倉庫
-
創建新的本地倉庫
git clone <遠程倉庫路徑> <可選的本地倉庫目錄名稱>
-
從遠程倉庫獲取最新內容,包括新的分支以及原有分支上的改動
git fetch
-
從遠程倉庫獲取最新內容,并合并到當前分支
git pull
注意:
- 該操作相當于
git fetch
+git merge origin/<當前分支名稱>
,因此出現沖突時可以使用git merge --abort
來終止; - 如果發生沖突,應當順序執行如下操作:
- 使用
git merge --abort
終止本次操作; - 使用
git checkout -b temp
創建并切換到1個臨時分支; - 使用
git branch -D <當前分支名稱>
刪除當前分支; - 使用
git checkout <當前分支名稱>
重新從遠程分支創建本地分支; - 使用
git branch -D temp
刪除臨時分支。
- 使用
- !!!請勿使用--rebase選項,除非你知道你在干什么!!!。
- 該操作相當于
3.1.3 從本地倉庫到遠程倉庫
-
本地倉庫更新到遠程倉庫
git push
注意:
- 若本地分支在遠程倉庫中沒有對應的分支,則本操作會在遠程倉庫中創建同名分支并自動關聯;
-
若與遠程倉庫代碼沖突且確認本地倉庫沒有問題,例如使用
git rebase
與master分支同步后,則可以使用git push --force
來強制推送到服務器,從而使用本地倉庫覆蓋遠程倉庫;此時,遠程倉庫中的修改日志將會丟失。
3.2 本地倉庫
本地倉庫是當前工作機器上的git倉庫,支持如下常用操作:
3.2.1 查看本地倉庫狀態
- 查看總體狀態
git status
命令結果中注釋如下:
- 注1: 本地倉庫當前分支名稱;
- 注2: 本地倉庫當前分支與遠程倉庫同名分支之間的差異;
- 注3: 推薦執行的操作;
- 注4: 暫存區(stage)內容;
- 注5: 工作區內容,對倉庫中文件的修改;
- 注6: 工作區內容,未加入到倉庫中的文件。
3.2.2 查看本地倉庫日志(參見Git-工具-選擇修訂版本)
-
查看所有或某個文件的修改記錄
git log <可選文件路徑>
-
查看所有或某個文件的修改記錄的概要(修改文件列別行數等)
git log --stat <可選文件路徑>
-
圖形化簡略模式查看倉庫日志
git log --oneline --graph
注意:在提交pull request之前,建議使用該命令確認需要合入主線的分支上沒有重疊區域,例如下圖中紅圈所示的重疊線條,否則出現問題時難以定位錯誤提交:
-
查看本地分支與遠程倉庫master分支的差別,即本地分支對應的pull request包含的內容
git log --oneline --left-right origin/master...<本地分支名稱>
對于未與遠程倉庫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 ...
其中,
<
代表僅存在于遠程分支上的提交,>
代表僅存在于本地分支上的提交。而已經與遠程倉庫master分支同步即rebase的分支,則只包含>
,即即僅存在于本地分支上的提交。 -
查看某次提交中所有或某個文件的具體修改內容
git show <提交ID> <可選文件路徑>
-
查看文件的歷史版本
git show <提交ID>:<文件路徑>
-
查看某個文件中所有或指定行的修改記錄
git blame <文件路徑>
git blame -L <起始行>,<結束行> <文件路徑>
git blame -L <起始行>,<+行數> <文件路徑>
3.2.3 查看本地倉庫的git操作記錄并無限回退
- 查看操作記錄
git reflog
-
回退到某次操作后的狀態
git reset HEAD@{序號}
注意:
- 沒有提到到倉庫中的代碼無法恢復;
- 暫存區的代碼會受影響,如需要保留可先提交到本地倉庫進行備份。
3.3 分支
分支是指向提交的的可變指針(參見Git-分支-分支簡介),每個git倉庫都有一個默認創建的master分支和若干其他分支,支持如下常用操作:
3.3.1 查看分支信息
-
查看本地分支信息
git branch
注意:當前分支名稱之前會有
*
標志。 -
查看本地分支詳細信息
git branch -v
- 查看包含分支標簽的本地倉庫日志
git log --oneline --decorate
- 查看遠程倉庫分支信息
git branch -r
- 查看所有分支(包含本地和遠程倉庫)信息
git branch -a
3.3.2 從當前分支到其他分支
-
切換到本地倉庫或遠程倉庫已有分支
git checkout <分支名稱>
-
從當前分支創建一個新分支并切換到新分支
git checkout -b <新分支名稱>
-
從某個提交創建一個新分支并切換到新分支(用于查看內容或者查找問題)
git checkout <提交ID> -b <新分支名稱>
-
刪除某個分支
git branch -D <分支名稱>
3.3.3 從其他分支到當前分支
-
合并其他分支到當前分支,
git merge <其他分支名稱>
注意:
- 該操作有可能造成提交交錯,影響問題定位,因此不建議使用,除非你知道自己在干什么!!!;
- 如果合并過程中有沖突,需要順序執行如下操作:
- 編輯沖突文件,或刪除不需要的文件;
- 使用
git add -u
將修改添加到暫存區; - 使用
git commit
提交修改。
-
終止當前合并操作
git merge --abort
-
將其他分支的某個提交合并到當前分支
git cherry-pick <提交ID>
3.4 工作區和暫存區
工作區是工作目錄的形象化稱呼,實際上就是當前分支最新版本的本地副本;暫存區(stage)則是包含將要提交到本地倉庫中的文件的索引列表(參見Git權威指南-git暫存區)。
3.4.1 查看工作區和暫存區內容
-
查看工作區中文件的修改內容,即比較工作區與暫存區中的文件
git diff <可選路徑或文件名>
-
查看暫存區中文件的修改內容,即比較暫存區與HEAD的文件
git diff --cached <文件名>
-
比較工作區與某個提交中的文件
git diff <提交ID> <可選路徑或文件名>
-
比較暫存區與某個提交中的文件
git diff --cached <提交ID> <可選路徑或文件名>
-
比較2個提交中的文件
git diff <提交ID1> <提交ID2> <可選路徑或文件名>
git diff --name-only <提交ID1> <提交ID2> <可選路徑或文件名>注意:
- 2個提交中必須包含對要比較的文件的修改,且
提交ID1
更舊; -
--name-only
用于只顯示文件名。
- 2個提交中必須包含對要比較的文件的修改,且
3.4.2 從工作區到暫存區
-
將工作區中的所有或某個文件放到暫存區
git add <文件或目錄路徑>
-
將工作區中所有對倉庫中已有代碼的修改放到暫存區
git add -u
-
以交互方式暫存文件
git add -i
注意:
- 該操作可以每一個被修改的文件和被修改的文件中的每一處修改都作出是否提交到暫存區的選擇;
- 詳細操作參見Git-工具-交互式暫存。
-
刪除文件和目錄
git rm
git rm -r -
移動文件和目錄
git mv
3.4.3 從暫存區到工作區
- 將暫存區中對倉庫中所有或某個文件的修改恢復到工作區
git reset HEAD <可選的文件或目錄路徑>
3.4.4 從暫存區到本地倉庫
-
將暫存區中的內容提交到本地倉庫(簡單注釋)
git commit -m "注釋信息"
-
將暫存區中的內容提交到本地倉庫(復雜注釋,將會進入文本編輯界面,默認使用vi)
git commit
-
修改上次提交的注釋信息
git commit --amend -m "注釋信息"
3.4.5 從本地倉庫到暫存區即清除暫存區
-
使用本地倉庫中某個提交的代碼覆蓋暫存區并更新HEAD指針
git reset <提交ID>
注意,工作區的內容不受影響,但是暫存區中未提交到本地倉庫中的修改會被覆蓋。
3.4.6 從本地倉庫到工作區
-
使用本地倉庫中的最新代碼覆蓋工作區中的內容,即撤銷工作區內的所有或某個文件的修改
git checkout .
git checkout -- <文件或者目錄名>注意:本操作實質上是用本地倉庫中的數據覆蓋工作區中的內容。
-
使用本地倉庫中某個提交的內容覆蓋工作區中的某個文件或所有內容
git checkout <提交ID> <可選的文件或者目錄名>
-
使用本地倉庫中某個提交的內容覆蓋工作區和暫存區并更新HEAD指針
git reset --hard <提交ID>
3.4.7 從工作區到本地倉庫
-
直接將文件提交到本地倉庫
git commit -a -m "注釋信息"
注意,該操作不經過暫存區,務必慎用!!!
3.4.8 清除工作區
- 清除工作區
git clean -fd
3.5 臨時緩沖區
臨時緩沖區(stash)是保存臨時修改內容的各個分支共享的全局緩沖區,支持如下常用操作(參見Git-工具-儲藏與清理):
3.5.1 查看臨時緩沖區
-
顯示臨時緩沖區內保存的工作進度
git stash list
如下所示:
$ git stash list stash@{0}: On bugfix/KTOS-499-pci-decouple: pci review
其中,第1個
:
之前的部分是每個工作進度的標簽,2個:
之間的部分是保存該工作進度時所在的分支,第2個:
之后的部分是該工作進度的描述信息。 -
顯示臨時緩沖區某個工作進度的內容
git stash show stash@{序號}
3.5.2 從工作區和暫存區到臨時緩沖區
-
將工作區和暫存區中對本地倉庫中已有代碼的修改備份到臨時緩沖區
git stash save "緩沖區描述"
-
將工作區和暫存區中的所有修改(包括不在本地倉庫中的文件)備份到臨時緩沖區
git stash save -u "緩沖區描述"
3.5.3 從臨時緩沖區到工作區
-
將臨時緩沖區中對倉庫中代碼的修改彈出到工作區
git stash pop stash@{序號}
-
將臨時緩沖區中對倉庫中代碼的修改應用到工作區(保留緩存區中的工作進度)
git stash apply stash@{序號}
4. git進階
4.1 變基(參見Git權威指南-改變歷史)
-
該操作的基本語法為:
git rebase --onto <目的提交> <起始提交> <結束提交>
變基操作會為切換到 <目的提交>,然后把<起始提交>和<結束提交>之間的提交逐條疊加到<目的提交>之后;如果
--onto <目的提交>
未指定,則使用<起始提交>;如果<結束提交>未指定,則使用當前分支;變基操作通常用于當前任務分支跟主線同步,例如
git rebase master
;變基操作中出現問題時,需要根據對沖突的文件提示進行修改,完成后使用
git add -u
提交到暫存區,并使用git rebase --continue
繼續或git rebase --skip
跳過當前提交繼續同步;變基操作可以被
git rebase --abort
終止以恢復到操作前狀態;變基操作結束以后,推送到服務器時,如果報錯,需要使用
git push --force
強制推送。-
如果修改內容較多,且長時間未同步,可能會出現同一文件多次沖突,因此強烈建議打開Rerere功能:
git config --global rerere.enabled true
使能后,沖突解決方案會被記錄,并在再次遇到時自動應用,不需要再吃手工編輯文件解決,只需要
git add -u
即可。
4.2 二分法查找錯誤版本(參考Git權威指南-二分查找)
該方法用于快速定位問題,但是需要如下條件作為前提才能高效工作:
- 提交線性排序,不存在下圖所示的重疊部分:
- 每個關鍵提交最好都能編譯通過或運行。
該操作具體步驟如下(使用簡單實例,具體使用時根據需要調整):
-
查看當前日志
$ git log --oneline** ebc659b second bad 2fe7f29 first bad abfcfbc second good 84ec8c3 first good
-
啟動查找
$ git bisect start
-
標志當前版本為壞版本
$ git bisect bad
-
標志某個好版本作為起點
$ git bisect good 84ec8c3 Bisecting: 0 revisions left to test after this (roughly 1 step) [2fe7f29987123abe3fa0cb3429c07b597f86594c] first bad
此時會自動跳轉到中間版本:
$ git log --oneline 2fe7f29 first bad abfcfbc second good 84ec8c3 first good
-
如果當前版本為壞版本,標志他
$ git bisect bad Bisecting: 0 revisions left to test after this (roughly 0 steps) [abfcfbc361beb42551b4219d6d70ccb1fe3ac103] second good
此時會自動跳轉到中間版本:
$ git log --oneline abfcfbc second good 84ec8c3 first good
-
如果當前版本為好版本,標志他
$ 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
找到第一個壞版本時,自動結束,不再跳轉到中間版本:
$ 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中應當包含盡可能少的提交,因此在推送到服務器之前,每個功能點或者修改點包含的所有提交都應當壓縮成一個提交,并編譯通過,最好能夠通過基本測試。
該操作具體步驟如下(使用簡單實例,具體使用時根據需要調整):
-
查看當前日志
$ 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
-
查看修改內容
$ 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
-
查看修改內容
$ 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-工具-重寫歷史#拆分提交)
該操作用于對不合理的提交壓縮進行拆分,以方便cherry-pick和二分法查找等后續操作。
注意:該操作也可以用于調整提交的順序,參見Git-工具-重寫歷史#重新排序提交。
該操作具體步驟如下(使用簡單實例,具體使用時根據需要調整):
-
查看日志
$ git log --oneline 0b22507 add aditional number abc373f update number and insert lines abfcfbc second good 84ec8c3 first good
假定
abc373f
為需要拆分的提交。 -
查看修改內容
$ 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^
此時會進入vim界面,顯示如下內容:
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 ~
根據提示,將需要拆分的提交前面的
pick
修改為edit
(此處可以調整提交順序):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
-
查看修改內容
$ 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 +
-
將修改內容保存到臨時緩沖區
$ git stash save "msg split" Saved working directory and index state On (no branch): msg split HEAD is now at abfcfbc second good
-
將修改內容應用到工作區并保留緩沖區中的進度
$ git stash apply stash@{0}
-
移除不需要的修改并提交(此處僅保留數字更新)
$ 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
-
查看修改內容
$ 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
-
將修改內容彈出到工作區,修改沖突后再次提交
$ 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
-
查看修改內容
$ 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
-
繼續變基
$ 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
-
查看修改內容
$ 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 補丁操作(參見分布式-Git-向一個項目貢獻#r_project_over_email和分布式 Git - 維護項目)
該操作用于創建和應用patch。
-
標準格式補丁創建
每個標準格式補丁就是1個包含提交消息、修改文件概述和修改文件細節的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(-) !!!此處可以增加自定義信息以方便閱讀,應用補丁時會被忽略。!!! 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
為主線上不存在的每個提交創建一個標準格式補丁文件,同時查找重命名操作。注意,該操作需要切換到當前工作分支,并與主線同步后執行,即
git checkout <工作分支>
和git rebase master
之后。 -
git format-patch <起始提交ID或者標簽>...<結束提交ID或者標簽>
為當前分支上起始提交ID或者標簽與結束提交ID或者標簽之間的每個提交創建一個標準格式補丁文件,不包括起始提交ID或者標簽,但是包含結束提交ID或者標簽。
注意:
-
--cover-letter
選項用于創建郵一個額外的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
-
結束提交ID或者標簽
可以省略,默認為HEAD
。
-
-
git am <標準格式補丁文件>
從標準格式補丁文件中讀取補丁內容并應用到當前分支。注意,補丁文件應用沖突時,該操作會停下來,提示手工解決沖突,并在沖突解決后使用
git am --resolved
繼續應用下一個補丁:$ vim README $ git add ticgit.gemspec $ git am --resolved Applying: test1
當然,也可以跳過(
git am --skip
)或者終止(git am --abort
)本次操作。
-
-
diff格式補丁
diff格式補丁使用diff命令創建,就是一個包含修改內容的文本文件,不包含提交消息和修改文件概述,但是可已經將多個提交的修改合并到一個文件中,方便閱讀,但是應用補丁時只有補丁內容全部應用和完全不應用兩種可能。
$ 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或者標簽>...<結束提交ID或者標簽> > <補丁文件名稱>
將當前分支上起始提交ID或者標簽與結束提交ID或者標簽之間的所有修改創建一個diff格式補丁,不包括起始提交ID或者標簽,但是包含結束提交ID或者標簽。注意,
結束提交ID或者標簽
可以省略,默認為HEAD
,例如:git diff -c -p HEAD^ > patch.txt
-
git apply <補丁文件名稱>
讀取補丁內容并應用到當前分支。注意,本操作只修改當前分支文件,不會自動創建提交。
-