如下內容爲轉載:linux
用Git 就是要愛用Branch 啊,Branch 很好用,開Branch 不用錢。開Branch 的情境除了在上一篇中提到因應產品release 需求的stable/production branch 以外,其餘開branch 狀況有:git
這些事情均可以先在本地開local branch 作,而不須要當即Push 分享給別人。github
web
git branch <new_branch_name>創建本地local branch
git branch -m <old_name> <new_name>更名字(若是有同名會失敗,改用-M能夠強制覆蓋)
git branch列出目前有那些branch以及目前在那個branch
git checkout <branch_name>切換branch (注意到若是你有檔案修改了卻還沒commit,會不能切換branch,解法稍後會談)
git checkout -b <new_branch_name> (<from_branch_name>)本地創建branch並當即checkout切換過去
git branch -d <branch_name>刪除local branch
開Branch 最大的好處除了能夠不影響stable 和其餘分支版本的開發,另外一個超棒的地方是」你能夠決定Merge 的方式」。Git 的Merge 方式能夠分紅四種:算法
其中rebase比較難理解在下一篇有圖解。app
svn
git merge <branch_name>合併另外一個branch,若沒有conflict衝突會直接commit。若須要解決衝突則會再多一個commit。
git merge --squash <branch_name>將另外一個branch的commit合併爲一筆,特別適合須要作實驗的fixes bug或new feature,最後只留結果。合併完不會幫你先commit。
git cherry-pick 321d76f只合並特定其中一個commit。若是要合併多個,能夠加上-n指令就不會先幫你commit,這樣能夠多pick幾個要合併的commit,最後再git commit便可。
使用merge 可能會有部分程式碼會conflict 衝突:簡單的狀況只要編輯檔案處理<<<< ===== >>>>> 便可,而後從新add 到staging area 並commit (沒有像SVN 的resolve指令)。複雜一點的能夠再用git mergetool 選檔案合併的GUI 工具(OS X 下面能夠用opendiff, linux 能夠用kdiff3 ),處理好後git commit。工具
一旦merge 好了,git branch -d <branch_name> 能夠刪除branch。但若是要刪除的branch 尚未合併,就會有錯誤訊息。若是真的要強制刪除能夠用-Dfetch
Git的working tree是從SVN換過來一個不習慣的地方,由於它只是一個工做暫存區,在切換Branch時就會整個換掉。也由於如此,若是有檔案有修改尚未commit出去,切換branch時就會出現error不能切換 (除非是新的untracking檔案),例若有修改還沒add會出現error: Entry 'ooxx' not uptodate. Cannot merge.有修改且已經add(還沒ci)會出現error: Entry 'ooxx' would be overwritten by merge. Cannot merge.spa
最理想的處理固然是事情恰好作到一個段落,把東西commit 出去才切換branch 作事。不過事情總有臨時,若是要換branch 的暫時的解決方式是使用git stash 會先把修改暫存下來,要回復則執行git stash pop。下一篇等你學會git reset 以後,你會發現就算把還沒完成的東西commit 也不會怎麼樣,只要還沒push 出去一切commit 紀錄都是能夠改的。
首先要認識的是Protocol,像在Github 上面看本身的Project,會有分Public Clone URL 跟Your Clone URL,這有什麼差?
其中Github 就是同時用SSH + Git protocol,兼顧認證需求及速度。
git clone <remote_address>
git checkout --track -b foobar origin/foobar將遠端的branch checkout回來並創建一個新的local branch,加上--track表示你以後還要pull、push回去,因此請Git記住對應關係。
git pull (<local_branch_name> origin/<remote_branch_name>)去遠端fetch新版並merge進local branch
git push將local branch的commit紀錄更新到遠端
git pull 要注意的是,若是別人在你上次pull 以後有push 新東西上去(也就是說跟你的branch 產生分岔了),此時有兩種狀況: 一是Git 能夠順利auto merge 的話, git 會自動多一次merge commit,這也就爲何經常log 會跑出Merge branch 'master' of git@foobar.com。二是若是有conflict,這時候就須要你手動處理而後commit。話說若是以爲這種local branch 和remote branch 的merge commit log 很煩,建議能夠改使用git pull –rebase 指令來變成fast-forward 形式(就會變得像svn up,而不會有merge commit log)。rebase 的意思可能要下一篇纔會詳細說明的清楚,簡單的說(?),就是先砍掉local branch 分岔點以後本身的commit,而後把遠端的commit 先一個個apply 進來,最後再把本身的commit 再apply 進去(若是有conflict 會中途停下來,等你修好纔會繼續apply),如此一來看線圖就會變成一條線而已,也就沒有所謂merge 這個動做了。
git push 預設的遠端是origin,而且會將全部有和remote 有對應的local branch 都push 上去。若是要把新的local branch push 上去,須要下git push origin <local_vranch_name> 指令。
git push 也可能會失敗,例如出現! [rejected] master -> master (non-fast forward),這個non-fast forward 的意思是你的parent commit 和遠端的不相同,也就是線圖有分岔,須要先pull 回來處理好merge 才能push 上去。
fast-forward 在Git 是一種merge 術語,當B branch (例如一個local branch) 是從A branch (例如一個remote branch) 的最新版(HEAD)分支出來的,那當A 要把B merge 進來時,由於B 的parent commit 是A 的HEAD,因此這兩個branch 惟一的差別就是B 後來的commit 而已,而不會有任何conflict。因此實際上的動做只要把A 的HEAD 改爲B 的HEAD 就行了,線圖上這兩個branch 根本是同一條線,此謂fast-forward。
其餘操做還有:
git fetch把遠端的branch更新下載回來,但不會merge到local branch
git branch -r顯示local有追蹤的遠端branch。注意到你不能直接修改這個remote branch,必定要用一個local branch對應它。
git remote show origin顯示遠端server的branch
git remote add foobar git://能夠新增別的repo.位置,因而pull的時候就能夠指定要從哪個遠端更新回來。
git push origin :foobar刪除遠端的branch
由於遠端的操做指令比較雜,因此也有人寫了git_remote_branch來簡化操做。