cherry-pick
cherry-pick隘世,就是下面ruby_client不想要整個分支松嘶,只想要e43a6念恍,那就櫻桃挑選
e43a6就可以犁功。
關(guān)于Branch
- Creating a New Branch,
只是創(chuàng)建啦testing branch晾蜘,并不切換到testing
$ git branch testing
- 查看branch歷史
會顯示所有它的commit,還會顯示哪個branch指向哪個commit邻眷,還有HEAD當前指向哪個branch眠屎。
$ git log --oneline --decorate
這個命令顯示branch歷史是圖形樣式的剔交。
$ git log --oneline --decorate --graph --all
- 切換branch
working tree里面文件都變成testing所指向那個commit指向的那個snapshot的樣子。
HEAD文件也從原來的branch變成指向testing branch
$ git checkout testing
- 新建并切換branch
該命令新建一個iss53 branch改衩,并且切換到該branch
$ git checkout -b iss53
//上面一句相當于下面兩句命令岖常。
$ git branch iss53
$ git checkout iss53
- 刪除分支
刪除名為hotfix的分支。
$ git branch -d hotfix
Deleted branch hotfix (3a0874c).
- 列出所有的branch
帶有*的是現(xiàn)在checkout的branch
$ git branch
iss53
* master
testing
顯示各個branch最后一次commit信息
git branch -v
iss53 93b412c fix javascript issue
* master 7a98805 Merge branch 'iss53'
testing 782fd34 add scott to the author list in the readmes
--merged
和--no-merged
兩個參數(shù)可以過濾branch
//顯示已經(jīng)merge到當前分支(master)的branch葫督,過濾其他的
$ git branch --merged
iss53
* master
//顯示沒有merge到當前分支的branch
$ git branch --no-merged
testing
//因為testing branch沒有merge到當前分支竭鞍,所以不能直接刪除
$ git branch -d testing
error: The branch 'testing' is not fully merged.
If you are sure you want to delete it, run 'git branch -D testing'.
關(guān)于remote branch
- remote branch是不能移動的板惑,它會自動根據(jù)服務器的branch進行移動。
- 查看remote branch的信息
git ls-remote [remote]
git remote show [remote]
- 克隆遠程倉庫
git clone //默認存儲到origin/master偎快,就是遠程服務默認名為origin
git clone -o booyah //該命令冯乘,使得倉庫存儲到booyah/master
- 從遠程倉庫獲取更新
- 從服務器獲取本地沒有的分支。
如果服務器有個新的分支叫serverfix
晒夹,本地沒有
git fetch origin會獲取更新裆馒,但我們不會有一個新的本地的serverfix
分支,只有一個origin/serverfix
遠程分支丐怯,而且還是不能修改的喷好。
- 從服務器獲取本地沒有的分支。
git fetch origin
把origin/serverfix
遠程分支合并當前所在的本地分支上
git merge origin/serverfix
也可以新建一個本地分支(serverfix),checkout這個origin/serverfix
遠程分支
$ git checkout -b serverfix origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'
下面三個命令做的是同樣的事情读跷。
// 正常命令梗搅,從origin/serverfix獲取并創(chuàng)建本地的serverfix分支。
$ git checkout -b serverfix origin/serverfix
// 上面操作太常用效览,所以git提供啦更簡單的命令
$ git checkout --track origin/serverfix
/*
下面這個命令无切,更加簡單,當本地不存在“serverfix”分支丐枉,
且遠程服務中订雾,有且只有一個與“serverfix”名字匹配的分支“
git就會自動創(chuàng)建本地分支。
*/
$ git checkout serverfix
- 設(shè)置本地分支的上游分支(就是本地對應遠程分支)
//-u 參數(shù)代表(upstrem branch)的縮寫
$ git branch -u origin/serverfix
- 從服務器獲取remote branch的更新矛洞,并合并到當前分支
假設(shè)洼哎,當前在master分支上,且master分支的(upstream branch)是 origin/master
$ git fetch origin
$ git fetch --all //這個命令代替上一個沼本,就會把所有遠程分支都更新噩峦。
//--------------------------------------------------
$ git merge origin/master
//下面兩句命令用@{u}和@{upstream}代替origin/master,比較方便
$ git merge @{u}
$ git merge @{upstream}
- git pull
$ git pull
//git pull == git fetch + git merge 一個命令其實就是兩個的結(jié)合
$ git fetch
$ git merge
- 刪除遠程服務器無用的branch
$ git push origin --delete serverfix
To https://github.com/schacon/simplegit
-[deleted] serverfix
- 添加新的遠程服務
git remote add teamone https://sss.github.com/sss/ss
- 推送更新到遠程服務
- 將遠程沒有的本地分支抽兆,推送到遠程服務器與別人共享
$ git push <remote> <branch>
$ git push origin serverfix
這里git會自動把serverfix
擴展成
refs/heads/serverfix:refs/heads/serverfix
识补,就是說把我本地的serverfix更新到遠程的serverfix分支中。
git push origin serverfix:serverfix //這種寫法也可以
git push origin serverfix:awesomebranch
//推送到遠程分支時辫红,分支名叫awesomebranch
- 查看本地branch與遠程branch的關(guān)系
輸出結(jié)果解釋:- iss53分支:追蹤origin/iss53凭涂,ahead 2表示本地有兩個commit未推送到遠程
- master分支:追蹤origin/master,是與遠程分支一致的最新版本
- serverfix分支:追蹤teamone/server-fix-good贴妻,遠程分支有一個commit為下載并merge到本地切油,本地有三個commit未推送到遠程。
- testing分支:是完全本地的分支名惩,不追蹤任何遠程分支澎胡。
$ git branch -vv
iss53 7e424c3 [origin/iss53: ahead 2] forgot the brackets
master 1ae2a45 [origin/master] deploying index fix
*serverfix f8674d9 [teamone/server-fix-good: ahead 3, behind 1] this should do it
testing 5ea463a trying something new
關(guān)于staging area
- 添加文件到staging area
$ git add README test.rb LICENSE
- 查看staging area的狀態(tài)
git status
關(guān)于commit
- 提交,直接輸入信息
$ git commit -m 'The initial commit of my project'
- 提交,打開編輯器輸入信息
$ git commit
- -a 選項攻谁,告訴git提交前稚伍,自動將修改回刪除的文件添加到staging area。
但是新增加的戚宦,git還沒有track的文件不會添加進去个曙。
$ git commit -a -m 'made a change'
關(guān)于git diff
- 檢查有沒有whitespace issues(不知道這是什么,先記下來吧)
在commit之前執(zhí)行該命令受楼。
git diff --check
關(guān)于merge
- 將一個branch合并到另一個
假設(shè)目前在hotfix上修復問題困檩,問題修復完成要合并到主分支
先切換到主分支master,然后git merge hotfix
$ git checkout master
$ git merge hotfix
- merge的兩種狀況
- Fast-forward
如圖一所示,hotfix對master中的緊急問題進行啦修復
修復完畢后那槽,要把hotfix合并到master中悼沿,那么這種情況下,git merge命令直接就把masterbranch移動到hotfix所在commit(就是c4)
命令執(zhí)行時會顯示骚灸,是Fast-forward
糟趾,因為這種情況的合并是簡單的移動啦master分支。合并后如圖二所示甚牲。
并且此時hotfix分支沒什么鳥用啦义郑,可以刪除掉。
- Merge made by the 'recursive' strategy.
第二種狀況丈钙,要合并的兩個分支已經(jīng)不再同一條線上非驮,從C2開始分裂成兩條線啦。如圖三所示雏赦。
如下的合并命令雖然跟之前的一樣劫笙,但結(jié)果發(fā)生的事情不一樣啦。
$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.
index.html | 1 +
1 file changed, 1 insertion(+)
這種合并星岗,會基于圖四所示的三個Commit(C2填大、C4、C5)俏橘,兩個是分支所指向的commit允华,一個是那兩個commit的共同祖先。
最終生成一個新的commit obejct,如圖五所示的C6寥掐。(Fast-forward類型的merge不產(chǎn)生新的commit)
C6叫做Merge commit靴寂,它有兩個parent(C4和C5),這就是Merge commit特殊的地方召耘。
合并完畢后百炬,如果iss53沒用啦,可以刪除掉怎茫。
Merge沖突的處理過程
下面merge命令執(zhí)行后收壕,顯示有沖突
$ git merge iss53
沖突后妓灌,Git就暫停啦merge commit的創(chuàng)建轨蛤,可以用下面命令看是哪些文件沖突蜜宪。
$ git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: index.html
no changes added to commit (use "git add" and/or "git commit -a")
有沖突的文件在Unmerged paths條目下列出。
結(jié)果中提示啦祥山,用git add命令來標記沖突文件問題已經(jīng)解決圃验。
下面是沖突文件中的沖突內(nèi)容的樣子,上下兩個分支名(HEAD缝呕、iss53)澳窑,(=======)上面屬于HEAD,(=======)下面屬于iss53供常。
<<<<<<< HEAD:index.html
=======
<div id="footer">
please contact us at support@github.com
</div>
>>>>>>> iss53:index.html
如果想用可視化工具來解決沖突摊聋,用下面的命令就行。
運行命令后輸出的文字中栈暇,提示啦可以使用的mergetools麻裁,在命令行中輸入想要用的工具,比如說輸入:kdiff3源祈,git就會打開那個工具來進行沖突修改煎源。
如果有多個沖突文件,如下面Merging列出啦:LICENSE和README香缺,會依次打開兩個沖突進行修改手销。
$ git mergetool
This message is displayed because 'merge.tool' is not configured.
See 'git mergetool --tool-help' or 'git help config' for more details.
'git mergetool' will now attempt to use one of the following tools:
meld opendiff kdiff3 tkdiff xxdiff tortoisemerge gvimdiff diffuse diffmerge ecmerge p4merge araxis bc codecompare emerge vimdiff
Merging:
LICENSE
README
當然也可以直接用vim來修改沖突文件。
vim README
沖突修改完畢后图张,使用git mergetool
命令锋拖,會自動將沖突文件add到staging area,而vim README
命令需要手動用git add
來將文件添加。
最后祸轮,提交就好啦姑隅。
git commit
關(guān)于rebase
-
最簡單的rebase
倉庫的狀態(tài)如圖一所示:
1.下載master分支時,只有C2倔撞,基于C2新建分支(experiment)分支讲仰,進行修改
2.然后別人對倉庫進行啦push,master更新到C3
4.我們可以使用rebase操作將experiment的修改應用到C3
$ git checkout experiment
$ git rebase master
兩行命令作啦啥痪蝇?
1.對比experiment分支所有commit相對于兩個分支的共同祖先(C2)的內(nèi)容區(qū)別鄙陡,將這些區(qū)別存儲到臨時文件中。
2.把當前分支(experiment)重新設(shè)定到rebase指定的分支(master)的commit(也就是C3)上躏啰,然后將臨時文件中存儲的內(nèi)容區(qū)別應用到C3上趁矾,產(chǎn)生C4'
3.最后experiment分支設(shè)定到C4'上。
4.其實rebase
相對于merge
的好處是给僵,減少歷史信息毫捣,如圖二详拙,在rebase操作后, 就變成啦一條線蔓同,C4就消失啦(不過其實C4的對象仍然有存著的饶辙,過一段時間運行GC才會刪除)
$ git checkout master
$ git merge experiment
最后就是合并啦,這次Merge屬于Fast-forward,Master直接往前移動一下就好啦斑粱。
-
更有趣一點的rebase
$ git rebase --onto master server client
將C8和C9的修改直接應用到master分支上弃揽。
結(jié)果如圖五所示,注意C3的內(nèi)容不會被應用到master上则北,只有C8和C9的修改會矿微。
$ git checkout master
$ git merge client
將client合并進master分支,fast-foward
git rebase [basebranch] [topicbranch]
$ git rebase master server
server分支在master上rebase
$ git checkout master
$ git merge server
$ git branch -d client
$ git branch -d server
- rebase會引發(fā)的問題與解決辦法
我們進行啦開發(fā)尚揣,產(chǎn)生C2 和 C3
我們進行啦Fetch快骗,得到C4娜庇、C5、C6滨巴,進行merge得到C7
別人強制覆蓋啦服務器的merge,改為rebase,產(chǎn)生C4'恭取,然后我們fetch下來
我們用啦git pull
耗跛,把C7與C4'合并得到C8,但是C4和C4'修改的內(nèi)容是重復的
解決辦法是
git pull --rebase //代替 git pull
//或者用
git fetch
git rebase teamone/master
得到結(jié)果攒发,所以說某些情況下發(fā)生這種事情调塌,確保團隊別的成員都用git pull --rebase,并且使用rebase的原則是never rebase anything you’ve pushed somewhere.