已經會用Git了?不會這十招怎麼行

edithfang發表於2014-11-21


注意:這裡介紹的命令中有的包含方括號(例如:gitadd -p [file_name])。在這些例子中,你應該用你自己的數字、識別符號等替代方括號裡的內容,並且去掉方括號。

1. Git自動補全

如果你在命令列環境中執行Git命令,每次都手動地逐個輸入命令是一件很無聊的事。為此,你可以花幾分鐘時間配置一下Git命令的自動補全功能。

在*nix系統執行下列命令下載自動補全指令碼:

cd ~
curl https://raw.github.com/git/git/master/contrib/completion/git-completion.bash -o ~/.git-completion.bash

然後,新增下面的行到你的~/.bash_profile檔案:

if [ -f ~/.git-completion.bash ]; then
. ~/.git-completion.bash
fi

儘管我之前已經提到過,但我還是想再強調一下:如果你想使用完整的Git特性,你絕bi應該切換到命令列環境。

2. 在Git中忽略檔案

你是不是對出現在你Git庫裡面的編譯生成檔案(比如.pyc)感到很無語?或者你是不是很厭惡不小心將他們新增到了Git?直接看這裡,這裡有一個方法可以讓你告訴Git忽略所有這些檔案和目錄。只需要建立一個名字為.gitignore的檔案,裡面列出你不想要Git跟蹤的檔案和目錄。可以用感嘆號(!)列出例外情況。

*.pyc
*.exe
my_db_config/
!main.pyc

3. 誰動了我的程式碼?

當事情出了亂子時立馬責怪別人這是人類的天性。如果你的伺服器程式不能正常工作了,要找出罪魁禍首是非常簡單的--只需要執行gitblame。這個命令告訴你檔案裡的每一行的作者是誰,最後改動那一行的提交,以及提交的時間戳。

git blame [file_name]

在下面的截圖裡,你可以看到在一個更大的庫裡這個命令的輸出是什麼樣的:


4. 檢視庫的歷史

在之前的教程裡,我們已經看過了如何使用git log命令。不管怎樣,有3個選項你應該知道。

  • --oneline -壓縮每次的提交資訊,只保留一個縮減的Hash值和說明文字,然後把這些都展示在一行裡。
  • --graph -這個選項將在左邊畫出一個文字介面的提交歷史圖。如果你只有一個分支,用這個選項檢視歷史時是沒什麼意義的。
  • --all - 顯示所有分支歷史。


這是這3個選項合起來使用的效果:


5. 不要丟失對某個提交的跟蹤

假設你提交了一些不需要的東西,然後你進行了hard重置回到之前的狀態。後來,你發現在這個過程中你丟失了其他一些重要的資訊,你想要把這些資訊找回來,或者至少可以檢視一下這些資訊。這就需要gitreflog幫忙。

簡單的git log只能告訴你最近的提交,這個提交的父提交,父提交的父提交,等等。但是gitreflog是一個HEAD指向的提交的列表。記住,這個列表依賴於你自己的本地操作環境,它不是庫的一部分,也不包含在push或者merge中。

如果執行git log命令,可以看到提交歷史,這是我的庫的一部分:



但是,git reflog命令顯示了一個被我用hard重置丟掉的提交(b1b0ee9-HEAD@{4}).


6. 暫存檔案的一部分更改以便進行一次提交

通常依據特性來提交是一個好的實踐方法,意思是說,每一個提交都只新增一個特性或者修復一個bug。想一下如果你一次修復了兩個bug或者新增了兩個特性但是都還沒有逐個提交該怎麼辦。這種場景下,你可以將他們一起提交。但是有一個更好的辦法:單獨暫存這些檔案,然後分開提交。

讓我們假設你對一個檔案做了多個更改,然後想讓這些更改分開提交。這時,我們用帶-p的新增命令。

git add -p [file_name]

我們來試試這種用法。我新增了3個新行到file_name,但是我只想讓第1行和第3行出現在我的提交裡。讓我們看看git diff的輸出是什麼樣的。



然後,我們看看帶-p選項的add命令會發生什麼。



看起來Git認為所有的更改都是同一個目的的一部分,所以把他們分組到同一個塊裡。這時,你可以:

  • 輸入 y 暫存塊
  • 輸入 n 不暫存塊
  • 輸入 e 手動編輯塊
  • 輸入 d 退出或者跳轉到下一個檔案
  • 輸入 s 分割塊

在我們這個例子中,我們想把這個塊分割成更小的部分,然後選擇其中一些忽略另外一些。



如你所見,我們已經逐個新增了第1和第3行,忽略了第2行。你可以看到庫的狀態並且進行一次提交。


7. 合併多個提交

為了進行核查或者發起一個合併請求(這經常發生在開源專案裡),對程式碼進行了修改提交。但在最後程式碼被接受之前,你也許會需要修改你的程式碼。於是你修改程式碼,但是下一次核查的時候又一次需要進行修改。不知不覺中,你就已經有了好幾個提交。理論上你應該用rebase命令把他們合併起來。

git rebase -i HEAD~[number_of_commits]

如果你想合併最後的兩次提交,你應該執行下面的命令。

git rebase -i HEAD~2

一旦你執行這個命令,你將進入一個互動式介面,它將詢問你想要合併哪些提交。你pick(揀選)最近的提交然後squash(合併)舊的提交。



接著你應該提供一個對新提交的說明。這個過程會重寫你的提交歷史。


8. 儲藏沒有提交的更改

假設你正在修復一個bug或者新增一個特性,突然你被要求展示一下你的工作成果。你現在的工作還沒有完成,不夠進行一次提交。這時,gitstash命令可以用來急救一下。Stash命令跟蹤你所有的更改,然後把他們儲藏起來以便以後使用。命令如下-

git stash

可以多次儲藏更改,檢視儲藏列表,你可以執行下面的命令:

git stash list

如果你想取消儲藏,覆蓋當前的更改,你可以通過下面的命令使用儲藏:

git stash apply

在最後的這個截圖裡,你可以看到每個儲藏都有一個識別符號,是一個唯一的數字(儘管在這裡我們只有一個儲藏)。如果你想使用某個儲藏,你在apply命令後面加上這個唯一的識別符號:

git stash apply stash@{2}

9. 檢查丟失的提交

儘管reflog是一種檢查丟失提交的方法,大型的庫裡卻不太實用。這個時候,應該用fsck(檔案系統檢查)命令。

git fsck --lost-found



這裡你可以看到一個丟失的提交。你可以通過git show [commit_hash] 檢視提交的更改或者通過執行git merge[commit_hash]命令進行恢復。

gitfsck跟reflog命令相比有一個優點。假設你刪除了一個遠端分支,然後clone了這個庫。用fsck命令你可以找到並且恢復這個刪除的遠端分支。

10. 最佳選擇

之前我已經存記下了那些最優雅的Git命令。但是目前為止,cherry-pick命令是我最喜歡的Git命令,因為它直白的名字和實用的功能!

最簡單的情況下,cherry-pick從另一個分支裡選出單獨的一個提交,然後合併到當前分支。如果你正並行工作在兩個或者更多的分支上,你也許會發現一個存在於所有分支上的bug。如果你解決了一個分支上的這個bug,你可以揀選這個對應的提交應用到其他分支上,而不會弄亂其他檔案或者提交。

讓我們來考慮一個可以使用這個命令的場景。我有兩個分支,我想揀選b20fd14: Cleaned junk這個提交到另一個分支上。



我切換到想要應用這個揀選出來的提交的分支,然後執行下面的命令:

git cherry-pick [commit_hash]



儘管這次我們很乾淨的用了cherry-pick命令,但你應該知道這個命令經常會引起衝突,所以請小心使用。

總結

到了這裡,我們結束了這個能使你Git能力提升一個級別的列表。Git是最好的版本控制器,它能完成你能想象到的任何事情。所以,經常試著用Git挑戰你自己。一不小心你就會學到很多新東西。
相關閱讀
評論(1)

相關文章