1. 程式人生 > >使用Git,10件你可能需要“反悔”的事

使用Git,10件你可能需要“反悔”的事

DevUI是一支兼具設計視角和工程視角的團隊,服務於華為雲DevCloud平臺和華為內部數箇中後臺系統,服務於設計師和前端工程師。
官方網站:devui.design
Ng元件庫:ng-devui(歡迎Star)
官方交流:新增 DevUI小助手(devui-official)

前言

Git是目前世界上最優秀最流行的分散式版本控制系統,也是程式設計師們日常使用最頻繁的工具之一(幾乎每天都需要使用它來對原始碼進行版本管理)。

使用Git的過程,難免由於手快或者別的什麼原因,需要對做過的事情進行“反悔”或者多次“反悔”。不用擔心,Git強大到幾乎任何操作都是可以“反悔”的,讓我們一起來看看吧。

1.在未暫存前,撤銷本地修改

在介紹Git“反悔”操作之前,先簡單提及下Git的一些基礎知識。

Git專案有3個區域:工作區、暫存區和Git倉庫(分成本地倉庫和遠端倉庫)。如下圖:

本地編寫的程式碼,不執行任何git命令,處於工作區。

執行git add命令時,會將工作區的檔案標記為已暫存,儲存在暫存區。

執行git commit命令時,會將標記為已暫存的檔案儲存都本地Git倉庫,並生成一個快照。

在沒有暫存之前(沒有執行git add命令),我們可以通過以下命令檢視本地修改:

git diff

顯示的格式如下圖所示:

如果我們不想要這些程式碼原生代碼(比如一些臨時的測試程式碼),可以通過以下命令一次性撤銷所有本地修改:

git checkout -- . 
注意:該命令不可二次“反悔”,本地操作一旦撤銷,將無法通過Git找回。

撤銷之後再次執行git diff命令將沒有任何輸出,代表沒有檔案在暫存區。

我們也可以指定具體的檔案路徑,撤銷該檔案的修改:

git checkout -- [filename]

2.在暫存之後,撤銷暫存區的修改

本地寫完程式碼,提交到本地倉庫之前,需要先將修改的檔案新增到暫存區,執行以下命令將本地所有已修改的檔案新增到暫存區(當然也可以指定具體的檔案):

git add .

此時我們執行git diff命令,將不會有任何輸出(因為檔案已被新增到暫存區),想要檢視暫存區的修改,可以執行以下命令:

git diff --staged

看到的效果和之前為暫存前,通過git diff看到的一模一樣。

如果這時我們想要一次性撤銷暫存區的全部修改,可以執行以下命令(當然也可以撤銷暫存區指定檔案的修改):

git reset .

注意:
該命令可以二次“反悔”,通過git add .命令可以將檔案再一次新增到暫存區。
這裡的“撤銷暫存區的修改”是指撤銷git add .這個命令,回到執行git add .之前的狀態,即已修改未暫存狀態。
此時,如果執行git diff --staged命令,將沒有任何輸出,執行git diff命名將看到已修改未暫存狀態的輸出。

1和2的兩個命令可以合併成一個:

git reset --hard


<=>


git reset .
git checkout -- 

即:如果已暫存,但未提交本地倉庫之前,想把所有檔案直接拋棄(而不是從暫存區刪除),可以直接執行以上命令。

3.提交到本地倉庫之後(但未推送到遠端倉庫),撤銷本次提交

執行以下命令,可以將暫存區的所有檔案儲存到本地Git倉庫,並生成檔案快照(便於之前的回退等操作):

git commit -m "modify some files"

此時提交歷史裡面會有一條記錄f8651ff(Commit ID):

如果我們不想要這次修改的內容,有以下2種方法:

方法一

回到當前提交的父物件a18c6fa(即上一次提交,通過git log檢視),就等於撤銷了本次提交:

git checkout a18c6fa

執行git log命令,發現已經回到之前的提交:

方法二

重置之前的提交

git reset --hard HEAD~1

效果和方法一一樣:

注意:該命令是可以二次“反悔”的,具體步驟如下:

1.找到被重置的提交 git reflog,發現是 f8651ff
2.使用reset回到該提交 git reset --hard f8651ff

4.修改提交

考慮以下場景:

原本打算修改兩個檔案,結果只提交了一個檔案,但又不想生成兩個提交記錄(Commit ID),具體執行的命令如下:

git add src/app/app.component.html
git commit -m "add test block"
git log

這樣其實只提交了app.component.html一個檔案,不是我們想要的。

可以通過以下命令“反悔”(新增遺漏檔案,又不重新生成新的Commit ID):

git add src/app/app.component.css
git commit --amend

還有一種場景可能更加常見,沒有遺漏的檔案,只是提交資訊裡有一個單詞寫錯了,可以使用以下命令進行修補:

git commit --amend -m "add test container"
注意:--amend修補引數會將改變之前的Commit ID,但不會生成新的Commit ID。

5.撤銷提交歷史中的某一次指定的提交

第3小結提到回退最近一次提交的方法(使用git reset命令),該方法只能針對連續的提交,如果只想撤銷提交歷史中的某一次提交(比如:),該怎麼辦呢?

比如:Commit ID為711bb0b的提交,該次提交將<a>標籤的target屬性由"_blank"改成了"_self"。

可以使用以下命令撤銷該次提交(將提交的內容“反操作”),並生成一個新的提交在最前面:

git revert 711bb0b

revert之後,會在提交歷史的最前面生成一個新的Commit ID(1f49a42),該次提交將<a>標籤的target屬性由"_self"改回了"_blank"。

6.合併出現衝突時,撤銷合併操作

兩個分支改了同一個檔案的同一個地方,合併時將出現衝突:

如果不想解決衝突,想撤銷這個合併,可以使用以下命令:

git merge --abort

abort之後,將恢復合併之前的狀態。

7.暫存區的檔案加多了,想移除,又不想刪掉本地的檔案

git rm --cached src/test.pptx

8.分支重新命名

git br -m [old_br] [new_br]

9.撤銷變基操作

將 rebase_test 分支的修改變基到master上:

git co rebase_test
git rebase master

撤銷的步驟如下:

1.使用 git reflog 命令找到變基前的提交 09b0adc
2.使用 git reset --hard 09b0adc 重置到該提交

10.以指令碼方式改寫提交

考慮以下場景,在一次很早的提交中,將一個儲存密碼的檔案passwords.txt提交到了遠端倉庫,這時如果只是從遠端倉庫中刪除該檔案,別人依然可以通過提交歷史找到這個檔案。

因此我們需要從每一個快照中移除該密碼檔案,用以下命令就可以做到:

git filter-branch --tree-filter 'rm -f passwords.txt' HEAD

該命令執行完會將提交歷史中所有提交的passwords.txt檔案徹底刪除,永遠沒法通過Git找回。

 

除了以上“反悔”操作,還有一個很強大的命令,也可以以某種形式對過去做過的事情進行“反悔”,那就是互動式變基:

git rebase -i

該命令非常強大,DevUI團隊的少東之前專門寫過一篇來介紹該命令,歡迎大家移步閱讀:

關於Git rebase你必須要知道的幾件事

 

如果發現文中有錯誤或者遺漏的地方,歡迎大家指正!

 

加入我們

我們是DevUI團隊,歡迎來這裡和我們一起打造優雅高效的人機設計/研發體系。招聘郵箱:[email protected]

文/DevUI Kagol

 

往期文章推薦

《手把手教你使用Vue/React/Angular三大框架開發Pagination分頁元件》

《現代富文字編輯器Quill的內容渲染機制》

《現代富文字編輯器Quill的模組化機制》

&n