天天看點

Git筆記02(Git基礎指令)檔案操作代碼復原

本文将介紹本地倉庫的基本操作:

  • 檔案操作指令
  • 代碼復原指令

掌握好這些指令之後,就能完成大部分個人作業了。

檔案操作

1. 檢查狀态 - git status

git status

是一個非常重要的指令,它顯示你的代碼在工作區和暫存區的狀态。

$ git status

On branch master
Untracked files:
  (use "git add ..." to include in what will be committed)

    modified:   readme.txt
           

可以加

-s

參數,以獲得簡短的結果輸出。若沒有這個 标記,則會有更多的提示與上下文提醒。

2. 檢視改動 - git diff

Git筆記02(Git基礎指令)檔案操作代碼復原

git diff

我們可以通過

git diff

命對比三個區之間的資料差别。

指令 作用
工作區vs緩存區
git diff HEAD 工作區vs版本區
git diff --cached 緩存區vs版本區

目前三個區的資料是一緻的,執行指令都為空。

結果
Git筆記02(Git基礎指令)檔案操作代碼復原
image
Git筆記02(Git基礎指令)檔案操作代碼復原
Git筆記02(Git基礎指令)檔案操作代碼復原

然後給 master.txt 添加一行内容後,現在工作區内容發生變化,暫存區和版本庫内容不變。

!()[]

Git筆記02(Git基礎指令)檔案操作代碼復原
Git筆記02(Git基礎指令)檔案操作代碼復原
Git筆記02(Git基礎指令)檔案操作代碼復原

執行

git add master.txt

之後,修改同步到緩存區,現在工作區與緩存區資料一緻。

Git筆記02(Git基礎指令)檔案操作代碼復原
Git筆記02(Git基礎指令)檔案操作代碼復原
Git筆記02(Git基礎指令)檔案操作代碼復原

git commit

操作後,修改已經同步到版本庫,三區資料再次保持一緻。

Git筆記02(Git基礎指令)檔案操作代碼復原
Git筆記02(Git基礎指令)檔案操作代碼復原
Git筆記02(Git基礎指令)檔案操作代碼復原

3. 檢視版本庫送出記錄 - git log

簡而言之,就是檢視版本庫中的送出曆史記錄。

這條指令有很多參數選項,我在下面隻列舉幾個常用的參數。

一、不帶參數

  1. 如果不帶任何參數,它會列出所有曆史記錄,最近的排在最上方,顯示送出對象的哈希值,作者、送出日期、和送出說明
  2. 如果記錄過多,則按Page Up、Page Down、↓、↑來控制顯示
  3. 按q退出曆史記錄清單
$ git log

commit 723ba27fbf4320237639151a4f44cf7b2cf93999 (HEAD -> master)
Author: ColleenKuang <[email protected]>
Date:   Wed Jun 20 01:11:41 2018 +0800

    add master.txt

commit b556edeab10f7f4365867e0172db4bfeee1b34e6
Author: ColleenKuang <[email protected]>
Date:   Tue Jun 19 23:53:20 2018 +0800

    add version number
           

二、帶參數

  1. --graph 顯示ASCII圖形表示的分支合并曆史
  2. --p 按更新檔顯示每個更新間的差異,比下一條- -stat指令資訊更全
  3. --stat 顯示每次更新的修改檔案的統計資訊,每個送出都列出了修改過的檔案,以及其中添加和移除的行數,并在最後列出所有增減行數小計
  4. --pretty=oneline 一行顯示,隻顯示哈希值和送出說明(--online本身也可以作為單獨的屬性)
  5. -n 顯示前n條log記錄
  6. --author="author_name" 顯示名為author_name貢獻的commit。注意:作者名不需要精确比對,隻需要包含就行了

4. 删除未跟蹤檔案 - git clean

git clean

指令将未跟蹤的檔案從你的工作目錄中移除。它隻是提供了一條捷徑,因為用

git status

檢視哪些檔案還未跟蹤然後手動移除它們也很友善。和一般的

rm

指令一樣,

git clean

是無法撤消的,是以在删除未跟蹤的檔案之前想清楚,你是否真的要這麼做。

$ git clean -n
           

執行一次git clean的『演習』。它會告訴你那些檔案在指令執行後會被移除,而不是真的删除它。

$ git clean -f
           

移除目前目錄下未被跟蹤的檔案。

-f

(強制)标記是必需的,除非

clean.requireForce

配置項被設為了

false

(預設為

true

)。它 不會 删除

.gitignore

中指定的未跟蹤的檔案。

$ git clean -df 
           

移除未跟蹤的檔案,以及目錄。

$ git clean -xf
           

移除目前目錄下未跟蹤的檔案,以及 Git 一般忽略的檔案。

代碼復原

1. 檢出之前的送出 - git checkout

版本控制系統背後的思想就是「安全」地儲存項目的拷貝,這樣你永遠不用擔心什麼時候不可複原地破壞了你的代碼庫。當你建立了項目曆史之後,

git checkout

是一種便捷的方式,來将儲存的快照「加載」到你的開發機器上去。

git checkout

這個指令有三個不同的作用:檢出檔案、檢出送出和檢出分支。在這一章中,我們隻關心前兩種用法。

檢出檔案

git checkout <commit> <file>

執行後,git會從指定的送出中拷貝檔案到暫存區域和工作目錄,而工作區中剩下的檔案不變,接下來看個例子:

Git筆記02(Git基礎指令)檔案操作代碼復原

拷貝檔案到緩存區和工作區

$ git checkout da985 hello.py
           

将送出節點da985中的hello.py複制到工作區和緩存區中,你就可以檢視da985節點的hello.py(如果指令中沒有指定送出節點,則會從暫存區域中拷貝内容。)注意目前分支不會發生變化。

這裡确實會影響你項目的目前狀态。舊的檔案版本會顯示為需要送出的更改,允許你復原到檔案之前的版本。如果你不想保留舊的版本,你可以用下面的指令檢出到最近的版本:

$ git checkout HEAD hello.py
           

檢出送出

git checkout <commit>

執行後,更新工作目錄中的所有檔案,使得和某個特定送出中的檔案一緻。與此同時,HEAD辨別會移動指定的送出。這被稱為分離HEAD。

Git筆記02(Git基礎指令)檔案操作代碼復原

分離的頭指針(匿名分支送出) - Detached HEAD

當HEAD處于分離狀态(不依附于任一分支)時,送出操作可以正常進行,但是不會更新任何已命名的分支。(你可以認為這是在更新一個匿名分支。)

Git筆記02(Git基礎指令)檔案操作代碼復原

一旦此後你切換到别的分支,比如說master,那麼這個送出節點(可能)再也不會被引用到,然後就會被丢棄掉了。注意這個指令之後就不會有東西引用2eecb。

Git筆記02(Git基礎指令)檔案操作代碼復原

但是,如果你想儲存這個狀态,可以用指令

git checkout -b name

來建立一個新的分支。

Git筆記02(Git基礎指令)檔案操作代碼復原

2. 重置送出曆史 - git reset

git reset

重設一個舊的送出,你不得不移除那個送出後的所有送出,再移除那個送出,然後重新送出後面的所有送出。不用說,這并不是一個優雅的復原方案。

此外,

git reset

可以通過設定參數有選擇的變動工作區、緩存區和版本倉庫。

  • --soft – 緩存區和工作目錄都不會被改變
  • --mixed – 預設選項。緩存區和你指定的送出同步,但工作目錄不受影響
  • --hard – 緩存區和工作目錄都同步到你指定的送出
Git筆記02(Git基礎指令)檔案操作代碼復原

The scope of git reset's modes

這些标記往往和

HEAD

作為參數一起使用。比如,

git reset --mixed HEAD

将你目前的改動從緩存區中移除,但是這些改動還留在工作目錄中。另一方面,如果你想完全舍棄你沒有送出的改動,你可以使用

git reset --hard HEAD

。這是

git reset

最常用的兩種用法。

如果你在本地倉庫中作死之後想要毀屍滅迹,

git reset --hard

git clean -f

是你最好的選擇。記住,

git reset

隻影響被跟蹤的檔案,是以還需要一個單獨的指令來清理未被跟蹤的檔案。運作這兩個指令使工作目錄和最近的送出相比對,讓你在幹淨的狀态下繼續工作。

3. 撤銷已送出快照 - git revert

git revert

指令用來撤銷一個已經送出的快照。但是,它是通過搞清楚如何撤銷這個送出引入的更改,然後在最後加上一個撤銷了更改的新送出,而不是從項目曆史中移除這個送出(重寫送出曆史)。這避免了Git丢失項目曆史,這一點對于你的版本曆史和協作的可靠性來說是很重要的。

Git筆記02(Git基礎指令)檔案操作代碼復原

Reverting the 2nd to last commit

$ git checkout hotfix
$ git revert HEAD~2
           

相比

git reset

,它不會改變現在的送出曆史。是以,

git revert

可以用在公共分支上,

git reset

應該用在私有分支上。

你也可以把

git revert

當作撤銷已經送出的更改,而

git reset HEAD

用來撤銷沒有送出的更改。

就像

git checkout

一樣,git revert 也有可能會重寫檔案。是以,Git 會在你執行 revert 之前要求你送出或者緩存你工作目錄中的更改。

小總結

作用域 常用情景
git reset 送出層面 在私有分支上舍棄一些沒有送出的更改
檔案層面 将檔案從緩存區中移除
git checkout 切換分支或檢視舊版本
舍棄工作目錄中的更改
git revert 在公共分支上復原更改
然而并沒有

參考連結:

廖雪峰Git教程 30分鐘git指令入門到放棄 圖解Git 代碼復原:Reset、Checkout、Revert 的選擇

繼續閱讀