前置條件:
在正式開始之前,我們需要先確定幾個概念。下面所提到的 master
分支預設為程式碼提交的主分支。
本地分支和遠端分支
本地分支是指我們在日常開發中自己通過 git checkout branch xxx
建立的分支,遠端分支是我們經過 git push -u origin xxxx
推到 git 伺服器的分支,在我們推送之後,git 會幫我們在本地建立一個以 orgin/
開頭的分支,這個我們也叫遠端分支,我們日常操作的就是本地分支 xxx
和遠端分支 origin/xxx
,origin/xxx
就是遠端的 git 伺服器在我們本地建立的一個分支的對照版本(我覺得這樣說應該比較容易理解),我們日常的 git fetch --all
就是將本地的 origin/xxx
與 git 伺服器的 origin/xxx
分支進行同步。
commit id
我們每次提交程式碼都會根據本次提交的內容生成一個幾乎唯一的 id ,這個 id 重複的概率幾乎為 0,我們可以這樣理解,我們每次的提交都會生成一個唯一索引的記錄,不管是本地的 git,還是遠端的 git ,我們都將她理解為一個資料庫,只要我們進行了 commit 操作,那麼可以幾乎確定,我們的程式碼是不會丟失的,我們都可以通過 commit id 找到那條提交記錄的內容。
本篇文章不會講解,分支與分支之間的版本比較等內容,作者比較菜,怕掌握不好度翻車。
使用指南
建立分支
建立分支我們可以使用 git checkout branch xxx
來建立一個新分支,這個很容易理解,但是如果我們現在在分支 branch-1,但是我們想新建一個基於遠端 master 最新版本的分支,我們該怎麼辦呢,不能說現在我回到 master,然後 git pull
拉取最新的 master 分支程式碼,然後建立分支,很繁瑣對不對,這裡我們就可以進行裡一個操作了:git fetch --all
記得我們上面提到的吧,同步遠端分支程式碼, --all
可以改成 origin/master
,然後進行 git checkout branch xxx origin/master
後面的 origin/master
代表我們是基於遠端分支 origin/master
進行建立的。
追加提交記錄
比如我現在已經在本地 commit
一次了,但是發現還有東西忘改了,如果我在 commit 一次就會生成兩條記錄,這樣從提交記錄上看可能不太好看,然後我們就可以使用 git commit --amend
對上一次的提交記錄進行追加,這個操作的前提是上一次提交必需沒有推送到遠端分支,否則,你會發現操作之後在進行 git push
會提示你版本不一致不允許提交,當然如果你可以保證提交沒有錯誤,且這一個分支只有你自己一個人玩,那你就可以使用 git push -f
進行強制提交了,這個操作很危險,謹慎使用。
merge 還是 rebase
我比較喜歡 rebase
操作,所以在這裡就只會講解 rebase
操作了。rebase
的使用場景。
- 使用場景 1:比如現在你在
branch-a
分支工作,但是這個任務有點困難,你已經在這個分支工作很長時間了,很長時間都沒有同步 master 分支的程式碼了,然後同組的小夥伴合併了一個新功能這個功能你需要使用,這個時候你就可以在當前分支使用git rebase origin/master
了,這個操作會將你在這個分支的提交附加於最新的 master 分支版本之後,很明顯這個操作之後你當前本地的branch-a
和遠端的origin/branch-a
已經不一樣了,所以有一個缺點就是你只能選擇git push -f
進行提交。 - 使用場景 2:你同組的小夥伴修改了你在
branch-a
分支也修改過的程式碼,並且你的小夥伴已經提交了,這個時候,你的branch-a
分支就會和origin/master
分支有衝突,嗯,這個時候你也可以使用git rebase origin/master
這個操作來解決衝突,並同步最新的master
的程式碼。 - 使用場景 3:你和小夥伴共同在
branch-a
分支提交程式碼,結果小夥伴比你先提交了,這個時候你再提交會發現版本不一致無法提交,這個時候我們就推薦使用git pull --rebase
,其實git pull
命令後面是有一個預設引數的那就是--merge
,會給我們剛接觸 git 的同學造成很多麻煩。所以在這git pull --rebase
是一個不錯的選擇。
rebase
的另外一個騷操作:合併 commit
git rebase -i HEAD~X
x 代表從當前的提交記錄往回回溯的提交記錄的個數,執行這個操作之後我們就可以看到一個這樣的互動介面:
git log
就可以看到一個新的提交記錄:
git cherry-pick
我們可能會有這樣一個使用場景,在分支 branch-a
需要分支 branch-b
的某次提交,這個時候我們就可以先找到 branch-b
的那次提交記錄的 id,然後在 branch-a
分支進行 git cherry-pick b-commit-id
將 branch-b
分支的提交記錄拿過來了
那如果我們只需要 branch-b
分支的某個檔案呢該怎麼辦呢,莫慌再交你一個操作,git checkout xxx file
這個操作可以將其他分支的檔案拉取到當前分支,注意這個操作是覆蓋式的,也就是如果你這個分支的這個檔案已將存在,那麼這個操作將會覆蓋你當前分支的這個檔案。可以發揮一下 xxx
也可以是遠端分支。
git checkout branch -- file
那麼這個操作又是幹嘛的呢,這個操作可以將你的某個檔案還原到某個分支的版本。如果某次你手誤提交了錯誤的檔案,但是改動又忘了,那麼這個命令或許可以幫到你。
git prune
根據官方的解釋,直白一點的翻譯就是刪除 git
資料庫中不可訪問的物件,那我的理解是這樣的,git prune
刪除的是你本地 .git 下的 object 目錄下,沒有被使用到的 hash 值,我理解的是它會刪除 origin/xx
開頭的沒有用到的分支,這個分支在你的遠端的 git 伺服器中已經刪除但是本地任然存在 origin/xxx
的對映,這個時候你就可以使用 git prune
來刪除本地的 origin/xxx
的對映,但是官方推薦使用的是 git gc
,而想刪除本地的 xxx
分支,就只能只用 git branch -D XXX
,在這附上一條我們部門自己寫的一個清除本地無用分支的 shell git fetch --all --prune && git branch -vv | grep gone | awk '{ print $1 }' | grep -v pit | xargs git branch -D
。
git stash
git stash
可以幫助我們來暫存一些更改,我推薦的是如果只是少部分的更改,使用 stash
是可以的,多了的話,推薦新建分支來儲存更改,以免自己忘記了哪個 stash
。那我們該如何取出這些更改呢,最常用的就是 git stash pop
它會將你最新一次的 stash 從一個快取陣列裡面推出來,這樣的話如果我們操作不當很可能就丟失了這些更改。我推薦的是使用 git stash apply
,這個會將你最新一次的 stash 從快取陣列裡面 copy
一個副本返還給你,缺點就是,你本地的 stash 陣列會越來越大,當然,你可以定時清空一下。還有一個場景,如果我想取出指定的 stash 該怎麼辦呢,在這我們可以使用 git stash list
來檢視一下自己本地的 stash 記錄的形式:
git stash pop/apply stashid
來取出指定的 stash。
後記
目前覺得這些在日常工作中使用的比較多,還有一個 patch 沒說,因為用得比較少,如果再想到其他的內容我會在這篇文章上進行修改。如果本文有錯誤的地方還請大家可以指正,謝謝。