給 Git 中級使用者的 25 個小貼士
Andy Jeffries 給 Git 中級使用者總結分享的 25 個小貼士。你不需要去做大量搜尋,或許這些小貼士對你就很有幫助的。
作為一個很享受git的人,我想要分享從各種社群學到的實用經驗,讓大家不需要花費過多的功夫就能找到答案。
基本技巧
1.安裝後的第一步
安裝git後,第一件事你需要設定你的名字和郵箱,因為每次提交都需要這些資訊。
Shell12 | $git config--global user.name"Some One"$git config--global user.email"[email protected]" |
2.是基於指標的
git上的所有東西都是儲存在檔案裡的,當你建立一次提交時,它會建立一個包含你的提交資訊和相關資料(名字,郵箱,日期/時間、上一次提交等等)的檔案並連線一個樹檔案,而這個樹檔案包含了物件列表或者其他樹。這上面的物件或者blob檔案就是這次提交的實際內容(你可以認為這也是一個檔案,儘管並沒有儲存在物件裡而是儲存在樹中)。所有的檔案都以經過SHA-1計算後的檔名(譯者注:經過SHA-1計算後的數,即git中的版本號)儲存在上面。
從這裡可以看出,分支和標籤都是包含一個指向這次提交的sha-1數(版本號)簡單的檔案,這樣使用引用會變得更快和更靈活,建立一個新的分支是就像建立檔案一樣簡單,SHA – 1數(版本號)也會引用你這個分支的提交。當然,如果你使用GIT命令列工具(或者GUI)你將無法接觸這些。但真的很簡單。
你可能聽說過HEAD引用,這是一個指向你當前提交的內容的SHA-1 數(版本號)的指標。如果你正在解決合併衝突,使用HEAD不會對你的特定分支有任何改動只會指向你當前的分支。
所有分支的指標都儲存在 .git/refs/heads,HEAD指標儲存在.git/HEAD,標籤則儲存在 .git/refs/tags,有時間就去看看吧。
3. 兩個母體(Parent),當然!
當我們在日誌檔案中檢視合併提交資訊,你會看到兩個母體,第一個母體是正在進行的分支,第二個是你要合併的分支。
4.合併衝突
現在,我發現有合併衝突並解決了它,這是一件在我們編輯檔案時很正常的事。將 <<<<, ====, >>>> 這些標記移除後,並儲存你想要儲存的程式碼。有些時候在程式碼被直接替代之前,能看到衝突是件挺不錯的事。比如在兩個衝突的分支變動之前,可以用這樣的命令方式:
Shell123456789101112131415 | $git diff--mergediff--cc dummy.rbindex5175dde,0c65895..4a00477---a/dummy.rb+++b/dummy.rb@@@-1,5-1,5+1,5@@@classMyFoodef say-puts"Bonjour"-puts"Hello world"++puts"Annyong Haseyo"endendIfthe fileisbinary,diffing files isn’tso easy…Whatyou’ll normally want todoistotryeachversion of the binary fileanddecide which one touse(ormanually copy portions over inthe binary file’seditor).Topullacopy of the filefromaparticular branch(say you’re merging master andfeature132): |
如果是二進位制檔案(binary),區別這些檔案並不容易。通常你會檢視每個二進位制檔案的版本,再決定使用哪個(或者在二進位制檔案編輯器中手動複製),並將其推送至特定的分支。(比如你要合併master和feature132)
Shell123456 | $git checkout master flash/foo.fla# or...$git checkout feature132 flash/foo.fla$# Then...$git add flash/foo.flaAnother way istocatthe filefrom git–you can dothistoanother filename thencopy the correct fileover(when you’ve decided which it is)tothe normal filename: |
另一個方法就是在git中cat檔案,你可以將其命名為另一個檔名,然後將你決定的那個檔案改為正確的檔名:
Shell12345678 | $git show master:flash/foo.fla>master-foo.fla$git show feature132:flash/foo.fla>feature132-foo.fla$# Check out master-foo.fla and feature132-foo.fla$# Let's say we decide that feature132's is correct$rmflash/foo.fla$mvfeature132-foo.flaflash/foo.fla$rmmaster-foo.fla$git add flash/foo.fla |
更新:感謝carls在原博評論中提醒我,可以使用 “git checkout —ours flash/foo.fla” 和“git checkout —theirs flash/foo.fla” 在不用考慮你需要合併的分支來檢查指定版本,就我個人而言,我喜歡更明確的方法,但這也是一個選擇…
記住,解決完合併衝突後要新增檔案。(我之前就犯過這樣的錯誤)
服務,分支和標註
5. 遠端服務
Git有一個非常強大的特性,就是可以有多個遠端服務端(以及你執行的一個本地倉庫)。你不需要總是進行訪問,你可以有多個服務端並能從其中一個(合併工作)讀取再寫入另一個。新增一個遠端服務端很簡單:
Shell123 | $git remote add john git@github.com:johnsomeone/someproject.gitIfyou want tosee information about your remote servers you can do: |
如果你想檢視遠端服務端的資訊你可以:
1234567 | # shows URLs of each remote server$git remote-v# gives more details about each$git remote show name You can always see the differences betweenalocal branch andaremote branch: |
你總是能看到本地分支和遠端分支不同的地方:
Shell123 | $git diffmaster..john/masterYou can also see the changes on HEADthat aren’ton that remote branch: |
你同樣也能看到遠端分支上沒有的HEAD指標的改動:
Shell12 | $git log remote/branch..# Note: no final refspec after .. |
6. Tagging 標籤
在Git中有兩種型別的標註:輕量級標註和註釋型標註。
記住第二個是Git的指標基礎,兩者區別很簡單,輕量級標註是簡單命名提交的指標,你可以將其指向另一個提交。註釋型標註是一個有資訊和歷史並指向標註物件的名字指標,它有著自己的資訊,如果需要的話,可以進行GPG標記。
建立兩種型別的標籤很簡單(其中一個命令列有改動)
Shell12 | $git tag to-be-tested$git tag-av1.1.0# Prompts for a tag message |
7. Creating Branches 建立分支
在git中建立分支是件非常簡單的事情(非常快並只需要不到100byte的檔案大小)。建立新分支並切換到該分支,通常是下面這樣的:
12 | $git branch feature132$git checkout feature132 |
當然,如果你想切換到該分支,最直接的方式是使用這樣一條命令:
1 | $git checkout-bfeature132 |
如果你想要重新命名本地分支,也很簡單:
12 | $git checkout-btwitter-experiment feature132$git branch-dfeature132 |
更新:或者你(Brian Palmer在原博的評論中指出的)可以使用 -m來切換到“git branch”(就像Mike指出,如果你只需要一個特定的分支,就可以重新命名當前分支)
12 | $git branch-mtwitter-experiment$git branch-mfeature132 twitter-experiment |
8.合併分支
以後你可能回想合併你的變動,有兩種方式可以做到這一點:
JavaScript123 | $git checkout master$git merge feature83#Or...$git rebase feature83 |
merge和rebase的區別是,merge會嘗試解決改動並建立的新的提交來融合他們。rebase則是將從你最後一次從另一個分支分離之後的改動併入,並直接沿用另一個分支的head指標。儘管如此,在你往遠端伺服器上推送分支之前,不要使用rebase。這會讓你混亂。
如果你不能確定哪個分支(哪些需要合併,哪些需要移除)。這裡有兩個git分支切換方式來幫助你:
JavaScript12345 | #Shows branches that are all merged intoyour current branch$git branch--merged#Shows branches that are notmerged intoyour current branch$git branch--no-merged |
9.遠端分支
如果你想將本地分支放置遠端服務端,你可以用這條命令進行推送:
JavaScript12 | $git push origin twitter-experiment:refs/heads/twitter-experiment#Where origin isour server nameandtwitter-experiment isthe branch |
如果你想要從服務端刪除分支:
JavaScript1 | $git push origin:twitter-experiment |
如果你想要檢視遠端分支的狀態:
JavaScript1 | $git remote show origin |
這將列出那些曾經存在而現在不存在的遠端分支,這將幫助你輕易地刪除你本地多餘的分支。
JavaScript1 | $git remote prune |
最後,如果本地追蹤遠端分支,常用方式是:
JavaScript12 | $git branch--track myfeature origin/myfeature$git checkout myfeature |
儘管這樣,Git的新版本將啟動自動追蹤,如果你使用-b來checkout: