本文将介紹本地倉庫的基本操作:
- 檔案操作指令
- 代碼復原指令
掌握好這些指令之後,就能完成大部分個人作業了。
檔案操作
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 diff
我們可以通過
git diff
命對比三個區之間的資料差别。
指令 | 作用 |
---|---|
工作區vs緩存區 | |
git diff HEAD | 工作區vs版本區 |
git diff --cached | 緩存區vs版本區 |
目前三個區的資料是一緻的,執行指令都為空。
結果 | |
---|---|
image | |
然後給 master.txt 添加一行内容後,現在工作區内容發生變化,暫存區和版本庫内容不變。
!()[]
執行
git add master.txt
之後,修改同步到緩存區,現在工作區與緩存區資料一緻。
git commit
操作後,修改已經同步到版本庫,三區資料再次保持一緻。
3. 檢視版本庫送出記錄 - git log
簡而言之,就是檢視版本庫中的送出曆史記錄。
這條指令有很多參數選項,我在下面隻列舉幾個常用的參數。
一、不帶參數
- 如果不帶任何參數,它會列出所有曆史記錄,最近的排在最上方,顯示送出對象的哈希值,作者、送出日期、和送出說明
- 如果記錄過多,則按Page Up、Page Down、↓、↑來控制顯示
- 按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
二、帶參數
- --graph 顯示ASCII圖形表示的分支合并曆史
- --p 按更新檔顯示每個更新間的差異,比下一條- -stat指令資訊更全
- --stat 顯示每次更新的修改檔案的統計資訊,每個送出都列出了修改過的檔案,以及其中添加和移除的行數,并在最後列出所有增減行數小計
- --pretty=oneline 一行顯示,隻顯示哈希值和送出說明(--online本身也可以作為單獨的屬性)
- -n 顯示前n條log記錄
- --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 checkout da985 hello.py
将送出節點da985中的hello.py複制到工作區和緩存區中,你就可以檢視da985節點的hello.py(如果指令中沒有指定送出節點,則會從暫存區域中拷貝内容。)注意目前分支不會發生變化。
這裡确實會影響你項目的目前狀态。舊的檔案版本會顯示為需要送出的更改,允許你復原到檔案之前的版本。如果你不想保留舊的版本,你可以用下面的指令檢出到最近的版本:
$ git checkout HEAD hello.py
檢出送出
git checkout <commit>
執行後,更新工作目錄中的所有檔案,使得和某個特定送出中的檔案一緻。與此同時,HEAD辨別會移動指定的送出。這被稱為分離HEAD。
分離的頭指針(匿名分支送出) - Detached HEAD
當HEAD處于分離狀态(不依附于任一分支)時,送出操作可以正常進行,但是不會更新任何已命名的分支。(你可以認為這是在更新一個匿名分支。)
一旦此後你切換到别的分支,比如說master,那麼這個送出節點(可能)再也不會被引用到,然後就會被丢棄掉了。注意這個指令之後就不會有東西引用2eecb。
但是,如果你想儲存這個狀态,可以用指令
git checkout -b name
來建立一個新的分支。
2. 重置送出曆史 - git reset
git reset
重設一個舊的送出,你不得不移除那個送出後的所有送出,再移除那個送出,然後重新送出後面的所有送出。不用說,這并不是一個優雅的復原方案。
此外,
git reset
可以通過設定參數有選擇的變動工作區、緩存區和版本倉庫。
- --soft – 緩存區和工作目錄都不會被改變
- --mixed – 預設選項。緩存區和你指定的送出同步,但工作目錄不受影響
- --hard – 緩存區和工作目錄都同步到你指定的送出
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丢失項目曆史,這一點對于你的版本曆史和協作的可靠性來說是很重要的。
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 的選擇