1. 程式人生 > >痞子衡嵌入式:第一本Git命令教程(5)- 提交(commit/format-patch/am)

痞子衡嵌入式:第一本Git命令教程(5)- 提交(commit/format-patch/am)

今天 分布 控制系統 rom end stat 準備工作 多少 cond


  今天是Git系列課程第五課,上一課我們做了Git本地提交前的準備工作,今天痞子衡要講的是Git本地提交操作。

  當我們在倉庫工作區下完成了文件增刪改操作之後,並且使用git add將文件改動記錄在暫存區之後,便可以開始將其提交到Git本地倉庫。

1.本地文件改動提交git commit

  Git空間本地的改動完成之後可以直接提交,有如下三種提交命令選項:

1.1將暫存區內容提交git commit -m ["description"]

  暫存區裏目前只有app/app.c文件,我們先將其提交至倉庫。

jay@pc MINGW64 /d/my_project/gittest (master)

$ git commit -m "Initial application"

[master 0a0c0fc] Initial application
 1 file changed, 7 insertions(+)
 create mode 100644 app/app.c

jay@pc MINGW64 /d/my_project/gittest (master)
$ git log

commit 0a0c0fcec8a1ef56bfc6a24e68bbf1436b2ef2cf (HEAD -> master)
Author: Jay Heng <[email protected]>
Date:   Sat Mar 10 21:58:36 2018 +0800

    Initial application

commit 867df08b4e13649e30926b483279dddce32750c2 (origin/master, origin/HEAD)
Author: Jay Heng <[email protected]>
Date:   Sat Mar 10 20:11:04 2018 +0800

    second commit

1.2追加提交git commit --amend -m ["description"]

  工作區裏面還有app/test.c文件處於Untracked狀態,我們想將其也加到1.1的提交裏合並成一個提交。

jay@pc MINGW64 /d/my_project/gittest (master)
$ git add app/test.c

jay@pc MINGW64 /d/my_project/gittest (master)
$ git commit --amend -m "Initial application and test"

[master 589f65b] Initial application and test
 Date: Sat Mar 10 21:58:36 2018 +0800
 2 files changed, 7 insertions(+)
 create mode 100644 app/app.c
 create mode 100644 app/test.c

jay@pc MINGW64 /d/my_project/gittest (master)
$ git log

commit 589f65b386dd4475bb884c40ea1441d8449fdcd1 (HEAD -> master)
Author: Jay Heng <[email protected]>
Date:   Sat Mar 10 21:58:36 2018 +0800

    Initial application and test

commit 867df08b4e13649e30926b483279dddce32750c2 (origin/master, origin/HEAD)
Author: Jay Heng <[email protected]>
Date:   Sat Mar 10 20:11:04 2018 +0800

    second commit

1.3非Untracked文件的改動全部提交git commit -a -m ["description"]

  我們新增一個名叫platform.c空白文件,並將其git add到暫存區;且對已提交的空白test.c文件修改恢復其一開始的內容。此時我們工作區(test.c)和暫存區(platform.c)均存在文件改動。有沒有可能一次性將test.c和platform.c改動提交上去,答案當然是有。

jay@pc MINGW64 /d/my_project/gittest (master)
$ git add app/platform.c

jay@pc MINGW64 /d/my_project/gittest (master)
$ git status

On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   app/platform.c

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   app/test.c

jay@pc MINGW64 /d/my_project/gittest (master)
$ git commit -a -m "Add initial platform and update test"

[master 610feaf] Add initial platform and update test
 2 files changed, 6 insertions(+)
 create mode 100644 app/platform.c

jay@pc MINGW64 /d/my_project/gittest (master)
$ git status

On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

jay@pc MINGW64 /d/my_project/gittest (master)
$ git log

commit 610feafbf5264b66dd0515f90cce79169aebd995 (HEAD -> master)
Author: Jay Heng <[email protected]>
Date:   Sun Mar 11 07:46:16 2018 +0800

    Add initial platform and update test

commit 589f65b386dd4475bb884c40ea1441d8449fdcd1
Author: Jay Heng <[email protected]>
Date:   Sat Mar 10 21:58:36 2018 +0800

    Initial application and test

  需要註意的是git commit -a雖然是-all的簡寫,但其並不是將Git空間內所有改動全部提交,其不會提交工作區裏新建的文件(Untracked狀態)。

2.補丁包方式提交

  Git是分布式版本控制系統,一個項目常常由多個人一起開發,有時候我們想把本地的改動交給別人去完成提交,傳統的做法是把你改動的所有文件全部提取出來打包發送給對方,但顯然這樣做比較繁瑣,而且你的提交描述也容易丟失。Git提供了一種很好方式解決這個需求,即生成一個patch,這個patch就是你本地的一次提交的所有信息,你只需要把這個patch發給別人就可以了。

2.1生成補丁包git format-patch

  git format-patch命令是以本地提交為基礎的,讓我們先看看目前本地有多少提交:

jay@pc MINGW64 /d/my_project/gittest (master)
$ gitk
技術分享圖片

  由上圖可知,倉庫裏一共有4次提交,其中兩次已推送到遠程,還有兩次在本地未推送:

2.1.1指定任意單個提交git format-patch -1 [commit]

  讓我們試著將"Initial application and test"這個提交生成patch:

jay@pc MINGW64 /d/my_project/gittest (master)
$ git format-patch -1 589f65b
0001-Initial-application-and-test.patch

  此時在gittest倉庫目錄下便可以看到生成的.patch文件,讓我們用文本編輯器打開它看一看,確實包含了這個提交的所有改動。

From 589f65b386dd4475bb884c40ea1441d8449fdcd1 Mon Sep 17 00:00:00 2001
From: Jay Heng <[email protected]>
Date: Sat, 10 Mar 2018 21:58:36 +0800
Subject: [PATCH] Initial application and test

---
 app/app.c  | 7 +++++++
 app/test.c | 0
 2 files changed, 7 insertions(+)
 create mode 100644 app/app.c
 create mode 100644 app/test.c

diff --git a/app/app.c b/app/app.c
new file mode 100644
index 0000000..20fe868
--- /dev/null
+++ b/app/app.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+#include <stdlib.h>
+int main(void)
+{
+    printf("hello world\n");
+    return 0;
+}
\ No newline at end of file
diff --git a/app/test.c b/app/test.c
new file mode 100644
index 0000000..e69de29
-- 
2.16.2.windows.1

2.1.2當前提交之前n個提交git format-patch -n

  如果一次想把本地未推送的提交全部生成patch,也可以試試-n參數,-1代表生成最近的一次提交的patch,-2代表生成最近兩次提交的patch,以此類推。這個參數也可以用HEAD替換,HEAD^ 等效於-1,HEAD^^等效於-2,HEAD~n等效於-n。

jay@pc MINGW64 /d/my_project/gittest (master)
$ git format-patch HEAD~3

0001-second-commit.patch
0002-Initial-application-and-test.patch
0003-Add-initial-platform-and-update-test.patch

jay@pc MINGW64 /d/my_project/gittest (master)
$ git format-patch -3

0001-second-commit.patch
0002-Initial-application-and-test.patch
0003-Add-initial-platform-and-update-test.patch

2.1.3某個提交之後的所有提交git format-patch [commit]

  如果你覺得用-n參數顯得有點繁瑣,比如本地有很多個提交,你需要先往回數一共有多少個。還有一個方法是直接指定某個提交,以某個提交為基準往後的所有提交全部生成patch,比如我們以"second commit"為基準:

jay@pc MINGW64 /d/my_project/gittest (master)
$ git format-patch 867df08

0001-Initial-application-and-test.patch
0002-Add-initial-platform-and-update-test.patch

2.2應用補丁包git am

  2.1.3節生成了2個補丁包,讓我們試著用一下這兩個補丁包,在用之前我們需要先把本地倉庫中這兩次提交撤銷並且也不保留在工作區(即完全刪除)。

jay@pc MINGW64 /d/my_project/gittest (master)
$ git reset --hard HEAD~2

HEAD is now at 867df08 second commit

jay@pc MINGW64 /d/my_project/gittest (master)
$ gitk
技術分享圖片

jay@pc MINGW64 /d/my_project/gittest (master)
$ git status

On branch master
Your branch is up to date with 'origin/master'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        0001-Initial-application-and-test.patch
        0002-Add-initial-platform-and-update-test.patch

nothing added to commit but untracked files present (use "git add" to track)

2.2.1指定單個補丁包git am [patch path]

  讓我們試著將0001-Initial-application-and-test.patch打入我們的倉庫。

jay@pc MINGW64 /d/my_project/gittest (master)
$ git am 0001-Initial-application-and-test.patch

Applying: Initial application and test

jay@pc MINGW64 /d/my_project/gittest (master)
$ gitk
技術分享圖片

  細心的朋友可能會註意到,同一個patch在生成和打入的時候SHA-1號是不一樣的,是的,Git會保證任何時候任何人在任何本地倉庫生成的任何提交都是唯一的。

2.2.2指定目錄下所有補丁包git am [patch dir/*.patch]

  讓我們試著將gittest目錄下的所有patch全部打入我們的倉庫,需要註意的是由於2.2.1中已經將編號為0001 patch打入了倉庫,所有我們需要先將這個patch文件刪除,否則在打入的時候會報錯。

jay@pc MINGW64 /d/my_project/gittest (master)
$ git am *.patch

Applying: Add initial platform and update test

jay@pc MINGW64 /d/my_project/gittest (master)
$ gitk
技術分享圖片

痞子衡嵌入式:第一本Git命令教程(5)- 提交(commit/format-patch/am)