玩轉git分支
原文 http://www.cnblogs.com/sunshine-anycall/p/4342520.html
搞個代碼的管理工具,居然不弄上分支啥的東西。這簡直太low了。尤其是在使用了傳說中得很牛X的Git的時候,尤其顯得low。拿著青龍偃月刀當燒火棍子使,關公知道了還不重反人間教育你!?
遠程分支
要說分支就一定要從分支產生的最遙遠的歷史談起。這一切開始于你用clone命令從遠端把代碼庫的代碼拉取到本地開始。這個時候,git自動把 這個遠端代碼庫命名為origin并自動創建一個origin/master分支。相對的在本地創建一個叫做master的本地分支。這個時候這兩個分支 的指針都是指向一個地方的(不同的push發生的時候,master的指針就會發生變化)。
要創建一個遠程分支是非常必要的。也非常的簡單。只需要先創建一個本地分支。
git branch 分支名 //如 git branch develop
這只是創建了一個叫做develop的分支。如果要使用這個分支,還需要切換到這個分支上:
git checkout 分支名 // 如 git checkout develop
還有一個更快的方式創建分支,并直接切換到這個分支上:
git checkout -b 分支名 // git checkout -b develop
一個命令就把上面的兩個命令干得事全部搞定了。
說了半天都是折騰在本地分支(local branch)了。沒有離題。遠程分支就是本地分支push到遠端以后生成的。也就是前面我們折騰出來的develop分支只要push到遠端服務器上就可以了。
git push origin 分支名 // git push origin develop
但是,你還需要給你建立起來的遠端的和本地的分支設定一個直接的聯系。這個時候就需要把你本地的分支變成一個tracking branch。Tracking branch就是一個和遠端的分支有直接聯系的本地分支。如果你在一個tracking branch里使用git pull命令,那么git自動檢測到從哪個代碼庫獲取代碼和哪個分支執行merge操作。創建tracking branch:
git checkout --track origin/分支名 // git checkout --track origin/develop
整個的命令是:
git checkout -b [本地分支名] [遠端代碼庫名稱]/[分支名] //這時會創建一個本地分支名和遠端分支名不一樣的分支
上面的是一個簡寫的版本。
下面是要給謹慎使用的命令,刪除遠端分支。
git push origin :分支名 // git push origin :develop
這個時候遠端分支就被刪除了。
日常工作
日常里使用Git的時候就是處理代碼的pull,push和merge以及在這個時候遇到的各種問題。
既然有了這么多分支。也許是兩個,但是使用Git創建分支的成本真的非常的低,所以有的時候可以是每一個大一點的issue就是一個分支。這時候就需要在多個分支之間切換:
git checkout [分支名稱] // git checkout develop
每天早晨一到公司首先要做的就是確保你在正確的分支上,然后從git repository上面把代碼弄下來。這就要用到pull:
git pull [遠端代碼庫名稱] [分支名稱] // git pull origin develop
如果你在前一天的晚上忘記push代碼或者有其他的人在你push之后push了代碼了。那么就會遇到:“沖突”。git會告訴你:
error: Your local changes to "你修改過的文件" would be overwritten by merge. Aborting.
Please commit your changes or stash them before you can merge.
這種情況是編輯文件的沖突
這樣的一個Aborting非常的郁悶。好的提示已經告訴我們該如何解決這個問題了。使用stash。
1. 使用stash命令把本地的代碼先存起來。
</p>
git stash
這時,你本地的修改已經暫時存起來了。使用命令:git stash list可以看到保存的信息。
2. 然后使用我們上面說到的pull命令拉取遠端庫的代碼。
</p>
git pull
3. 還原暫時保存的本地的修改
</p>
git stash pop stash@{0}
大象裝冰箱分的是三部。到這里我們的代碼還是沒有處理完畢的。真正的問題才浮出水面。ooxx這個時候就出現了。也就是在svn中常見 的<<<<<<< ======什么的就出現在了你的代碼里。手動的解決沖突吧。當你處理好這些沖突的代碼之后。
git add [沖突文件名]
然后commit,之后:
當把代碼同步的事情弄順了以后就應該考慮要把本地文件提交到遠端代碼庫了。
git push origin [本地分支名]:[遠端分支名]
當然如果你的本地分支名和遠端分支名是一樣的,那么就只需要git push origin [分支名稱]就可以了。
補充:
1. 有的時候即使你處理完成沖突之后再commit還是會有問題:
</p>
<p>
<br />
</p>
fatal: cannot do a partial commit during a merge.
這個時候:
git commit -i [沖突文件名]
來commit沖突的文件。
2. 這里你還會用到別的命令:
</p>
git status // 看看git里的狀態,是沖突的有哪些文件等
git show | head // 查看commit進去的是誰、日期等
3. 撤銷對某個文件的修改:
</p>
git checkout -- [文件名]
如果是文件的刪除沖突的話:
這個時候只要使用git rm [文件名]刪掉已經被刪掉的文件就可以了。
commit之后用git show | head命令查看結果。
合并分支
要合并那個分支,比如要把develop的分支合并到master上。那么:
1. 轉到master分支上:
</p>
git checkout master
2. 開始合并:
</p>
git merge develop
在這個命令執行之后就會把develop分支上的代碼都合并到master上了。
如果遇到任何沖突
git diff //查看是什么沖突
按照以上提到的解決沖突的方法解決沖突就可以。
撤銷一個合并
如果你發現你的本地代碼簡直是一團糟,需要回到合并之前的狀態:
git reset --hard HEAD
本地代碼回到合并之前的狀態。
或者,你已經把合并后的代碼提交,但還是想把它們撤銷:
git reset --hard ORIG_HEAD
但是這個命令某些情況下會很危險,尤其是在你已經把合并后的分支刪除之后再使用這個命令。。。
刪除不存在對應于遠程分支的本地分支
在刪除之前首先需要查看一下遠端代碼庫origin下得分支都是什么情況的:
$ git remote show origin* remote origin
Fetch URL: git@github.com:xxx/xxx.git
Push URL: git@github.com:xxx/xxx.git
HEAD branch: master
Remote branches:
master tracked
refs/remotes/origin/b1 stale (use 'git remote prune' to remove)
Local branch configured for 'git pull':
master merges with remote master
Local ref configured for 'git push':
master pushes to master (up to date)</pre>
<p> 這時候你會看到這個b1的分支還是stable的。使用git remote prune origin可以將其從本地代碼庫中去除。 </p> <p> 還有一個更簡單的方法:git fetch -p。會在fetch之后刪除沒有與遠程分支對應的本地分支。 </p> <h4> 重命名遠程分支 </h4> <p> 這個過程很墨跡。因為要先刪除遠程分支,然后重命名本地分支,然后再提交這個命名好的本地分支到遠程分支。 </p> <p> 現在有一個devel的分支,要把它重命名為develop。先用git branch -av命令查看分支的狀況。這里最重要是確定好了,你要刪除的不是默認分支!之后就可以刪除了: </p>
git push --delete origin develTo git@github.com:xxx/xxxxxxxx.git
- [deleted] devel</pre>
<p> 重命名本地分支: </p>
git branch -m devel develop推送本地分支到遠端:
$ git push origin developCounting objects: 92, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (48/48), done.
Writing objects: 100% (58/58), 1.38 MiB, done.
Total 58 (delta 34), reused 12 (delta 5)
To git@github.com:xxx/xxx-xxxxxx-x.git
* [new branch] develop -> develop</pre>
查看未推送
查看全部分支的已經commit但是沒有push的:
git log --branches --not --remotes查看全部分支的全部的最近的commit:
git log --branches --not --remotes --simplify-by-decoration --decorate --online查看某文件的歷史記錄:
git log my/file.c #全部歷史 git log -n 1 -- my/file.c #查看最近歷史修改常見錯誤處理
1. non-fast-forward </h4> <p> 如果有人比你先push代碼到你所在的分支了,那么git就不允許你再嵌入代碼到這代碼庫。 </p>
git push origin masterTo https://github.com/USERNAME/REPOSITORY.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to '
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again. See the
'Note about fast-forwards' section of 'git push --help' for details.</pre>
<p> 這時候使用fetch和merge的方法解決這個問題: </p> <p> fetch: </p>
git fetch origin [分支名稱]merge:
git merge origin [分支名稱]或者直接pull。pull命令同時執行了這兩個命令。
</div> </div>