你需要知道的 12 個(gè) Git 高級(jí)命令

作者:張龍
原文地址:
http://www.infoq.com/cn/news/2016/01/12-git-advanced-commands

眾所周知恼除,Git目前已經(jīng)是分布式版本控制領(lǐng)域的翹楚嬉愧,圍繞著Git形成了完整的生態(tài)圈。學(xué)習(xí)Git剂碴,首先當(dāng)然是學(xué)習(xí)Git的基本工作流把将。相比于SVN等傳統(tǒng)版本控制系統(tǒng)來說,Git是專為分布式版本控制而生的強(qiáng)大工具忆矛。使用Git時(shí)常用的命令有pull察蹲、commitpush等催训,貌似很簡(jiǎn)單洽议。不過,有時(shí)你會(huì)遇到合并沖突的情況漫拭,Git這時(shí)會(huì)將沖突標(biāo)記出來亚兄,需要你手工來解決。有時(shí)采驻,你會(huì)不小心將代碼提交到錯(cuò)誤的分支上审胚,并且又推送到了遠(yuǎn)程倉(cāng)庫(kù)。還有些時(shí)候挑宠,你需要切換到不同的分支菲盾,但Git卻不讓你這么做,因?yàn)檫€有未保存的修改各淀。如果需要通過另一個(gè)分支的提交來為代碼打補(bǔ)丁該怎么做呢懒鉴?本文就將介紹12個(gè)Git高級(jí)命令,合理使用這些命令可以大大提升應(yīng)用Git的效率。

1. 使用rebase而非merge來拉取上游修改

分支合并會(huì)被記錄為一次合并提交临谱,這種做法是很有意義的璃俗。比如說,可以通過這種方式來標(biāo)識(shí)一個(gè)新特性被合并到了發(fā)布分支中悉默。不過城豁,當(dāng)多個(gè)團(tuán)隊(duì)成員工作在一個(gè)項(xiàng)目中并使用常規(guī)的git pull來同步分支時(shí),提交時(shí)間線就會(huì)被不必要的合并提交所污染抄课。更好的做法則是使用git rebase將一個(gè)feature分支變基到master分支:

$ git checkout feature
$ git rebase master

這么做會(huì)將整個(gè)feature分支移動(dòng)到master分支的起點(diǎn)唱星,它會(huì)合并master分支上所有新的提交。不過跟磨,相比于使用合并提交來說间聊,變基會(huì)通過在原來的分支中為每次提交創(chuàng)建全新提交來重寫項(xiàng)目歷史。變基的主要好處在于你會(huì)得到一個(gè)更加整潔的項(xiàng)目歷史抵拘。此外哎榴,這里還有關(guān)于變基的陷阱的一些討論。

2. 在執(zhí)行g(shù)it rebase后解決合并沖突

正如能力越大責(zé)任就越大一樣僵蛛。在執(zhí)行git rebase時(shí)尚蝌,你可能會(huì)遇到合并沖突的情況。合并沖突表示兩個(gè)提交修改了同一個(gè)文件的同一行充尉,Git不知道該應(yīng)用哪一個(gè)修改飘言。這會(huì)導(dǎo)致如下所示的錯(cuò)誤消息:

Git會(huì)為你提供3個(gè)選擇來修復(fù)導(dǎo)致沖突的提交(fa39187):

  • 可以運(yùn)行git rebase --abort來完全取消變基。這么做會(huì)取消變基修改喉酌,并將分支置回到執(zhí)行g(shù)it rebase之前的狀態(tài)热凹。
  • 可以運(yùn)行git rebase --skip來完全忽略該提交。這樣泪电,有問題的提交所引入的變化就不會(huì)被添加到歷史中般妙。
  • 可以使用與合并沖突相同的標(biāo)準(zhǔn)步驟來解決沖突。

3. 臨時(shí)性保存修改

在工作進(jìn)行中時(shí)相速,有些東西常常會(huì)處于凌亂的狀態(tài)碟渺。如果這時(shí)需要切換到不同的分支該怎么辦呢?Git是不允許你這么做的突诬,因?yàn)檫€有尚未保存的修改苫拍。坦率地說,你并不想將半成品提交上去旺隙,后面再來修改绒极。這個(gè)問題的解決之道就是使用git stash命令。Stash會(huì)接收工作目錄的當(dāng)前狀態(tài)(比如說蔬捷,修改了的追蹤文件與暫存區(qū)的修改等)垄提,并將其保存到未完成的修改棧中榔袋,這樣后面隨時(shí)可以再來修改≌±可以通過如下命令來暫存你的工作:

$ git stash
Saved working directory and index state WIP on feature: 3fc175f fix race condition
HEAD is now at 3fc175f fix race condition

現(xiàn)在凰兑,工作目錄就是干凈的了:

$ git status
# On branch feature
nothing to commit, working directory clean

這時(shí)就可以安全地切換分支做別的事情了。不過不必?fù)?dān)心审丘,暫存的提交依舊還在:

$ git stash list
stash@{0}: WIP on feature: 3fc175f fix race condition

稍后吏够,在回到feature分支后,你就可以取回所有暫存的變更了:

$ git stash pop
On branch feature
Changes not staged for commit:
  (use "git add ..." to update what will be committed)

     modified:   index.html
Dropped 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脓钾,不過這么做會(huì)將所有其他分支都一并克隆下來喉镰。一個(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來選擇給定SHA值的提交,然后將其合并到當(dāng)前分支中:

$ git cherry-pick

6. 應(yīng)用來自于不相關(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í)行git merge或是git rebase。不過柱蟀,這么做可能會(huì)重置一些與環(huán)境相關(guān)的配置文件川蒙,這樣在每次合并后都需要修改。與之相反长已,你可以通過如下命令永久性地告訴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)通過腳本(或是使用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ù)胞四。這可以通過git filter-branch來實(shí)現(xiàn):

$ git filter-branch --prune-empty --subdirectory-filter  master
# Filter the master branch to your directory and remove empty commits
Rewrite 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”。造成這種情況的原因有很多舌稀。不過通常來說,我們可以使用如下命令來保持工作樹的整潔耘子,從而防止這種情況的發(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)目副本提供給無法訪問GitHub倉(cāng)庫(kù)的外部成員。最簡(jiǎn)單的方式就是使用tarzip來打包所有的項(xiàng)目文件囚聚。不過靖榕,如果不小心,隱藏的.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í)行git blame优质。該命令會(huì)顯示出文件中每一行的作者竣贪,提交hash則會(huì)找出該行的上一次修改,還能看到提交的時(shí)間戳:

$ git blame

當(dāng)然巩螃,Git命令是非常多的演怎,除了上面介紹的12個(gè)重要命令外,相信各位InfoQ讀者在日常工作過程中也有自己偏愛且好用的一些命令避乏,不妨以評(píng)論的形式與其他讀者一同分享爷耀。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市拍皮,隨后出現(xiàn)的幾起案子歹叮,更是在濱河造成了極大的恐慌,老刑警劉巖铆帽,帶你破解...
    沈念sama閱讀 211,376評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件咆耿,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡锄贼,警方通過查閱死者的電腦和手機(jī)票灰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宅荤,“玉大人屑迂,你說我怎么就攤上這事》爰” “怎么了惹盼?”我有些...
    開封第一講書人閱讀 156,966評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)惫确。 經(jīng)常有香客問我手报,道長(zhǎng)蚯舱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,432評(píng)論 1 283
  • 正文 為了忘掉前任掩蛤,我火速辦了婚禮枉昏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘揍鸟。我一直安慰自己兄裂,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評(píng)論 6 385
  • 文/花漫 我一把揭開白布阳藻。 她就那樣靜靜地躺著晰奖,像睡著了一般。 火紅的嫁衣襯著肌膚如雪腥泥。 梳的紋絲不亂的頭發(fā)上匾南,一...
    開封第一講書人閱讀 49,792評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音蛔外,去河邊找鬼蛆楞。 笑死,一個(gè)胖子當(dāng)著我的面吹牛夹厌,可吹牛的內(nèi)容都是我干的臊岸。 我是一名探鬼主播,決...
    沈念sama閱讀 38,933評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼尊流,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了灯帮?” 一聲冷哼從身側(cè)響起崖技,我...
    開封第一講書人閱讀 37,701評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎钟哥,沒想到半個(gè)月后迎献,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,143評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡腻贰,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評(píng)論 2 327
  • 正文 我和宋清朗相戀三年吁恍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片播演。...
    茶點(diǎn)故事閱讀 38,626評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡冀瓦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出写烤,到底是詐尸還是另有隱情翼闽,我是刑警寧澤,帶...
    沈念sama閱讀 34,292評(píng)論 4 329
  • 正文 年R本政府宣布洲炊,位于F島的核電站感局,受9級(jí)特大地震影響尼啡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜询微,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評(píng)論 3 313
  • 文/蒙蒙 一崖瞭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧撑毛,春花似錦书聚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至蹦疑,卻和暖如春艇肴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背叁温。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工再悼, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人膝但。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓冲九,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親跟束。 傳聞我的和親對(duì)象是個(gè)殘疾皇子莺奸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • Git是目前最流行的版本管理系統(tǒng),也是最先進(jìn)的分布式版本控制系統(tǒng)(distributed version cont...
    pro648閱讀 5,682評(píng)論 1 17
  • git常用命令 GIT常用命令備忘:http://stormzhang.com/git/2014/01/27/gi...
    新篇章閱讀 8,458評(píng)論 1 26
  • 找了網(wǎng)上的婚紗線稿練手冀宴,覺得設(shè)計(jì)者好厲害灭贷。
    蘇江何閱讀 844評(píng)論 3 2
  • 我們不可能脫離環(huán)境研究人。每個(gè)人在不同環(huán)境中略贮,有不同的身份甚疟,就會(huì)有不同的態(tài)度。單獨(dú)脫離外界影響逃延,來研究這些無意義览妖。...
    隨心所欲_e050閱讀 340評(píng)論 0 0
  • 悟空:我要這鐵棒有何用? 龍王:大王神通了得揽祥。 悟空:我有這變化又如何黄痪? 閻王:求莫?dú)巧啦尽?悟空:踏碎凌霄,...
    傅人閱讀 1,028評(píng)論 5 29