git幾個常用命令介紹(專案相關+內部分享)
楔子
本文的有些git命令是基於我本地的git alias,如下做下解釋:
[alias] co = checkout st = status ci = commit br = branch
專案背景
開發專案特別是團隊協作的專案,每個專案組的人都會在本地建自己的專案分支,同時遠端會有自己的repository,功能需求程式碼完成後會先把程式碼push到遠端自己的相應的分支下,然後手動提交PR合到專案主線上來。
正常的程式碼提交流程
1. 基於zaihui/dev在本地新建一個branch,假如分支名叫做my_branch:
git fetch zaihui
git co -b my_branch zaihui/dev
2. 本地分支my_branch開發,開發完成後提交程式碼:
git st
git diff
git add .
git ci -m <commit_desc>/ git ci —amend
git fetch zaihui
git rebase zaihui/dev
git push origin my_branch [-f]
3. 手動提交PR,將origin/my_branch合進zaihui/dev
其中,git add .和git ci -m <cm_desc>可以合併成git ci -am <cm_desc>
分支管理
git br
git br -v
git br —merged
git br -d/D <branch_name>
git br -M <old_branch_name> <new_branch_name>
拉取程式碼
儘量用git fetch + git merge
少用git pull——— 相當於先fetch再merge
變基 vs 合併
git rebase
git merge
變基使得提交歷史更加整潔。 你在檢視一個經過變基的分支的歷史記錄時會發現,儘管實際的開發工作是並行的,但它們看上去就像是序列的一樣,提交歷史是一條直線沒有分叉。
無論是通過變基,還是通過三方合併,整合的最終結果所指向的快照始終是一樣的,只不過提交歷史不同罷了。 變基是將一系列提交按照原有次序依次應用到另一分支上,而合併是把最終結果合在一起。
總的原則是,只對尚未推送或分享給別人的本地修改執行變基操作清理歷史,從不對已推送至別處的提交執行變基操作
git stash/git stash apply stash@{index}
git stash / git stash apply stash@{index}這組命令可以使我們暫時儲存當前的修改,並在之後的某個時間將程式碼恢復。它的用途非常廣泛,而且對於提高我們的工作效率非常有幫助。它常常用於這樣一種場景,當我們在一個分支上工作時修改了很多程式碼,但是任務還沒完成,還沒有到能夠提交程式碼的程度,這時測試人員發現了一個非常嚴重的bug,需要我們緊急修復,這時我們怎麼做呢?首先要做的就是先執行git stash命令將這些修改暫存,然後我們切換到master命令上去建立一個新的針對這個bug修復的分支,並在這個新的分支上工作。當我們完成修復工作後,我們切換回到之前的分支上,通過命令git stash stash@{index}將之前暫存的改動提取出來,繼續我們的工作。
git cherry-pick <commit_id>
git cherry-pick <commit ID>這條命令非常有意思,它使我們可以在工作樹上隨意摘取一個或者一組commit到當前的分支。這些commit可以是不同的branch上的。這條命令的好處在於,當我們在一個分支上面進行了程式碼修改並提交後,有其他的分支也同樣需要這些程式碼的時候,可以通過git cherry-pick <commit ID>命令將想要的commit摘取到當前的分支上,並自動提交到本地倉庫。它常常用於這樣的一種場景:我們新建立了一個分支用於新的版本1.0的release,同時我們也維護著master分支的代。當我們在master上面發現了bug並將其修復後,我們同樣也需要在1.0的分支上將這些修改拿過來,此時git cherry-pick <commit ID>就可以派上用場了,它將這些修改的commit從master分支上摘取過來,並自動提交到當前的分支。
git pull —rebase/git rebase —continue
這組命令主要用於從遠端程式碼庫拉取程式碼到本地,主要針對在一個相同分支上的程式碼操作(比如master分支)。試想一下,當我們有多個人都在同一個分割槽上面進行程式碼操作時,這時候我們拉取程式碼時會有多少衝突,場面會有多麼混亂。如果我們使用git pull或者git fetch從遠端拉取程式碼,那麼我們在提交自己新的程式碼時就會使得整個工作樹變得非常凌亂。git pull --rebase / git rebase --continue可以很好的解決這些問題。首先我們將我們改動的程式碼提交到本地倉庫,然後利用git pull --rebase命令將遠端倉庫的程式碼拉取到本地,它將其獲取的所有的commit放在我們新提交的commit的底部,這步完成後可能會有衝突,等我們將衝突解決完成後,再利用git rebase --continue命令將解決衝突後的程式碼提交到之前提交的程式碼中去。通過這兩步之後,我們整個的工作樹始終會保持在一條直線上,而不會出現程式碼的merge分支的情況。
git rebase -i/git rebase —continue
與多人同時工作在一個相同的分支上相比,我們一般真對每個task都會新建一個對應的branch,每個人僅僅工作在自己的分支上,沒有人會工作在master上,當工作完成後才會將程式碼提交到master上去。這樣做的好處顯而易見,它使得我們無須同時操作相同的分支,尤其是master的分支,從而保證了master分支的整潔與安全。那麼這樣做的一個關鍵在於我們在自己的分支上如何與master分支保持一致性。實踐中,我們不應在工作切底完成之後,再與master分支同步程式碼,實踐證明,這樣會導致大量的衝突,我們應該做的是工作的每天都應該與master同步一次程式碼,這裡僅僅是從master同步新的程式碼,而不應將自己的程式碼提交到master分支。git rebase -i master這條命令就是我們最好的工具。它不僅可以讓我們當前的分支從master同步最新的程式碼,而且還可以將我們分支上的多個commit合併成為一個,可以讓branch更簡潔,畢竟branch上的程式碼都是為了實現一個功能。如果同步時有衝突,我們解決完衝突後,使用git rebase --continue將程式碼提交到先前的commit中去。有了這兩條命令,我們在不同分支上的工作就會變得簡單輕鬆。