天天看點

Git用法快速參考安裝特點三個區域三種狀态已跟蹤或未跟蹤簡單描述Git庫儲存的内容Git使用Git的配置建立本地Git倉庫本地Git庫的常用操作指令涉及遠端庫的常用操作指令分支操作指令(git建立的預設分支名為master)檢視送出曆史stash儲藏工作清理工作目錄如何在Github上工作Git指令的别名替換忽略不想被納入Git管理的檔案Git伺服器架設三種分布式工作流程常見疑問

注:本文會不定期更新,請關注 雲栖社群@一唐。

linux: <code>$ sudo yum install git</code> 或 <code>$ sudo apt-get install git</code>

直接記錄檔案快照,而非記錄檔案的差異資訊(倉庫中包含每個檔案的獨立拷貝,修改後的檔案會生成新拷貝);

若版本a和版本b中有6個檔案(共同的檔案)沒有做過任何修改,那麼在倉庫中這6個檔案隻會存在一份,而不是兩份;

利用sha-1校驗機制來保證檔案資料完整性;

使用者克隆一個git庫到本地時,會把該庫的所有資訊都拷貝下來,包括這個庫的所有曆史送出記錄;

git庫一般隻添加資料,意味着隻要是曾經送出到倉庫的内容,都可以被恢複出來。

工作區:就是使用者可編輯檔案或目錄的區域;

git倉庫:就是包含了項目各個版本資料的地方,我們不管需要哪個版本都可從這個區域取資料;

暫存區:就是把使用者修改、建立、删除檔案的記錄儲存起來,作為送出操作的參考資訊。

已修改:如果工作區的某檔案發生了修改,此檔案就屬于已修改狀态;

已暫存:如果某檔案作了修改并已添加(git add filename)到暫存區,此檔案就屬于已暫存狀态;

已送出:如果對某檔案進行了修改,并且在添加到暫存區後不久就送出到了git倉庫,此檔案就屬于已送出狀态。

已跟蹤:曾經被送出過本地git庫的檔案,也就是被納入了版本控制的檔案;

未跟蹤:沒有被納入版本控制的檔案,就是“已跟蹤”狀态之外的檔案;

工作目錄下的檔案,不是“已跟蹤”就是“未跟蹤”。

假設建立了一個本地庫,裡面建立了3個檔案,并且已用指令把它們送出到了本地庫;

在上面送出後,本地庫會有五個對象:三個 blob 對象(儲存着檔案快照,裡面有檔案内容)、一個樹對象(記錄着目錄結構和 blob 對象索引)以及一個送出對象(包含着指向前述樹對象的指針和所有送出資訊)

1、在指令視窗輸入 <code>$ git help</code> 即可檢視git的使用幫助,若不能使用此指令,說明git沒有安裝好;

2、檢視某個git指令的幫助,例如檢視config指令的幫助 <code>$ git help config</code>

檢視目前配置的指令 <code>$ git config --list</code>

設定使用者資訊(git的每次送出操作都會使用這些資訊,以便讓别人知道是誰送出的)

<code>$ git config --global user.name "yourname"</code>

<code>$ git config --global user.email [email protected]</code>

配置分為三級:系統配置、目前使用者配置、目前git庫配置

“目前git庫配置”會覆寫“目前使用者配置”,“目前使用者配置”會覆寫“系統配置”

修改系統配置方法 <code>$ git config --system user.name "yourname"</code>

修改目前使用者配置方法 <code>$ git config --global user.name "yourname"</code>

修改目前git庫配置方法(先進入到該git庫的目錄) <code>$ git config user.name "yourname"</code>

檢視目前的某項配置是什麼 <code>$ git config user.name</code>

建立一個目錄作為本地倉庫的落腳點;

進入建立的目錄,用倉庫初始化指令把它變成git倉庫 <code>$ git init</code>

如果不是一個建立的目錄,裡面已經有了檔案,也照樣先初始化;

不管是此目錄後來建立的檔案,還是本來就有的檔案,都需要先把它們加入暫存區,然後再送出它們,才算是把這些檔案放入了git倉庫。

把某檔案添加到暫存區 <code>$ git add filename</code>

把某目錄下的所有檔案(包含遞歸子目錄)添加到暫存區 <code>$ git add dirname</code>

把擴充名為.c的檔案都添加到暫存區 <code>$ git add *.c</code>

把記錄在暫存區的檔案全部送出到本地git倉庫 <code>$ git commit -m 'your comment'</code> (送出後會出現報告資訊,比如在哪個分支送出的,本次送出的sha-1校驗碼是什麼(如463dc4f),在本次送出中有多少檔案修改過,多少行添加和删改過等)

從暫存區移出檔案movefile.txt,讓它先不暫存 <code>$ git reset head movefile.txt</code>

從git庫中恢複一個檔案并覆寫到工作區 <code>$ git checkout -- filename.txt</code>

檢視目前git庫的狀态 <code>$ git status</code>

可以知道:

a、目前所在分支(on branch xxxx)

b、哪些檔案處于暫存區(changes to be committed)

c、哪些屬于“未跟蹤”狀态的新檔案(untracked files)

d、哪些屬于被修改但未處于暫存區的已跟蹤檔案(changes not staged for commit)

簡要檢視目前git庫的狀态 <code>$ git status -s</code>

前面辨別含義:

?? 未跟蹤檔案

a 新添加到暫存區中的檔案

m 檔案被修改了并放入了暫存區

 m (注意m的左邊有個空格)檔案被修改了但是還沒放入暫存區(需要再 git add 一下)

mm 在工作區被修改并添加到暫存區後又在工作區中被修改了(需要再 git add 一下)

am 新添加到暫存區中的檔案,還未送出的情況下又被修改了(需要再 git add 一下)

檢視工作區檔案和暫存區檔案之間的差異 <code>$ git diff</code>

檢視已經暫存起來的檔案變化狀況 <code>$ git diff --cached</code>

調用文本編輯器并送出更新 <code>$ git commit</code> (按回車後會出現文本編輯視窗,讓你輸入相關的修改記錄資訊,比如描述自己新增加了哪些内容、哪些功能等)

自動把所有已經跟蹤過的檔案暫存起來一并送出,進而跳過加入暫存區的操作 <code>$ git commit -a -m 'new comment'</code>

删除檔案 <code>$ git rm filename.txt</code> (如果隻是 rm filename.txt ,并不能起到删除暫存區檔案的作用)

檔案被修改了并已添加到暫存區的删除 <code>$ git rm -f filename.txt</code> (此時需要加-f強制删除)

檔案被誤放入暫存區,需要移出來 <code>$ git rm --cached filename.txt</code> (可以使用通配符,如 *.log 表示.log結尾的檔案, dir/*.a 表示dir目錄下.a結尾的檔案,請務必注意*号前面要加 )

檔案改名 <code>$ git mv oldname newname</code>

相當于執行了三條指令:

<code>$ mv oldname newname</code>

<code>$ git rm oldname</code>

<code>$ git add newname</code>

補充送出操作,比如送出完了才發現漏掉了幾個檔案沒有添加,或者送出資訊寫錯了,可參考下面的步驟:

<code>$ git commit -m 'comment'</code> #此時發現忘了送出forgotten.txt檔案

<code>$ git add forgotten.txt</code> #加上forgotten.txt

<code>$ git commit --amend</code> #用--amend參數補交,按下回車後會讓你編輯前面的comment資訊

給某個送出曆史打标簽 <code>$ git tag -a v1.1 085bb3 -m 'my version 1.1'</code> (085bb3是該曆史版本的sha-1校驗碼前6位)

檢視本地庫有哪些标簽 <code>$ git tag</code> (标簽隻是一個曆史送出的别名而已)

檢視指定模式比對的标簽 <code>$ git tag -l 'v1.8*'</code>

給目前版本打标簽 <code>$ git tag -a v1.2 -m 'smallez_version 1.2'</code>

檢視指定标簽版本對應的送出資訊 <code>$ git show v1.1</code>

檢查要送出的檔案中是否包含多餘的空白字元 <code>$ git diff --check</code>

把format-patch更新檔檔案應用到目前分支 <code>$ git am patch-smallez-client.patch</code>

把老式diff更新檔檔案應用到目前分支 <code>$ git apply patch-smallez-client.patch</code>

輸出master分支最後一次送出的可讀名稱 <code>$ git describe master</code> (如果最後一次送出設定了标簽,就顯示标簽名,否則由最近的标簽名、自該标簽之後的送出數目和它部分sha-1值構成)

為master分支打包建立一個歸檔 <code>$ git archive master --prefix='projname/' | gzip &gt; `projname_v1.x`.tar.gz</code>

接上面,如果要生成zip格式 <code>$ git archive master --prefix='projname/' --format=zip &gt; `projname_v1.x`.zip</code>

生成自master分支v1.1(标簽名)以來的changelog <code>$ git shortlog --no-merges master --not v1.1</code> (如果已經合并到master,此指令就沒意義了)

檢視某個送出的父送出(就是上一個送出)資訊 <code>$ git show d921970^</code> (使用^符号)

從工作目錄查找一個包含某關鍵字的檔案 <code>$ git grep -n keyword</code>

将某個版本恢複到工作區 <code>$ git checkout d92197</code> (d92197是要恢複的送出曆史的sha-1前6位) ,如果要再恢複到最新的送出 <code>$ git checkout branch_name</code> (branch_name是分支名稱)

把遠端庫的項目克隆到本地 <code>$ git clone https://github.com/libgit2/libgit2</code> (此時遠端庫的預設名為origin)

把遠端庫的項目克隆到本地并改名為smallez <code>$ git clone https://github.com/libgit2/libgit2 smallez</code>

檢視本地庫所配置的遠端庫資訊 <code>$ git remote</code> (顯示的是遠端庫的簡寫名)

檢視遠端庫簡寫名對應的url <code>$ git remote -v</code> (注意:一個本地庫可以擁有多個遠端庫,即可以把本地庫的版本推送到多個遠端庫儲存)

為本地庫添加一個新的遠端庫 <code>$ git remote add remote-name https://smallez.com/xxx</code> (remote-name是遠端庫的簡寫名,你可以自由設定)

更改遠端庫的簡寫名 <code>`$ git remote rename oldname newname</code>

删除一個遠端庫配置 <code>$ git remote rm remote-name</code>

從遠端庫抓取最新更改的檔案 <code>$ git fetch remote-name</code> (并不會自動合并或修改你目前的工作)

從遠端庫拉取最新更改的檔案并自動嘗試合并到目前所在的分支 <code>$ git pull remote-name</code>

把本地庫的master分支版本推送到簡寫名為origin的遠端庫 <code>$ git push origin master</code>

可能會推送失敗的情況:

a、沒有遠端庫的寫入權限

b、上次從遠端庫抓取檔案下來後,在你準備推送前,又有其它人更新了遠端庫

c、由于上面的情況導緻伺服器上的檔案可能會比你本地的要新,是以必須先從遠端伺服器拉取最新的檔案合并到你的本地庫後才能推送

檢視某個遠端倉庫的資訊 <code>$ git remote show remote-name</code>

當把本地庫檔案推送到遠端庫時,并不會把标簽資訊也自動推送過去,要另外用指令推送 <code>$ git push origin v1.5</code>

把所有不在遠端庫上的本地标簽都推送過去 <code>$ git push origin --tags</code>

用指定的标簽建立一個新分支 <code>$ git checkout -b branchname tagname</code>

把本地庫的master分支推送到命名為origin的遠端庫的master分支,并建立跟蹤 <code>$ git push -u origin master</code>

把本地庫的test分支推送到命名為origin的遠端庫的newtest分支,并建立跟蹤 <code>$ git push -u origin test:newtest</code>

當從遠端庫抓取更新檔案時,發現一個新的分支,本地不會自動生成一份可編輯的拷貝,解決方法:

a、抓取遠端庫 <code>$ git fetch origin</code> (發現遠端庫有serverfix分支)

b、在本地庫建立localfix分支,并讓它保持和origin/serverfix跟蹤 $ git checkout -b localfix origin/serverfix

c、上面的操作,如果localfix名字變成了serverfix(即和遠端庫一樣),可以簡化成這樣 <code>$ git checkout --track origin/serverfix</code>

d、如果要在本地已有的分支跟蹤一個遠端分支 <code>$ git branch -u origin/serverfix</code>

可以用@{upstream}或@{u} 作為快捷字元,來代替正在跟蹤的分支路徑,比如 origin/master

檢視本地分支和遠端分支的對應清單 <code>$ git branch -vv</code> (注意它隻是在本地做比較并未連到遠端伺服器,第20條有說明)

顯示含義:

a、 master 1ae2a45 [origin/master] deploying index 表示本地master分支正在跟蹤origin/master分支并且是最新的

b、 iss53 7e424c3 [origin/iss53: ahead 2, behind 1] forgot the brackets 表示iss53分支正在跟蹤origin/iss53并且ahead是2,意味着本地有兩個送出還沒有推送到伺服器上,behind 1表示落後1,伺服器上有一次送出還沒抓到本地并入

接上面第19條,先抓取所有的遠端庫,然後再顯示清單 <code>$ git fetch --all; git branch -vv</code>

删除遠端庫的分支 <code>$ git push origin --delete serverfix</code>

生成自己對遠端庫版本做了哪些修改的摘要 <code>$ git request-pull origin/master myfork</code>

隻是建立一個新分支并不切換過去 <code>$ git branch testing</code>

通過檢視曆史版本的資訊,知道各個分支目前所指的版本對象 <code>$ git log --oneline --decorate</code>

切換到另一個分支 <code>$ git checkout testing</code> (這條指令做了兩件事,一是使 head 指向 testing 分支,二是将工作目錄恢複成 testing 分支所指向的快照内容)

檢視項目分叉曆史,以便知道分支的共同父節點 <code>$ git log --oneline --decorate --graph --all</code>

建立一個分支并同時切換到那個分支 <code>$ git checkout -b new-branch-name</code>

相當于下面兩個指令:

<code>$ git branch new-branch-name</code>

<code>$ git checkout new-branch-name</code>

假如目前分支是master,有一個包含最新修改的hotfix分支需要合并過來,使用 <code>$ git merge hotfix</code>

假設已完成了上面的第6個操作,hotfix分支已經沒用了,需要删除hotfix分支 <code>$ git branch -d hotfix</code>

合并分支時發生沖突的解決方法:

a、先檢視哪些檔案沖突了 <code>$ git status</code> (會出現unmerged paths)

b、手工打開這些檔案,修改裡面的代碼,并删除 &lt;&lt;&lt;&lt;&lt;&lt;&lt; , ======= , 和 &gt;&gt;&gt;&gt;&gt;&gt;&gt;

c、把修改好的檔案全都添加到暫存區 <code>$ git add filename</code>

d、改完所有沖突的檔案并都添加到暫存區後送出它們即可 <code>$ git commit</code>

檢視目前庫所有分支的清單 <code>$ git branch</code> (前面有*星号的是目前工作的分支)

檢視每一個分支的最後一次送出 <code>$ git branch -v</code>

檢視哪些分支已經合并到目前分支 <code>$ git branch --merged</code> (未打*星号的分支都是已并入的,已經沒用了,可以删除掉)

檢視所有包含未合并工作的分支 <code>$ git branch --no-merged</code>

強制删除一個未合并工作的分支 <code>$ git branch -d unmerged-branch-name</code>

合并(merge)和變基(rebase)的差別:合并會保留曆史分叉資訊,變基會把一個分支上的變化應用到另一個分支上,去掉了分叉

fix分支變基到master:把fix分支上的修改應用到master上,再把fix和master合并,最後隻保留master,删除fix

a、先切換到fix分支 <code>$ git checkout fix</code>

b、變基到master分支上 <code>$ git rebase master</code> 或者 <code>$ git rebase master fix</code>

c、切換到master分支 <code>$ git checkout master</code>

d、把fix合并到master上 <code>$ git merge fix</code>

e、删除fix分支 <code>$ git branch -d fix</code>

變基的使用注意事項:如果版本分叉曆史已送出到了遠端庫,切勿再在本地用變基的方法抹平這些分叉

基于master分支建立帶命名空間的分支 <code>$ git branch sc/branchname master</code> (其中sc是貢獻該項工作的人名稱的簡寫)

檢視送出曆史 <code>$ git log</code>

隻檢視最近2次送出曆史 <code>$ git log -2</code>

檢視最近1次送出和上一版本的内容差異 <code>$ git log -p -1</code>

檢視送出曆史的簡略統計資訊 <code>$ git log --stat -3</code>

格式化輸出送出曆史 <code>$ git log --pretty=format:"%h - %an, %ad : %s"</code>

形象化展示送出曆史 <code>$ git log --pretty=format:"%h %s" --graph</code> (如果曆史記錄有分支會看得更清楚)

顯示某一特定日期前的送出曆史 <code>$ git log --since=2009-01-15</code>

檢視對某關鍵字進行了修改操作的送出曆史 <code>$ git log -skeyword</code>

檢視送出曆史中,2008年10月期間,tom送出的但未合并的測試檔案,可以用下面的查詢指令:

<code>$ git log --pretty="%h - %s" --author=tom --since="2008-10-01" --before="2008-11-01" --no-merges</code>

隻顯示所有origin/master分支,但不在issue54分支的送出 <code>$ git log --no-merges issue54..origin/master</code>

檢視最後一次送出的詳細資訊 <code>$ git log --pretty=fuller -1</code>

在目前工作沒做完時,需要轉到master分支改bug,但不想送出現在的工作,可以用儲藏 <code>$ git stash save "work in progress"</code>

bug改完送出後,切換回先前的分支,然後繼續先前的工作 <code>$ git stash apply</code>

檢視儲藏隊列清單 <code>$ git stash list</code>

删除指定的儲藏 <code>$ git stash drop stash@{0}</code>

清空儲藏隊列 <code>$ git stash clear</code>

應用指定的儲藏 <code>$ git stash apply stash@{1}</code>

應用最近的儲藏并且應用後就删除它 <code>$ git stash pop</code>

建立一個分支來應用儲藏 <code>$ git stash branch new-branch-name</code>

看看目前工作目錄中可删除的未跟蹤檔案和空目錄有哪些(-n表示隻看看,但不執行) <code>$ git clean -d -n</code>

把上面列出的未跟蹤檔案和空目錄删除掉 <code>$ git clean -f -d</code>

隻移除沒有加入到.gitiignore的未跟蹤檔案 <code>$ git clean</code>

使用-x參數将加入到.gitiignore的檔案也删除 <code>$ git clean -d -x</code>

先fork官方項目

把項目克隆到本地 <code>$ git clone https://github.com/smallezcom/blink</code>

進入項目目錄 <code>$ cd blink</code>

建立一個分支用做開發新功能 <code>$ git checkout -b slow-blink</code>

在分支上做修改

改完之後送出到本地庫 <code>$ git commit -a -m 'comment'</code>

推送自己的slow-blink分支到遠端庫的slow-blink分支 <code>$ git push -u origin slow-blink</code>

在github網站上浏覽分支頁面,點選“compare &amp; pull request”按鈕進入建立合并請求的頁面

輸入标題和描述,讓項目的官方人員考慮接受自己的修改

寫完上面的标題和描述後,點選“create pull request”,項目的官方人員會收到自己的合并請求

項目官方人員會在github上審查你代碼,并可以線上單擊某一行代碼進行評論

官方人員的評論會通過電子郵件通知到自己

官方人員如果最終同意合并,他可以點選頁面上的“merge pull request”按鈕來合并,或者把貢獻者的分支拉取到本地合并後,再推送到github

如果自己送出的合并請求與現在官方的版本産生沖突怎麼辦?

a、用另外一個簡寫名把官方庫的連結再添加一次到本地 <code>$ git remote add blink2 https://github.com/smallezcom/blink</code>

b、把新命名的遠端庫再抓取一遍到本地 <code>$ git fetch blink2</code>

c、確定目前是在自己想送出到官方的分支上,然後嘗試把新抓取的官方版本合并過來 <code>$ git merge blink2/master</code>

d、上面的輸出資訊會告知你哪些檔案存在沖突

e、手工修改這些沖突的檔案,然後送出到本地庫

f、把自己想送出到官方的分支再次推送到官方遠端庫 <code>$ git push origin slow-blink</code>

用 git ci 代替 git commit 的方法 <code>$ git config --global alias.ci commit</code>

以後送出檔案可以這樣輸入 <code>$ git ci -m 'your comment'</code>

用 git last 代替 git log -1 head 的方法 <code>$ git config --global alias.last 'log -1 head'</code>

以後檢視最後一次送出可以這樣輸入 <code>$ git last</code>

建立忽略檔案.gitignore <code>$ cat .gitignore</code>

在檔案中加入想忽略的檔案路徑或比對模式

<code>*.a</code> 表示忽略以 .a 結尾的檔案

<code>*.[oa]</code> 表示忽略所有以 .o 或 .a 結尾的檔案

<code>*~</code> 表示忽略所有以波浪符 ~ 結尾的檔案

<code>!lib.a</code> 表示不忽略lib.a,(即使前面忽略了所有以 .a 結尾的檔案,也不能忽略lib.a)

<code>/todo</code> 隻忽略目前目錄下的todo檔案,不包含子目錄下的todo檔案

<code>build/</code> 忽略build/目錄下的所有檔案

<code>doc/*.txt</code> 忽略諸如 doc/notes.txt 這樣的檔案,但不忽略 doc/server/arch.txt

<code>doc/**/*.pdf</code> 忽略 doc/test.pdf、doc/other/test.pdf 等檔案,兩個星号**表示比對任意中間目錄<code>`</code>

忽略檔案.gitignore本身也要加入到暫存區以便送出到倉庫 <code>$ git add .gitignore</code>

伺服器上的遠端庫通常隻是一個裸倉庫(bare repository)— 即一個沒有工作目錄的倉庫

git可使用四種協定來傳輸資料:本地協定(local),http 協定,ssh(secure shell)協定及 git 協定

本地協定範例 <code>$ git clone /opt/git/project.git</code> 或 <code>$ git clone file:///opt/git/project.git</code>

http協定範例 <code>$ git clone https://smallez.com/gitproject.git</code>

ssh 協定範例 <code>$ git clone ssh://user@server/project.git</code> 或 <code>$ git clone user@server:project.git</code>

git 協定範例 <code>$ git clone git://192.168.10.2/project.git</code>

從一個git庫建立它的裸倉庫方法:

a、假如git庫的目錄名是test,需要進入到它的上一級目錄

b、使用--bare參數克隆test庫的裸倉庫 <code>$ git clone --bare test test.git</code>

c、用ls指令檢視一下,建立的test.git目錄就是裸倉庫

把裸倉庫拷貝到伺服器上就可以用ssh協定來通路這個遠端庫了,例如 <code>$ git clone [email protected]:/path/test.git</code>

從一個空目錄建立裸倉庫,并賦予此目錄的“組可寫”權限:先 <code>cd newdir</code> 然後在newdir目錄裡面 <code>$ git init --bare --shared</code>

修改git使用者的shell工具,以保證伺服器安全性:

a、編輯檔案 <code>$ sudo vim /etc/shells</code>

b、在/etc/shells檔案中把shell工具的絕對路徑加進去 /usr/bin/git-shell (實際路徑請通過指令which git-shell得知)

c、使用chsh修改git使用者的shell工具 <code>$ sudo chsh git</code> (shell工具要寫絕對路徑)

添加要用git使用者登入ssh的公鑰:

a、先在git使用者主目錄下建立.ssh目錄 <code>$ mkdir .ssh &amp;&amp; chmod 700 .ssh</code>

b、建立存放使用者公鑰的檔案 <code>$ touch .ssh/authorized_keys &amp;&amp; chmod 600 .ssh/authorized_keys</code>

c、把使用者公鑰都儲存到authorized_keys裡面 <code>$ cat id_rsa.john.pub &gt;&gt; ~/.ssh/authorized_keys</code>

集中式工作流 (團隊共同維護一個公有遠端庫)

內建管理者工作流 (github的典型模式 --- 每個人都可以fork一個自己的庫,修改後通知官方維護者拉取更新)

司令官與副官工作流 (相當于分級别的內建管理者工作流)

把一個檔案添加到暫存區後未送出的情況下,又對此檔案做了修改,怎麼辦?

答:如果此時送出,放入到倉庫的檔案是前面添加該檔案到暫存區時刻的内容,并非最後修改完的内容,如果要在送出時,讓倉庫儲存最新的内容,隻要在送出前再 git add 此檔案即可。

如何生成本地電腦上的ssh公鑰和私鑰?

答:使用ssh-keygen指令即可,按提示輸入存儲路徑和密碼 <code>$ ssh-keygen</code>

假如自己維護着一個遠端庫,如何知道别人送出過來版本修改了哪些東西?

答:

a、先建立一個分支contrib <code>$ git checkout -b contrib</code>

b、在新分支上應用别人送出過來的更新檔,或把别人的送出抓取過來合并到該分支

c、用log指令檢視别人的送出曆史(排除master分支上的曆史) <code>$ git log contrib --not master</code>

d、接上面,如果要輸出完整的差異資訊 <code>$ git log contrib -p --not master</code>

e、找出contrib和master分支的共同祖先 <code>$ git merge-base contrib master</code>

f、顯示contrib分支和指定分支(比如sha-1校驗碼為36c7db)的差異 <code>$ git diff 36c7db</code>

g、找出contrib和master分支共同祖先,然後顯示contrib和這個祖先的差異 <code>$ git diff master...contrib</code> (相當于ef的簡化)

假如自己維護着一個遠端庫,對于别人送出過來的版本,隻想選擇裡面某一個送出來應用到master分支,怎麼辦?

答:使用cherry-pick揀選更改即可

a、通過上面第3裡面的abc步得知想要的送出為 e43a6fd3e94888d76779ad79fb568ed180e5fcdf

b、執行揀選 <code>$ git cherry-pick e43a6fd3e94888d76779ad79fb568ed180e5fcdf</code>

c、揀選之後,如果建立的分支不想要了,可以删除它

在本地建立了一個git庫,要把這個本地庫送出到遠端(如github)新建立的庫,出現no tracked branch configured for branch master 或 refusing to merge unrelated histories 錯誤,怎麼辦?

答:出現這個問題是因為兩個庫不同源造成的(因為是分别建立的),隻需要在本地先 pull 把遠端庫的檔案同步過來,然後再push即可, 但是pull的時候一定要加上 --allow-unrelated-histories 參數。

參考指令 <code>git pull origin master --allow-unrelated-histories</code> ,執行了這條指令後,就可以正常push了。