Git 進(jìn)階指南

在掌握了基礎(chǔ)的 Git 使用 之后写半,可能會(huì)遇到一些問(wèn)題屿衅。以下是貓哥篩選總結(jié)的部分常見(jiàn)問(wèn)題,分享給各位朋友擅腰,掌握了這些問(wèn)題的中的要點(diǎn)之后蟋恬,git 進(jìn)階也就完成了,它包含以下部分:

  • 如何修改 origin 倉(cāng)庫(kù)信息
  • 如何配置 git ssh keys
  • 如何撤銷(xiāo)修改
  • 遇到?jīng)_突了怎么解決
  • git stash / alias / submodule 的使用問(wèn)題等

問(wèn):如何修改 origin 倉(cāng)庫(kù)信息趁冈?

1筋现、添加 origin 倉(cāng)庫(kù)信息

git remote add origin <git倉(cāng)庫(kù)地址>

2、查看 origin 倉(cāng)庫(kù)信息

# 以下三種方式均可
git config get --remote.origin.url
git remote -v
git remote show origin

3箱歧、刪除 origin 倉(cāng)庫(kù)信息

git remote rm origin

問(wèn):如何配置 git ssh keys 矾飞?

  1. 在本地生成 ssh 私鑰 / 公鑰 文件
  2. 將「公鑰」添加到 git 服務(wù)(github、gitlab呀邢、coding.net 等)網(wǎng)站后臺(tái)
  3. 測(cè)試 git ssh 連接是否成功

接下來(lái)以添加 github ssh keys 為例洒沦,請(qǐng)注意替換 github 文件名。

注:如果對(duì)密鑰機(jī)制不熟悉,建議不要指定 -f 參數(shù),直接使用默認(rèn)的 id_rsa 文件名犁钟。

# 運(yùn)行以下命令粮坞,一直回車(chē),文件名可隨意指定
ssh-keygen -t rsa -b 4096 -C "kaiye@macbook" -f ~/.ssh/github

# 如果不是默認(rèn)密鑰 id_rsa 攒钳,則需要以下命令注冊(cè)密鑰文件,-K 參數(shù)將密鑰存入 Mac Keychain
ssh-add -K ~/.ssh/github

# 將 pub 公鑰的內(nèi)容粘貼到線(xiàn)上網(wǎng)站的后臺(tái)
cat ~/.ssh/github.pub

# 測(cè)試 git ssh 是否連接成功
ssh -T git@github.com

問(wèn):如何撤銷(xiāo)修改?

修改包含四種情況濒翻,需單獨(dú)區(qū)分。

1啦膜、新建的文件和目錄有送,且從未提交至版本庫(kù)

此類(lèi)文件的狀態(tài)為 Untracked files ,撤銷(xiāo)方法如下:

git clean -fd .

其中僧家,. 表示當(dāng)前目錄及所有子目錄中的文件雀摘,也可以直接指定對(duì)應(yīng)的文件路徑,以下其他情況類(lèi)似八拱。

2阵赠、提交過(guò)版本庫(kù),但未提交至?xí)捍鎱^(qū)的文件(未執(zhí)行 git add)

此類(lèi)文件的狀態(tài)為 Changes not staged for commit肌稻,撤銷(xiāo)方法:

git checkout .

3清蚀、已提交至?xí)捍鎱^(qū)的文件

此類(lèi)文件的狀態(tài)為 Changes to be committed,撤銷(xiāo)方法:

git reset .

執(zhí)行之后文件將會(huì)回到以上的 1 或者 2 狀態(tài)灯萍,可繼續(xù)按以上步驟執(zhí)行撤銷(xiāo)轧铁,若 git reset 同時(shí)加上 --hard 參數(shù),將會(huì)把修改過(guò)的文件也還原成版本庫(kù)中的版本旦棉。

4齿风、已提交至版本庫(kù)(執(zhí)行了 git commit)

每次提交都會(huì)生成一個(gè) hash 版本號(hào)药薯,通過(guò)以下命令可查閱版本號(hào)并將其回滾:

git log
git reset <版本號(hào)>

如果需要「回滾至上一次提交」,可直接使用以下命令:

git reset head~1

執(zhí)行之后救斑,再按照 1 或者 2 狀態(tài)進(jìn)行處理即可童本,如果回滾之后的代碼同時(shí)需要提交至 origin 倉(cāng)庫(kù)(即回滾 origin 線(xiàn)上倉(cāng)庫(kù)的代碼),需要使用 -f 強(qiáng)制提交參數(shù)脸候,且當(dāng)前用戶(hù)需要具備「強(qiáng)制提交的權(quán)限」穷娱。

5、如果回滾了之后又不想回滾了怎么辦运沦?

如果是以上的情況 1 或者 2泵额,只能歇屁了,因?yàn)樾薷臎](méi)入過(guò)版本庫(kù)携添,無(wú)法回滾嫁盲。

如果是情況 4,回滾之后通過(guò) git log 將看不到回滾之前的版本號(hào)烈掠,但可通過(guò) git reflog 命令(所有使用過(guò)的版本號(hào))找到回滾之前的版本號(hào)羞秤,然后 git reset <版本號(hào)>

問(wèn):遇到?jīng)_突了怎么解決左敌?

兩個(gè)分支進(jìn)行合并時(shí)(通常是 git pull 時(shí))瘾蛋,可能會(huì)遇到?jīng)_突,同時(shí)被修改的文件會(huì)進(jìn)入 Unmerged 狀態(tài)矫限,需要解決沖突哺哼。

1、最快的辦法

大部分時(shí)候奇唤,「最快解決沖突」的辦法是:使用當(dāng)前 HEAD 的版本(ours)幸斥,或使用合并進(jìn)來(lái)的分支版本(theirs)。

# 使用當(dāng)前分支 HEAD 版本咬扇,通常是沖突源文件的 <<<<<<< 標(biāo)記部分,======= 的上方
git checkout --ours <文件名>

# 使用合并分支版本廊勃,通常是源沖突文件的 >>>>>>> 標(biāo)記部分
git checkout --theirs <文件名>

# 標(biāo)記為解決狀態(tài)加入暫存區(qū)
git add <文件名>

2懈贺、最通用的辦法

用編輯器打開(kāi)沖突的源文件進(jìn)行修改,可能會(huì)發(fā)生遺留坡垫,且體驗(yàn)不好梭灿,通常需要借助 git mergetool 命令。

在 Mac 系統(tǒng)下冰悠,運(yùn)行 git mergetool <文件名> 可以開(kāi)啟配置的第三方工具進(jìn)行 merge堡妒,默認(rèn)的是 FileMerge 應(yīng)用程序,還可以配置成 Meld 或 kdiff3溉卓,體驗(yàn)更佳皮迟。

3搬泥、最好的習(xí)慣

有三個(gè)好的習(xí)慣,可以減少代碼的沖突:

  • 在開(kāi)始修改代碼前先 git pull 一下伏尼;
  • 將業(yè)務(wù)代碼進(jìn)行劃分忿檩,盡量不要多個(gè)人在同一時(shí)間段修改同一文件;
  • 通過(guò) Gitflow 工作流 也可以提升 git 流程效率爆阶,減少發(fā)生沖突的可能性燥透。

4、最復(fù)雜的情況

如果你的項(xiàng)目周期比較長(zhǎng)辨图,還應(yīng)該養(yǎng)成「定期 rebase 的習(xí)慣」班套,git pull --rebase 可以讓分支的代碼和 origin 倉(cāng)庫(kù)的代碼保持兼容,同時(shí)還不會(huì)破壞線(xiàn)上代碼的可靠性故河。

它的大概原理是吱韭,先將 origin 倉(cāng)庫(kù)的代碼按 origin 的時(shí)間流在本地分支中提交,再將本地分支的修改記錄追加到 origin 分支上忧勿。如果發(fā)生沖突杉女,則可以即時(shí)的發(fā)現(xiàn)問(wèn)題并解決,否則到項(xiàng)目上線(xiàn)時(shí)再解決沖突鸳吸,可能會(huì)發(fā)生額外的風(fēng)險(xiǎn)熏挎。

rebase 大概的操作步驟如下:

# 將當(dāng)前分支的版本追加到從遠(yuǎn)程 pull 回來(lái)的節(jié)點(diǎn)之后
git pull --rebase

# 若發(fā)生沖突,則按以上其他方法進(jìn)行解決晌砾,解決后繼續(xù)
git rebase --continue

# 直到所有沖突得以解決坎拐,待項(xiàng)目最后上線(xiàn)前再執(zhí)行
git push origin

# 若多次提交修改了同一文件,可能需要直接跳過(guò)后續(xù)提交养匈,按提示操作即可
git rebase --skip

問(wèn):如何在不提交修改的前提下哼勇,執(zhí)行 pull / merge 等操作?

有些修改沒(méi)有完全完成之前呕乎,可能不需要提交到版本庫(kù)积担,圡方法是將修改的文件 copy 到 git 倉(cāng)庫(kù)之外的目錄臨時(shí)存放,pull / merge 操作完成之后猬仁,再 copy 回來(lái)帝璧。

這樣的做法一個(gè)是效率不高,另外一個(gè)可能會(huì)遺漏潛在的沖突湿刽。此類(lèi)需求最好是通過(guò) git stash 命令來(lái)完成的烁,它可以將當(dāng)前工作狀態(tài)(WIP,work in progress)臨時(shí)存放在 stash 隊(duì)列中诈闺,待操作完成后再?gòu)?stash 隊(duì)列中重新應(yīng)用這些修改渴庆。

以下是 git stash 常用命令:

# 查看 stash 隊(duì)列中已暫存了多少 WIP
git stash list

# 恢復(fù)上一次的 WIP 狀態(tài),并從隊(duì)列中移除
git stash pop

# 添加當(dāng)前 WIP,注意:未提交到版本庫(kù)的文件會(huì)自動(dòng)忽略襟雷,只要不運(yùn)行 git clean -fd . 就不會(huì)丟失
git stash

# 恢復(fù)指定編號(hào)的 WIP刃滓,同時(shí)從隊(duì)列中移除
git stash pop stash@{num}

# 恢復(fù)指定編號(hào)的 WIP,但不從隊(duì)列中移除
git stash apply stash@{num}

問(wèn):如何在 git log 中查看修改的文件列表嗤军?

默認(rèn)的 git log 會(huì)顯示較全的信息注盈,且不包含文件列表。使用 --name-status 可以看到修改的文件列表叙赚,使用 --oneline 可以將參數(shù)簡(jiǎn)化成一行老客。

git log --name-status --oneline

每次手動(dòng)加上參數(shù)很麻煩,可以通過(guò)自定義快捷命令的方式來(lái)簡(jiǎn)化操作:

git config --global alias.ls 'log --name-status --oneline --graph'

運(yùn)行以上配置后震叮,可通過(guò) git ls 命令來(lái)實(shí)現(xiàn)「自定義 git log」效果胧砰,通過(guò)該方法也可以創(chuàng)建 git stgit ci 等一系列命令苇瓣,以便沿用 svn 命令行習(xí)慣尉间。

git config --global alias.st 'status --porcelain'

更多 git log 參數(shù),可通過(guò) git help log 查看手冊(cè)击罪。

如果是看上一次提交的版本日志哲嘲,直接運(yùn)行 git show 即可。

此外媳禁,如果你的 Mac 安裝了 zsh(參考《全新 Mac 安裝指南(編程篇)》 )眠副,那么可以直接使用大量?jī)?nèi)置 git 快捷命令,詳見(jiàn)此列表:Plugin:git 竣稽,其中較為常用的命令包括:

  • gl 即 git pull
  • gup 即 git pull --rebase囱怕,一般建議使用 gup,它會(huì)比 gl 少一次 merge 記錄
  • gst 即 git status
  • gaa 將當(dāng)前版本庫(kù)所有改動(dòng)提交至?xí)捍鎱^(qū)毫别,即 git add -all
  • gp 本地分支提交至遠(yuǎn)程倉(cāng)庫(kù)娃弓,即 git push
  • gcmsg 即 git commit -m
  • gco 即 git checkout
  • glol 格式化版本號(hào)、提交時(shí)間岛宦、作者信息的 git log
  • gwip 臨時(shí)提交版本
  • gunwip 從當(dāng)前分支的上一次臨時(shí)提交版本恢復(fù)修改

問(wèn):git submodule update 時(shí)出錯(cuò)怎么解決台丛?

例如,在執(zhí)行 git submodule update 時(shí)有以下錯(cuò)誤信息:

fatal: reference is not a tree: f869da471c5d8a185cd110bbe4842d6757b002f5
Unable to checkout 'f869da471c5d8a185cd110bbe4842d6757b002f5' in submodule path 'source/i18n-php-server'

在此例中砾肺,發(fā)生以上錯(cuò)誤是因?yàn)?i18n-php-server 子倉(cāng)庫(kù)在某電腦 A 的「本地」commit 了新的版本 「f869da471c5d8a185cd110bbe4842d6757b002f5」齐佳,且該次 commit 未 push origin。但其父級(jí)倉(cāng)庫(kù) i18n-www 中引用了該子倉(cāng)庫(kù)的版本號(hào)债沮,且將引用記錄 push origin,導(dǎo)致其他客戶(hù)機(jī)無(wú)法 update 本鸣。

解決方法疫衩,在電腦 A 上將 i18n-php-server 版本庫(kù) push origin 后,在其他客戶(hù)機(jī)上執(zhí)行 git submodule update 荣德∶泼海或者用以上提到的 git reset 方法童芹,將子倉(cāng)庫(kù)的引用版本號(hào)還原成 origin 上存在的最新版本號(hào)。

其他問(wèn)題

  • 設(shè)置本地分支與遠(yuǎn)程分支保持同步鲤拿,在第一次 git push 的時(shí)候帶上 -u 參數(shù)即可

    git push origin master -u 
    
  • 支持中文目錄與文件名的顯示(git 默認(rèn)將非 ASCII 編碼的目錄與文件名以八進(jìn)制編碼展示)

    git config core.quotepath off
    
  • 常用的打 tag 操作假褪,更多請(qǐng)查看《Git 基礎(chǔ) - 打標(biāo)簽

    # 列出所有本地 tag
    git tag
    
    # 本地新增一個(gè) tag,推送至 origin 服務(wù)器
    git tag -a v1.0.0 -m 'tag description'
    git push origin v1.0.0
    
    # 刪除本地與 origin tag
    git tag -d v1.0.0
    git push origin --delete v1.0.0
    
  • 使用 Git GUI 客戶(hù)端(如近顷,SoureTree生音、Github Desktop)能極大的提升分支管理效率。分支合并操作通常只有兩種情況:從 origin merge 到本地窒升,使用 git pull 即可缀遍;從另外一個(gè)本地分支 merge 到當(dāng)前分支,使用 git merge <分支名>饱须,以下是常用命令:

    # 新建分支 branch1域醇,并切換過(guò)去
    git checkout -b branch1
    
    # 查看所有本地與遠(yuǎn)程分支
    git branch -a
    
    # 修改完成后,切換回 master 分支蓉媳,將 branch1 分支合并進(jìn)來(lái)
    git checkout master
    git merge branch1
    
    # 刪除已完成合并的分支 branch1
    git branch -d branch1
    
  • Mac 下好用的 Git 對(duì)比譬挚、合并工具不多,推薦使用 Beyond Compare Pro Edition(付費(fèi)軟件酪呻,多人團(tuán)購(gòu)有優(yōu)惠)减宣,配置方法如下

    1. 從 Beyond Compare 主菜單中執(zhí)行 Install Command Line Tools
    2. Shell 中運(yùn)行如下 git 配置命令:
    git config --global diff.tool bc3
    # 設(shè)置完成后可使用 git difftool file.ext 對(duì)比文件歷史記錄
    
    git config --global merge.tool bc3
    git config --global mergetool.bc3 trustExitCode true
    git config --global mergetool.keepBackup false # 關(guān)閉生成 .orig 備份文件
    # 設(shè)置完成后可使用 git mergetool file.ext 合并沖突狀態(tài)的文件
    

    若使用 SourceTree 客戶(hù)端号杠,設(shè)置與操作步驟如下:

    1. 配置外部對(duì)比蚪腋、合并工具為 Beyond Compare
    sourceTree 配置外部對(duì)比、合并工具
    1. 使用指定合并工具解決沖突文件
    sourceTree 啟動(dòng)合并工具解決沖突
    1. Beyond Compare 的合并界面姨蟋,「上左」與「上右」面板為合并發(fā)生沖突的兩次提交版本屉凯,「上中」為前次歷史版本,「下方」為合并后的代碼眼溶。通常只需要處理下方面板中悠砚,「紅色!」所指示的代碼行堂飞,點(diǎn)擊「藍(lán)色?」或「紫色?」灌旧,選擇正確的代碼。合并完成后直接關(guān)閉窗口绰筛,文件會(huì)被自動(dòng)標(biāo)記為已解決狀態(tài)枢泰,添加至?xí)捍鎱^(qū)。
    Beyond Compare Merge 操作面板

如有其他問(wèn)題铝噩,請(qǐng)?jiān)?github 上留言補(bǔ)充 :)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末衡蚂,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌毛甲,老刑警劉巖年叮,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異玻募,居然都是意外死亡只损,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén)七咧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)跃惫,“玉大人,你說(shuō)我怎么就攤上這事坑雅”补遥” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵裹粤,是天一觀的道長(zhǎng)终蒂。 經(jīng)常有香客問(wèn)我,道長(zhǎng)遥诉,這世上最難降的妖魔是什么拇泣? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮矮锈,結(jié)果婚禮上霉翔,老公的妹妹穿的比我還像新娘。我一直安慰自己苞笨,他們只是感情好债朵,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著瀑凝,像睡著了一般序芦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上粤咪,一...
    開(kāi)封第一講書(shū)人閱讀 49,784評(píng)論 1 290
  • 那天谚中,我揣著相機(jī)與錄音,去河邊找鬼寥枝。 笑死宪塔,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的囊拜。 我是一名探鬼主播某筐,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼冠跷!你這毒婦竟也來(lái)了来吩?” 一聲冷哼從身側(cè)響起敢辩,我...
    開(kāi)封第一講書(shū)人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎弟疆,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體盗冷,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡怠苔,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了仪糖。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片柑司。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖锅劝,靈堂內(nèi)的尸體忽然破棺而出攒驰,到底是詐尸還是另有隱情,我是刑警寧澤故爵,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布玻粪,位于F島的核電站,受9級(jí)特大地震影響诬垂,放射性物質(zhì)發(fā)生泄漏劲室。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一结窘、第九天 我趴在偏房一處隱蔽的房頂上張望很洋。 院中可真熱鬧,春花似錦隧枫、人聲如沸喉磁。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)协怒。三九已至,卻和暖如春确买,著一層夾襖步出監(jiān)牢的瞬間斤讥,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工湾趾, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留芭商,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓搀缠,卻偏偏與公主長(zhǎng)得像铛楣,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子艺普,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

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

  • 1. 安裝 Github 查看是否安裝git: $ git config --global user.name "...
    Albert_Sun閱讀 13,644評(píng)論 9 163
  • 不知道還愛(ài) 不知道還恨 不知道什么是喜歡 不知道什么是愛(ài) 不知道明天還在 不知道你是誰(shuí) 不知道歲月不饒人 不知道有...
    大濕人閱讀 179評(píng)論 0 0
  • 春三月簸州,此謂發(fā)陳鉴竭,天地俱生,萬(wàn)物以榮岸浑,夜臥早起搏存,廣步于庭,被發(fā)緩形矢洲,以使志生璧眠,生而勿殺,予而勿奪读虏,賞而勿罰责静,此春氣...
    錦似半夏閱讀 296評(píng)論 0 1
  • 三個(gè)月相處 讓我更相信你們 從最初的不開(kāi)心 到現(xiàn)在的其樂(lè)融融 雖然現(xiàn)在我們不會(huì)別離 但我已開(kāi)始想戀 現(xiàn)在一別 不知...
    寫(xiě)作星閱讀 314評(píng)論 0 0