你需要知道的12個(gè)Git高級(jí)命令
2016-01-29 22:13:10 來(lái)源:張龍 評(píng)論:0 點(diǎn)擊:
眾所周知,Git目前已經(jīng)是分布式版本控制領(lǐng)域的翹楚,圍繞著Git形成了完整的生態(tài)圈。學(xué)習(xí)Git,首先當(dāng)然是學(xué)習(xí)Git的基本工作流。相比于SVN等傳統(tǒng)版本控制系統(tǒng)來(lái)說(shuō),Git是專(zhuān)為分布式版本控制而生的強(qiáng)大工具。使用Git時(shí)常用的命令有pull、commit、push等,貌似很簡(jiǎn)單。不過(guò),有時(shí)你會(huì)遇到合并沖突的情況,Git這時(shí)會(huì)將沖突標(biāo)記出來(lái),需要你手工來(lái)解決。有時(shí),你會(huì)不小心將代碼提交到錯(cuò)誤的分支上,并且又推送到了遠(yuǎn)程倉(cāng)庫(kù)。還有些時(shí)候,你需要切換到不同的分支,但Git卻不讓你這么做,因?yàn)檫€有未保存的修改。如果需要通過(guò)另一個(gè)分支的提交來(lái)為代碼打補(bǔ)丁該怎么做呢?本文就將介紹12個(gè)Git高級(jí)命令,合理使用這些命令可以大大提升應(yīng)用Git的效率。
1. 使用rebase而非merge來(lái)拉取上游修改
分支合并會(huì)被記錄為一次合并提交,這種做法是很有意義的。比如說(shuō),可以通過(guò)這種方式來(lái)標(biāo)識(shí)一個(gè)新特性被合并到了發(fā)布分支中。不過(guò),當(dāng)多個(gè)團(tuán)隊(duì)成員工作在一個(gè)項(xiàng)目中并使用常規(guī)的git pull來(lái)同步分支時(shí),提交時(shí)間線就會(huì)被不必要的合并提交所污染。更好的做法則是使用git rebase將一個(gè)feature分支變基到master分支:
$ git checkout feature$ git rebase master
這么做會(huì)將整個(gè)feature分支移動(dòng)到master分支的起點(diǎn),它會(huì)合并master分支上所有新的提交。不過(guò),相比于使用合并提交來(lái)說(shuō),變基會(huì)通過(guò)在原來(lái)的分支中為每次提交創(chuàng)建全新提交來(lái)重寫(xiě)項(xiàng)目歷史。變基的主要好處在于你會(huì)得到一個(gè)更加整潔的項(xiàng)目歷史。此外,這里還有關(guān)于變基的陷阱的一些討論。
2. 在執(zhí)行g(shù)it rebase后解決合并沖突
正如能力越大責(zé)任就越大一樣。在執(zhí)行g(shù)it rebase時(shí),你可能會(huì)遇到合并沖突的情況。合并沖突表示兩個(gè)提交修改了同一個(gè)文件的同一行,Git不知道該應(yīng)用哪一個(gè)修改。這會(huì)導(dǎo)致如下所示的錯(cuò)誤消息:
Git會(huì)為你提供3個(gè)選擇來(lái)修復(fù)導(dǎo)致沖突的提交(fa39187):
- 可以運(yùn)行g(shù)it rebase --abort來(lái)完全取消變基。這么做會(huì)取消變基修改,并將分支置回到執(zhí)行g(shù)it rebase之前的狀態(tài)。
- 可以運(yùn)行g(shù)it rebase --skip來(lái)完全忽略該提交。這樣,有問(wèn)題的提交所引入的變化就不會(huì)被添加到歷史中。
- 可以使用與合并沖突相同的標(biāo)準(zhǔn)步驟來(lái)解決沖突。
3. 臨時(shí)性保存修改
在工作進(jìn)行中時(shí),有些東西常常會(huì)處于凌亂的狀態(tài)。如果這時(shí)需要切換到不同的分支該怎么辦呢?Git是不允許你這么做的,因?yàn)檫€有尚未保存的修改。坦率地說(shuō),你并不想將半成品提交上去,后面再來(lái)修改。這個(gè)問(wèn)題的解決之道就是使用git stash命令。Stash會(huì)接收工作目錄的當(dāng)前狀態(tài)(比如說(shuō),修改了的追蹤文件與暫存區(qū)的修改等),并將其保存到未完成的修改棧中,這樣后面隨時(shí)可以再來(lái)修改。可以通過(guò)如下命令來(lái)暫存你的工作:
$ git stashSaved working directory and index state WIP on feature: 3fc175f fix race conditionHEAD is now at 3fc175f fix race condition
現(xiàn)在,工作目錄就是干凈的了:
$ git status# On branch featurenothing to commit, working directory clean
這時(shí)就可以安全地切換分支做別的事情了。不過(guò)不必?fù)?dān)心,暫存的提交依舊還在:
$ git stash liststash@{0}: WIP on feature: 3fc175f fix race condition
稍后,在回到feature分支后,你就可以取回所有暫存的變更了:
$ git stash popOn branch featureChanges not staged for commit: (use "git add ..." to update what will be committed) modified: index.htmlDropped refs/stash@{0} (ac2321cc3a33ba712b8e50c99a99d3c20da9d6b8)
關(guān)于暫存,還有其他一些選項(xiàng)可用,如下所示:
$ git stash save "describe it" # give the stash a name$ git stash clear # delete a stashed commit$ git stash save --keep-index # stash only unstaged files
4. 克隆一個(gè)特定的遠(yuǎn)程分支
如果想要從遠(yuǎn)程倉(cāng)庫(kù)中克隆一個(gè)特定的分支該怎么做呢?通常你會(huì)使用git clone,不過(guò)這么做會(huì)將所有其他分支都一并克隆下來(lái)。一個(gè)便捷的方式是使用git remote add:
$ git init $ git remote add -t-f origin $ git checkout
5. 將cherry-pick遠(yuǎn)程提交合并到自己的分支中
更有甚者,如果只想將遠(yuǎn)程倉(cāng)庫(kù)的一個(gè)特定提交合并到自己的分支中該怎么做呢?可以使用git cherry-pick 來(lái)選擇給定SHA值的提交,然后將其合并到當(dāng)前分支中:
$ git cherry-pick
6. 應(yīng)用來(lái)自于不相關(guān)的本地倉(cāng)庫(kù)的補(bǔ)丁
如果需要將另一個(gè)不相關(guān)的本地倉(cāng)庫(kù)的提交補(bǔ)丁應(yīng)用到當(dāng)前倉(cāng)庫(kù)該怎么做呢?答案就是下面這條命令:
$ git --git-dir=/.git format-patch -k -1 --stdout | git am -3 -k
7. 忽略追蹤文件中的變更
如果你和你的同事操縱的是相同分支,那么很有可能需要頻繁執(zhí)行g(shù)it merge或是git rebase。不過(guò),這么做可能會(huì)重置一些與環(huán)境相關(guān)的配置文件,這樣在每次合并后都需要修改。與之相反,你可以通過(guò)如下命令永久性地告訴Git不要管某個(gè)本地文件:
$ git update-index --assume-unchanged
8. 每隔X秒運(yùn)行一次git pull
通常,合并沖突出現(xiàn)的原因在于你正在工作的本地倉(cāng)庫(kù)不再反映遠(yuǎn)程倉(cāng)庫(kù)的當(dāng)前狀態(tài)。這正是我們?yōu)槭裁疵刻煸绯恳紫葓?zhí)行一次git pull的緣故。此外,你還可以在后臺(tái)通過(guò)腳本(或是使用GNU Screen)每隔X秒調(diào)用一次git pull:
$ screen$ for((i=1;i<=10000;i+=1)); do sleep X && git pull; done
9. 將子目錄分隔為新的倉(cāng)庫(kù)
有時(shí),你可能需要將Git倉(cāng)庫(kù)中某個(gè)特定的目錄轉(zhuǎn)換為一個(gè)全新的倉(cāng)庫(kù)。這可以通過(guò)git filter-branch來(lái)實(shí)現(xiàn):
$ git filter-branch --prune-empty --subdirectory-filtermaster# Filter the master branch to your directory and remove empty commitsRewrite 48dc599c80e20527ed902928085e7861e6b3cbe6 (89/89)Ref 'refs/heads/master' was rewritten
現(xiàn)在,倉(cāng)庫(kù)會(huì)包含指定子目錄中的所有文件。雖然之前的所有文件都會(huì)被刪除,但他們依舊存在于Git歷史中。現(xiàn)在可以將新的本地倉(cāng)庫(kù)推送到遠(yuǎn)程了。
10. 清理
有時(shí),Git會(huì)提示“untracked working tree files”會(huì)“overwritten by checkout”。造成這種情況的原因有很多。不過(guò)通常來(lái)說(shuō),我們可以使用如下命令來(lái)保持工作樹(shù)的整潔,從而防止這種情況的發(fā)生:
$ git clean -f # remove untracked files$ git clean -fd # remove untracked files/directories$ git clean -nfd # list all files/directories that would be removed
11. 將項(xiàng)目文件打成tar包,并且排除.git目錄
有時(shí),你需要將項(xiàng)目副本提供給無(wú)法訪問(wèn)GitHub倉(cāng)庫(kù)的外部成員。最簡(jiǎn)單的方式就是使用tar或zip來(lái)打包所有的項(xiàng)目文件。不過(guò),如果不小心,隱藏的.git目錄就會(huì)包含到tar文件中,這會(huì)導(dǎo)致文件體積變大;同時(shí),如果里面的文件與接收者自己的Git倉(cāng)庫(kù)弄混了,那就更加令人頭疼了。輕松的做法則是自動(dòng)從tar文件中排除掉.git目錄:
$ tar cJf.tar.xz / --exclude-vcs
12. 查找修改者
最后,如果出現(xiàn)混亂的情況,你一定想要找出是誰(shuí)造成的。如果生產(chǎn)服務(wù)器宕機(jī),那么找到罪魁禍?zhǔn)资潜容^容易的事情:只需執(zhí)行g(shù)it blame。該命令會(huì)顯示出文件中每一行的作者,提交hash則會(huì)找出該行的上一次修改,還能看到提交的時(shí)間戳:
$ git blame
當(dāng)然,Git命令是非常多的,除了上面介紹的12個(gè)重要命令外,相信各位InfoQ讀者在日常工作過(guò)程中也有自己偏愛(ài)且好用的一些命令,不妨以評(píng)論的形式與其他讀者一同分享。
相關(guān)熱詞搜索:12 git advanced commands 語(yǔ)言 & 開(kāi)發(fā) git 配置管理 源代碼
上一篇:Facebook將關(guān)閉其移動(dòng)開(kāi)發(fā)者平臺(tái)Parse
下一篇:Hadoop之父祝賀黃色小象的十歲生日快樂(lè)

頻道總排行
- Cisco NetFlow v9為何無(wú)人問(wèn)津?
- 技術(shù)專(zhuān)題:智能化運(yùn)維
- 開(kāi)源代碼管理:如何安全地使用開(kāi)源庫(kù)?
- Facebook架構(gòu)解讀
- IT運(yùn)維分析與海量日志搜索需要注意什么(1)
- 金山運(yùn)維肖力:如何將業(yè)務(wù)遷移到虛擬化環(huán)境并穩(wěn)定運(yùn)行(1)
- Apache Ignite(四):基于Ignite的分布式ID生成器
- CrazyEye,一款國(guó)人開(kāi)源的堡壘機(jī)軟件(1)
- SDN時(shí)代的網(wǎng)絡(luò)管理系統(tǒng)會(huì)走向何方
- WOT2016吳兆松:Zabbix監(jiān)控自動(dòng)化的未來(lái)如何發(fā)展
頻道本月排行
- 8你消費(fèi)我買(mǎi)單——"漏洞"天使OneRASP...
- 7有了Jenkins,為什么還需要一個(gè)獨(dú)立...
- 6IT運(yùn)維分析與海量日志搜索需要注意什么(1)
- 5新浪微博王傳鵬:微博推薦架構(gòu)的演進(jìn)(1)
- 4史上最大機(jī)器學(xué)習(xí)數(shù)據(jù)集,雅虎對(duì)外開(kāi)...
- 4雅虎開(kāi)源可以提升流操作速度的DataSketches
- 4大眾點(diǎn)評(píng)高可用性系統(tǒng)運(yùn)維經(jīng)驗(yàn)分享
- 4云運(yùn)維如何選擇部署適合自身的IDC和...
- 4開(kāi)源還是商用?十大云運(yùn)維監(jiān)控工具測(cè)...
- 4論開(kāi)發(fā)與運(yùn)維沖突的根源、表現(xiàn)形式及...