Git 系列教程(5)- 記錄每次更新到倉庫


文件狀態

你工作目錄下的每一個文件只有兩種狀態:tracked 或 untracked

 

tracked

  • 已跟蹤 tracked 的文件是指那些被納入了版本控制的文件
  • 在上一次快照中有它們的記錄,在工作一段時間后, 它們的狀態可能是未修改unmodified、已修改modified 或已放入暫存區staged
  • 簡單來說,已跟蹤 tracked 的文件就是 Git 知道的文件

 

untracked

  • 工作目錄中除 tracked 文件外的其它所有文件都屬於 untracked 文件
  • 它們既不存在於上次快照的記錄中,也沒有被放入暫存區
  • 初次 clone 某個倉庫的時候,工作目錄中的所有文件都屬於 tracked 文件,並處於 unmodified
  • 編輯文件后,Git 將它們標記為 modified 文件。 在工作時,你可以選擇性地將這些修改過的文件放入暫存區,然后提交所有已暫存的修改

 

文件的狀態變化周期

Git 下文件生命周期圖。
 

檢查當前文件狀態

可以用 git status 命令查看哪些文件處於什么狀態。 如果在克隆倉庫后立即使用此命令,會看到類似這樣的輸出:

git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean

可以獲取到的內容

  • 所有 tracked 件在上次提交后都未被更改過
  • 當前目錄下沒有出現任何 untracked 的新文件,否則 Git 會在這里列出來
  • 還顯示了當前所在分支,並告訴你這個分支同遠程服務器上對應的分支沒有偏離,現在,分支名是“master”,這是默認的分支名

 

在項目下創建一個新的 README 文件,使用 git status 命令,將看到一個新的 untracked 文件

echo 'My Project' > README
$ 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)

    README

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

可以獲取到的內容

  •  README 文件出現在 Untracked files 下面
  • untracked 的文件意味着 Git 在之前的快照(提交)中沒有這些文件

 

如何跟蹤

git add 文件名

# 更新目錄下所有文件
git add .

后面會再詳細講這個命令

 

跟蹤新文件

使用命令 git add 開始跟蹤一個文件。 所以,要跟蹤 README 文件,運行:

git add README

 

此時再運行 git status 命令,會看到 README 文件已被跟蹤,並處於 staged

git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)

    new file:   README

可以獲取到的內容

  • 只要在 Changes to be committed 這行下面的,就說明是 staged 狀態
  • 如果此時提交,那么該文件在你運行 git add 時的版本將被留存在后續的歷史記錄中

 

暫存已修改的文件

如果修改了一個名為 CONTRIBUTING.md 的已被 tracked 的文件,然后運行 git status 命令,會看到下面內容

git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   README

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:   CONTRIBUTING.md

可以獲取到的內容

  • CONTRIBUTING.md 出現在 Changes not staged for commit 這行下面,說明已跟蹤文件的內容發生了變化,但還沒有放到暫存區
  • 要暫存這次更新,需要運行 git add 命令

 

再次運行 git add 命令

運行 git add 將“CONTRIBUTING.md”放到暫存區,然后再看看 git status 的輸出:

$ git add CONTRIBUTING.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   README
    modified:   CONTRIBUTING.md

 

再次修改文件內容

編輯 CONTRIBUTING.md,再運行 git status 看看

$ vim CONTRIBUTING.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   README
    modified:   CONTRIBUTING.md

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:   CONTRIBUTING.md

可以獲取到的內容

  • CONTRIBUTING.md 文件同時出現在暫存區和非暫存區
  • 實際上 Git 只不過暫存了運行 git add 命令時的版本
  • 如果你現在提交代碼,CONTRIBUTING.md 的版本是你最后一次運行 git add 命令時的那個版本,而不是當前版本
  • 所以,運行了 git add 之后又編輯了文件,需要再次 git add 把最新版本暫存
$ git add CONTRIBUTING.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   README
    modified:   CONTRIBUTING.md
 

真實的實際操作栗子

 

狀態簡述

  • git status 命令的輸出十分詳細,但其用語有些繁瑣
  • git status -s 或 git status --short ,輸出結果更加簡潔
git status -s
 M markers.py
 M test.py
D  test_func01.py
D  test_login.py
?? text.txt

查看已暫存和未暫存的修改

修改 README 文件后暫存,然后編輯 CONTRIBUTING.md 文件后先不暫存, 運行 status 命令將會看到:

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    modified:   README

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:   CONTRIBUTING.md

 

初次使用 git diff

要查看尚未暫存的文件更新了哪些部分,不加參數直接輸入 git diff

$ git diff
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 8ebb991..643e24f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -65,7 +65,8 @@ branch directly, things can get messy.
 Please include a nice description of your changes when you submit your PR;
 if we have to read the whole diff to figure out why you're contributing
 in the first place, you're less likely to get feedback and have your change
-merged in.
+merged in. Also, split your changes into comprehensive chunks if your patch is
+longer than a dozen lines.

 If you are starting to work on a particular area, feel free to submit a PR
 that highlights your work in progress (and note in the PR title that it's

 

實際栗子

 

git diff 的作用 

  • 比較的是當前文件和暫存區快照之間的差異,也就是修改之后還沒有暫存起來的變化內容
  • 若要查看已暫存且要添加到下次提交里的內容,可以用 git diff --staged 命令
  • 會比較已暫存文件與最后一次提交的文件差異
$ git diff --staged
diff --git a/README b/README
new file mode 100644
index 0000000..03902a1
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
+My Project

 

git diff

git diff 本身只顯示尚未暫存的改動,而不是自上次提交以來所做的所有改動,所以有時候一下子暫存了所有更新過的文件,運行 git diff 后卻什么也沒有

像之前說的,暫存 CONTRIBUTING.md 后再編輯,可以使用 git status 查看已被暫存的修改或未被暫存的修改。 如果我們的環境(終端輸出)看起來如下:

$ git add CONTRIBUTING.md
$ echo '# test line' >> CONTRIBUTING.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    modified:   CONTRIBUTING.md

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:   CONTRIBUTING.md

 

現在運行 git diff 看暫存前后的變化:

$ git diff
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 643e24f..87f08c8 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -119,3 +119,4 @@ at the
 ## Starter Projects

 See our [projects list](https://github.com/libgit2/libgit2/blob/development/PROJECTS.md).
+# test line

 

然后用 git diff --cached 查看已經暫存起來的變化( --staged 和 --cached 是同義詞):

$ git diff --cached
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 8ebb991..643e24f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -65,7 +65,8 @@ branch directly, things can get messy.
 Please include a nice description of your changes when you submit your PR;
 if we have to read the whole diff to figure out why you're contributing
 in the first place, you're less likely to get feedback and have your change
-merged in.
+merged in. Also, split your changes into comprehensive chunks if your patch is
+longer than a dozen lines.

 If you are starting to work on a particular area, feel free to submit a PR
 that highlights your work in progress (and note in the PR title that it's

 

實際栗子

 

提交更新

  • 現在的暫存區已經准備就緒,可以提交了
  • 在此之前,請務必確認還有什么已修改或新建的文件還沒有 git add 過, 否則提交的時候不會記錄這些尚未暫存的變化
  • 這些已修改但未暫存的文件只會保留在本地磁盤
  • 所以,每次准備提交前,先用 git status 看下,你所需要的文件是不是都已暫存起來了, 然后再運行提交命令 git commit
git commit -m "test"

可以獲取到的內容

  • commit 之后 git status 可以看到本地是干凈的
  • 提交后會顯示當前是在哪個分支(master)提交的
  • 本次提交的完整 SHA-1 校驗和是什么(9a8c6b3
  • 以及在本次提交中,有多少文件修訂過,多少行添加和刪改過

 

重點

  • 提交時(git commit)記錄的是放在暫存區域的快照
  • 每一次運行提交操作,都是對項目作一次快照,以后可以回到指定快照版本,或者進行比較

 

跳過使用暫存區域

  • Git 提供了一個跳過使用暫存區域的方式
  • git commit 加上 -a 選項,Git 就會自動把所有已經跟蹤過的文件暫存起來一並提交,從而跳過 git add 步驟

-a 選項使本次提交包含了所有修改過的文件,但是要小心,有時這個選項會將不需要的文件添加到提交中

 

移除文件

兩種情況

  • 直接刪除文件(從本地刪除):-f 參數
  • 只是將文件從 Git 的暫存區移除,並不會刪除本地文件:--cached

直接看栗子

已跟蹤的文件(出現在暫存區)的文件被執行 git rm --cached 命令后,它會被移出暫存區,重新變成一個未跟蹤的文件

 

移動文件

在 Git 中對文件改名

$ git mv file_from file_to

 

查看狀態信息,也會看到關於重命名操作的說明

文件會自動提交到暫存區,且不需要手動執行 git add 

 

其實,運行 git mv 就相當於運行了下面三條命令

$ mv README.md README
$ git rm README.md
$ git add README

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM