文章目錄
-
- 1. 取得項目的Git倉庫
-
- 1.1 在工作目錄中初始化新倉庫
- 1.2 從現有倉庫克隆
- 2. 記錄每次更新
-
- 2.1 檢查目前檔案狀态
- 2.2 跟蹤新檔案
- 2.3 暫存已修改檔案
- 2.4 檢視已暫存和未暫存的更新
- 2.5 送出更新
- 3. 移除檔案
- 4. 檔案改名
- 5. 忽略某些檔案(.gitignore)
- 6.檢視送出曆史
- 7. 撤銷操作
-
- 7.1 修改最後一次送出
- 7.2 取消已經暫存的檔案
- 7.3 取消對檔案的修改
- 8.版本回退
1. 取得項目的Git倉庫
有兩種取得 Git 項目倉庫的方法。第一種是在現存的目錄下,通過導入所有檔案來建立新的 Git 倉庫。第二種是從已有的 Git 倉庫克隆出一個新的鏡像倉庫來。
1.1 在工作目錄中初始化新倉庫
要對現有的某個項目開始用 Git 管理,隻需到此項目所在的目錄,執行:
$ git init
初始化後,在目前目錄下會出現一個名為 .git 的目錄,所有 Git 需要的資料和資源都存放在這個目錄中。不過目前還沒有開始跟蹤管理項目中的任何一個檔案。
也就是說,git init指令隻是讓code_test目錄擁有了版本管理的能力,無論code_test目錄中原來是否存在檔案,".git"目錄都是新建立出來的,從git倉庫的角度來說,這就是一個新的倉庫,還沒有任何檔案被這個倉庫所管理。
需要注意
git init指令是把目前目錄轉化成git repo
git init repo_name 指令是在目前目錄中建立一個以repo_name命名的新目錄,新目錄是一個git repo
如果目前目錄下有幾個檔案想要納入版本控制,需要先用
git add
指令告訴 Git 開始對這些檔案進行跟蹤,然後送出:
$ git add *.c
$ git add README
$ git commit -m 'initial project version'
1.2 從現有倉庫克隆
如果想對某個開源項目出一份力,可以先把該項目的 Git 倉庫複制一份出來,這就需要用到
git clone
指令。
克隆倉庫的指令格式為
git clone [url]
。比如,要克隆 Ruby 語言的 Git 代碼倉庫 Grit,可以用下面的指令:
$ git clone git://github.com/schacon/grit.git
這會在目前目錄下建立一個名為
grit
的目錄,其中包含一個
.git
的目錄,用于儲存下載下傳下來的所有版本記錄,然後從中取出最新版本的檔案拷貝。如果進入這個建立的
grit
目錄,你會看到項目中的所有檔案已經在裡邊了,準備好後續的開發和使用。如果希望在克隆的時候,自己定義要建立的項目目錄名稱,可以在上面的指令末尾指定新的名字:
$ git clone git://github.com/schacon/grit.git mygrit
唯一的差别就是,現在建立的目錄成了
mygrit
,其他的都和上邊的一樣。
Git 支援許多資料傳輸協定。之前的例子使用的是
git://
協定,不過你也可以用
http(s)://
或者
[email protected]:/path.git
表示的 SSH 傳輸協定。
2. 記錄每次更新
請記住,工作目錄下面的所有檔案都不外乎這兩種狀态:已跟蹤或未跟蹤。已跟蹤的檔案是指本來就被納入版本控制管理的檔案,在上次快照中有它們的記錄,工作一段時間後,它們的狀态可能是未更新,已修改或者已放入暫存區。而所有其他檔案都屬于未跟蹤檔案。它們既沒有上次更新時的快照,也不在目前的暫存區域。初次克隆某個倉庫時,工作目錄中的所有檔案都屬于已跟蹤檔案,且狀态為未修改。
在編輯過某些檔案之後,Git 将這些檔案标為已修改。我們逐漸把這些修改過的檔案放到暫存區域,直到最後一次性送出所有這些暫存起來的檔案,如此重複。
2.1 檢查目前檔案狀态
要确定哪些檔案目前處于什麼狀态,可以用
git status
指令。如果在克隆倉庫之後立即執行此指令,會看到類似這樣的輸出:
$ git status
On branch master
nothing to commit, working directory clean
這說明你現在的工作目錄相當幹淨。換句話說,所有已跟蹤檔案在上次送出後都未被更改過。此外,上面的資訊還表明,目前目錄下沒有出現任何處于未跟蹤的新檔案,否則 Git 會在這裡列出來。最後,該指令還顯示了目前所在的分支是
master
,這是預設的分支名稱。
現在讓我們用 vim 建立一個新檔案 README,儲存退出後運作
git status
會看到該檔案出現在未跟蹤檔案清單中:
$ vim README
$ git status
On branch 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”**下面。未跟蹤的檔案意味着Git在之前的快照(送出)中沒有這些檔案;Git 不會自動将之納入跟蹤範圍,除非你明明白白地告訴它“我需要跟蹤該檔案”,因而不用擔心把臨時檔案什麼的也歸入版本管理。不過現在的例子中,我們确實想要跟蹤管理 README 這個檔案。
2.2 跟蹤新檔案
使用指令
git add
開始跟蹤一個新檔案。是以,要跟蹤 README 檔案,運作:
$ git add README
此時再運作
git status
指令,會看到 README 檔案已被跟蹤,并處于暫存狀态:
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: README
隻要在 “Changes to be committed” 這行下面的,就說明是已暫存狀态。如果此時送出,那麼該檔案此時此刻的版本将被留存在曆史記錄中。
2.3 暫存已修改檔案
現在我們修改下之前已跟蹤過的檔案
benchmarks.rb
,然後再次運作
status
指令,會看到這樣的狀态報告:
$ git status
On branch 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: benchmarks.rb
檔案
benchmarks.rb
出現在 **“Changes not staged for commit” **這行下面,說明已跟蹤檔案的内容發生了變化,但還沒有放到暫存區。要暫存這次更新,需要運作
git add
指令。
很多時候可以通過git status下的提示來進行下一步操作。
現在讓我們運作
git add
将 benchmarks.rb 放到暫存區,然後再看看
git status
的輸出:
$ git add benchmarks.rb
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: README
modified: benchmarks.rb
現在兩個檔案都已暫存,下次送出時就會一并記錄到倉庫。假設此時,你想要在
benchmarks.rb
裡再加條注釋,重新編輯存盤後,準備好送出。不過且慢,再運作
git status
看看:
$ vim benchmarks.rb
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: README
modified: benchmarks.rb
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: benchmarks.rb
怎麼回事?
benchmarks.rb
檔案出現了兩次!一次算未暫存,一次算已暫存,這怎麼可能呢?好吧,實際上 Git 隻不過暫存了你運作
git add
指令時的版本,如果現在送出,那麼送出的是添加注釋前的版本,而非目前工作目錄中的版本。是以,運作了
git add
之後又作了修訂的檔案,需要重新運作
git add
把最新版本重新暫存起來:
$ git add benchmarks.rb
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: README
modified: benchmarks.rb
2.4 檢視已暫存和未暫存的更新
實際上
git status
的顯示比較簡單,僅僅是列出了修改過的檔案,如果要檢視具體修改了什麼地方,可以用
git diff
指令。
假如再次修改
README
檔案後暫存,然後編輯
benchmarks.rb
檔案後先别暫存,運作
status
指令将會看到:
$ git status
On branch 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: benchmarks.rb
要檢視尚未暫存的檔案更新了哪些部分,不加參數直接輸入
git diff
:
$ git diff
diff --git a/benchmarks.rb b/benchmarks.rb
index 3cb747f..da65585 100644
--- a/benchmarks.rb
+++ b/benchmarks.rb
@@ -36,6 +36,10 @@ def main
@commit.parents[0].parents[0].parents[0]
end
+ run_code(x, 'commits 1') do
+ git.commits.size
+ end
+
run_code(x, 'commits 2') do
log = git.commits('master', 15)
log.size
若要看已經暫存起來的檔案和上次送出時的快照之間的差異,可以用
git diff --cached
指令。(Git 1.6.1 及更高版本還允許使用
git diff --staged
,效果是相同的,但更好記些。)來看看實際的效果:
$ git diff --cached
diff --git a/README b/README
new file mode 100644
index 0000000..03902a1
--- /dev/null
+++ b/README2
@@ -0,0 +1,5 @@
+grit
+ by Tom Preston-Werner, Chris Wanstrath
+ http://github.com/mojombo/grit
+
+Grit is a Ruby library for extracting information from a Git repository
請注意,單單
git diff
不過是顯示還沒有暫存起來的改動,而不是這次工作和上次送出之間的差異。
2.5 送出更新
現在的暫存區域已經準備妥當可以送出了。在此之前,請一定要确認還有什麼修改過的或建立的檔案還沒有
git add
過,否則送出的時候不會記錄這些還沒暫存起來的變化。是以,每次準備送出前,先用
git status
看下,是不是都已暫存起來了,然後再運作送出指令
git commit
:
$ git commit
這種方式會啟動文本編輯器以便輸入本次送出的說明。(預設會啟用 shell 的環境變量
$EDITOR
所指定的軟體,一般都是 vim 或 emacs。當然也可以按照第一章介紹的方式,使用
git config --global core.editor
指令設定你喜歡的編輯軟體。)
編輯器會顯示類似下面的文本資訊(本例選用 Vim 的屏顯方式展示):
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
# new file: README
# modified: benchmarks.rb
#
~
~
~
".git/COMMIT_EDITMSG" 10L, 283C
可以看到,預設的送出消息包含最後一次運作
git status
的輸出,放在注釋行裡,另外開頭還有一空行,供你輸入送出說明。你完全可以去掉這些注釋行,不過留着也沒關系,多少能幫你回想起這次更新的内容有哪些。(如果覺得這還不夠,可以用
-v
選項将修改差異的每一行都包含到注釋中來。)退出編輯器時,Git 會丢掉注釋行,将說明内容和本次更新送出到倉庫。
另外也可以用 -m 參數後跟送出說明的方式,在一行指令中送出更新:
$ git commit -m "Story 182: Fix benchmarks for speed"
[master 463dc4f] Story 182: Fix benchmarks for speed
2 files changed, 3 insertions(+)
create mode 100644 README
好,現在你已經建立了第一個送出!可以看到,送出後它會告訴你,目前是在哪個分支(master)送出的,本次送出的完整 SHA-1 校驗和是什麼(
463dc4f
),以及在本次送出中,有多少檔案修訂過,多少行添改和删改過。
記住,送出時記錄的是放在暫存區域的快照,任何還未暫存的仍然保持已修改狀态,可以在下次送出時納入版本管理。每一次運作送出操作,都是對你項目作一次快照,以後可以回到這個狀态,或者進行比較。
3. 移除檔案
要從 Git 中移除某個檔案,就必須要從已跟蹤檔案清單中移除(确切地說,是從暫存區域移除),然後送出。可以用
git rm
指令完成此項工作,并連帶從工作目錄中删除指定的檔案。
如果隻是簡單地從工作目錄中手工删除檔案,運作
git status
時就會在 “Changes not staged for commit” 部分(也就是未暫存清單)看到:
$ rm grit.gemspec
$ git status
On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: grit.gemspec
no changes added to commit (use "git add" and/or "git commit -a")
然後再運作
git rm
記錄此次移除檔案的操作:
$ git rm grit.gemspec
rm 'grit.gemspec'
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
deleted: grit.gemspec
4. 檔案改名
既然如此,當你看到 Git 的
mv
指令時一定會困惑不已。要在 Git 中對檔案改名,可以這麼做:
$ git mv file_from file_to
它會恰如預期般正常工作。實際上,即便此時檢視狀态資訊,也會明白無誤地看到關于重命名操作的說明:
$ git mv README.txt README
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: README.txt -> README
其實,運作
git mv
就相當于運作了下面三條指令:
$ mv README.txt README
$ git rm README.txt
$ git add README
5. 忽略某些檔案(.gitignore)
一般我們總會有些檔案無需納入 Git 的管理,也不希望它們總出現在未跟蹤檔案清單。通常都是些自動生成的檔案,比如日志檔案,或者編譯過程中建立的臨時檔案等。
不需要從頭寫
.gitignore
檔案,GitHub已經為我們準備了各種配置檔案,隻需要組合一下就可以使用了。所有配置檔案可以直接線上浏覽:https://github.com/github/gitignore
在版本管理的根目錄下(與.Git檔案夾同級)建立一個 .gitignore(沒有檔案名,在Windows下需要編寫完文本文檔後另存為,在win10系統下還是文本文檔,隻不過屬性裡能看到是文本文檔(.gitignore檔案)
檔案
.gitignore
的格式規範如下:
- 所有空行或者以注釋符号
開頭的行都會被 Git 忽略。#
- 可以使用标準的 glob 模式比對。
- 比對模式最後跟反斜杠(
)說明要忽略的是目錄。/
- 要忽略指定模式以外的檔案或目錄,可以在模式前加上驚歎号(
)取反。!
很簡單吧,被過濾掉的檔案就不會出現在你的GitHub庫中了,當然本地庫中還有,隻是push的時候不會上傳。以及未追蹤時,不會顯示出未追蹤狀态。
想象一個場景:我們隻需要管理/mtk/目錄中的one.txt檔案,這個目錄中的其他檔案都不需要管理。那麼我們就需要使用:
- /mtk/
- !/mtk/one.txt
假設我們隻有過濾規則沒有添加規則,那麼我們就需要把/mtk/目錄下除了one.txt以外的所有檔案都寫出來!
删除了.gitignore檔案後
之前的a.c檔案又出現了未追蹤狀态。
有些時候,你想添加一個檔案到Git,但發現添加不了,原因是這個檔案被
.gitignore
忽略了:
$ git add App.class
The following paths are ignored by one of your .gitignore files:
App.class
Use -f if you really want to add them.
如果你确實想添加該檔案,可以用
-f
強制添加到Git:
$ git add -f App.class
或者你發現,可能是
.gitignore
寫得有問題,需要找出來到底哪個規則寫錯了,可以用
git check-ignore
指令檢查:
$ git check-ignore -v App.class
.gitignore:3:*.class App.class
Git會告訴我們,
.gitignore
的第3行規則忽略了該檔案,于是我們就可以知道應該修訂哪個規則。
最後需要強調的一點是,如果你不慎在建立.gitignore檔案之前就push了項目,那麼即使你在.gitignore檔案中寫入新的過濾規則,這些規則也不會起作用,Git仍然會對所有檔案進行版本管理。
簡單來說,出現這種問題的原因就是Git已經開始管理這些檔案了,是以你無法再通過過濾規則過濾它們。
是以大家一定要養成在項目開始就建立.gitignore檔案的習慣,否則一旦push,處理起來會非常麻煩。
.gitignore
檔案本身要放到版本庫裡,并且可以對
.gitignore
做版本管理!
6.檢視送出曆史
在送出了若幹更新之後,又或者克隆了某個項目,想回顧下送出曆史,可以使用
git log
指令檢視。
$ git log
commit 1094adb7b9b3807259d8cb349e7df1d4d6477073 (HEAD -> master)
Author: Michael Liao <[email protected]>
Date: Fri May 18 21:06:15 2018 +0800
append GPL
commit e475afc93c209a690c39c13a46716e8fa000c366
Author: Michael Liao <[email protected]>
Date: Fri May 18 21:03:36 2018 +0800
add distributed
commit eaadf4e385e865d25c48e7ca9c8395c3f7dfaef0
Author: Michael Liao <[email protected]>
Date: Fri May 18 20:59:18 2018 +0800
wrote a readme file
git log
指令顯示從最近到最遠的送出日志,我們可以看到3次送出,最近的一次是
append GPL
,上一次是
add distributed
,最早的一次是
wrote a readme file
。
每次更新都有一個 SHA-1 校驗和、作者的名字和電子郵件位址、送出時間,最後縮進一個段落顯示送出說明。
下面介紹常用的一些選項:
我們常用
-p
選項展開顯示每次送出的内容差異,用
-2
則僅顯示最近的兩次更新
常用的
--pretty
選項,可以指定使用完全不同于預設格式的方式展示送出曆史。比如用
oneline
将每個送出放在一行顯示,這在送出數很大時非常有用。另外還有
short
,
full
和
fuller
可以用,展示的資訊或多或少有些不同
$ git log --pretty=oneline
ca82a6dff817ec66f44342007202690a93763949 changed the version number
085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 removed unnecessary test code
a11bef06a3f659402fe7563abf99ad00de2209e6 first commit
--stat
,僅顯示簡要的增改行數統計
format
,可以定制要顯示的記錄格式,這樣的輸出便于後期程式設計提取分析,像這樣:
$ git log --pretty=format:"%h - %an, %ar : %s"
ca82a6d - Scott Chacon, 11 months ago : changed the version number
085bb3b - Scott Chacon, 11 months ago : removed unnecessary test code
a11bef0 - Scott Chacon, 11 months ago : first commit
用 oneline 或 format 時結合
--graph
選項,可以看到開頭多出一些 ASCII 字元串表示的簡單圖形,形象地展示了每個送出所在的分支及其分化衍合情況。在我們之前提到的 Grit 項目倉庫中可以看到:
$ git log --pretty=format:"%h %s" --graph
* 2d3acf9 ignore errors from SIGCHLD on trap
* 5e3ee11 Merge branch 'master' of git://github.com/dustin/grit
|\
| * 420eac9 Added a method for getting the current branch.
* | 30e367c timeout code and tests
* | 5a09431 add timeout protection to grit
* | e1193f8 support for heads with slashes in them
|/
* d6016bc require time for xmlschema
* 11d191e Merge branch 'defunkt' into local
7. 撤銷操作
7.1 修改最後一次送出
在本地已有的 commit 資訊上再次送出改動,而不是在已有的 commit 上再新增一個 commit。
使用
git commit --amend
指令可以達到在現有最新 commit 上再次送出改動的效果。
有時候我們送出完了才發現漏掉了幾個檔案沒有加,或者送出資訊寫錯了。想要撤消剛才的送出操作,可以使用
--amend
選項重新送出:
$ git commit --amend
此指令将使用目前的暫存區域快照送出。如果剛才送出完沒有作任何改動,直接運作此指令的話,相當于有機會重新編輯送出說明,但将要送出的檔案快照和之前的一樣。
啟動文本編輯器後,會看到上次送出時的說明,編輯它确認沒問題後儲存退出,就會使用新的送出說明覆寫剛才失誤的送出。
如果剛才送出時忘了暫存某些修改,可以先補上暫存操作,然後再運作
--amend
送出:
$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend
上面的三條指令最終隻是産生一個送出,第二個送出指令修正了第一個的送出内容。
7.2 取消已經暫存的檔案
情景:檔案add後想要取消暫存
來看下面的例子,有兩個修改過的檔案,我們想要分開送出,但不小心用
git add .
全加到了暫存區域。該如何撤消暫存其中的一個檔案呢?其實,
git status
的指令輸出已經告訴了我們該怎麼做:
$ git add .
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: README.txt
modified: benchmarks.rb
就在 “Changes to be committed” 下面,括号中有提示,可以使用
git reset HEAD <file>...
的方式取消暫存。好吧,我們來試試取消暫存 benchmarks.rb 檔案:
$ git reset HEAD benchmarks.rb
Unstaged changes after reset:
M benchmarks.rb
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: README.txt
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: benchmarks.rb
現在 benchmarks.rb 檔案又回到了之前已修改未暫存的狀态。把暫存區的修改回退到工作區。
7.3 取消對檔案的修改
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: benchmarks.rb
在第二個括号中,我們看到了抛棄檔案修改的指令,讓我們試試看:
$ git checkout -- benchmarks.rb
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: README.txt
可以看到,該檔案已經恢複到修改前的版本。
指令
git checkout -- readme.txt
意思就是,把
readme.txt
檔案在工作區的修改全部撤銷,這裡有兩種情況:
- 一種是
自修改後還沒有被放到暫存區,現在,撤銷修改就回到和版本庫一模一樣的狀态;readme.txt
- 一種是
已經添加到暫存區後,又作了修改,現在,撤銷修改就回到添加到暫存區後的狀态。readme.txt
總之,就是讓這個檔案回到最近一次
git commit
或
git add
時的狀态。
8.版本回退
在Git中,我們用
git log
指令檢視:
$ git log
commit 1094adb7b9b3807259d8cb349e7df1d4d6477073 (HEAD -> master)
Author: Michael Liao <[email protected]>
Date: Fri May 18 21:06:15 2018 +0800
append GPL
commit e475afc93c209a690c39c13a46716e8fa000c366
Author: Michael Liao <[email protected]>
Date: Fri May 18 21:03:36 2018 +0800
add distributed
commit eaadf4e385e865d25c48e7ca9c8395c3f7dfaef0
Author: Michael Liao <[email protected]>
Date: Fri May 18 20:59:18 2018 +0800
wrote a readme file
一大串類似
1094adb...
的是
commit id
(版本号也稱SHA-1校驗和),和SVN不一樣,Git的
commit id
不是1,2,3……遞增的數字,而是一個SHA1計算出來的一個非常大的數字,用十六進制表示,而且每個人都不一樣,以你自己的為準。(SHA-1校驗和)為什麼
commit id
需要用這麼一大串數字表示呢?因為Git是分布式的版本控制系統,後面我們還要研究多人在同一個版本庫裡工作,如果大家都用1,2,3……作為版本号,那肯定就沖突了。
首先,Git必須知道目前版本是哪個版本,在Git中,用
HEAD
表示目前版本,也就是最新的送出
1094adb...
(注意我的送出ID和你的肯定不一樣),上一個版本就是
HEAD^
,上上一個版本就是
HEAD^^
,當然往上100個版本寫100個
^
比較容易數不過來,是以寫成
HEAD~100
。HEAD^對應 HEAD~1
實際使用指令時,可以指定版本号或者使用HEAD
執行個體:
–hard 參數撤銷工作區中所有未送出的修改内容,将暫存區與工作區都回到上一次版本,并删除之前的所有資訊送出:
現在,我們要把目前版本
append GPL
回退到上一個版本
add distributed
,就可以使用
git reset
指令:
$ git reset --hard HEAD^
HEAD is now at e475afc add distributed
不過且慢,讓我們用
git log
再看看現在版本庫的狀态:
$ git log
commit e475afc93c209a690c39c13a46716e8fa000c366 (HEAD -> master)
Author: Michael Liao <[email protected]>
Date: Fri May 18 21:03:36 2018 +0800
add distributed
commit eaadf4e385e865d25c48e7ca9c8395c3f7dfaef0
Author: Michael Liao <[email protected]>
Date: Fri May 18 20:59:18 2018 +0800
wrote a readme file
最新的那個版本
append GPL
已經看不到了!好比你從21世紀坐時光穿梭機來到了19世紀,想再回去已經回不去了,腫麼辦?
辦法其實還是有的,隻要上面的指令行視窗還沒有被關掉,你就可以順着往上找啊找啊,找到那個
append GPL
的
commit id
是
1094adb...
,于是就可以指定回到未來的某個版本:如果之前指令行視窗被關掉的話,就還有一條指令,那就是"git reflog"指令,用于檢視操作記錄。
$ git reflog
aa81e63 (HEAD -> master) [email protected]{0}: reset: moving to aa81e63
526ff66 [email protected]{1}: commit: 5E
866b6de [email protected]{2}: commit: 4D
aa81e63 (HEAD -> master) [email protected]{3}: commit: 3C
2fc70fe [email protected]{4}: commit: 2B
510658e [email protected]{5}: commit (initial): 1A
版本号沒必要寫全,前幾位就可以了,Git會自動去找。當然也不能隻寫前一兩位,因為Git可能會找到多個版本号,就無法确定是哪一個了。
git reset 分為三種:軟 --soft,中 —mixed,硬 --hard 對應着三種復原的程度,程度越硬,復原的越“狠”
- –soft 已 add,但尚未 commit
- –mixed(git reset 的預設設定,可以省略不寫),檔案會回退到未 add(未暫存)的狀态
- –hard 硬核,徹底,會徹底傳回到回退前的版本狀态,了無痕迹