在这里解释一下git中HEAD和master的关系。
在Git里,主分支即master分支(git默认分支的名字是master)。HEAD严格来说不是指向提交,而是指向分支master,master指向提交的,HEAD指向当前所在分支。
git checkout -b dev
时,发现HEAD此时指向dev分支当你切换分支的时候,Git 会重置你的工作目录,使其看起来像回到了你在那个分支上最后一次提交的样子。里是引用
并且HEAD 指向当前分支并随之移动,HEAD指回master分支。
(图虽然和前面有点小差(把testing换成dev分支),但是就是这么个意思)
git merge
命令合并这两个分支git merge dev
命令。git branch -d dev
,只剩下master分支话不多说,开始实战吧,实战背景
假设你正在你的iss53分支上进行开发,然后接到一个紧急任务,需要建立一个新的分支来修复bug,修复完成后合并到master,再切回iss53继续工作
创建iss53分支并切换到iss53分支(注意:创建分支的基础是以当前分支为基础的)
$ git checkout -b iss53
Switched to a new branch 'dev'
git checkout
命令加上-b参数表示创建并切换,相当于以下两条命令:
$ git branch iss53
$ git checkout iss53
Switched to branch 'dev'
git branch
命令查看当前分支,前面带*的就是你现在在的分支
$ git branch
* iss53
master
git branch //查看本地分支
git branch -r //查看远程分支
git branch -a //查看本地和远程的所有分支
检出分支中“检出”二字,你可以简单的理解为切换分支
本质上,checkout操作是移动HEAD指针,将HEAD指针指向要切换到的分支的指针处。
$ vim index.txt
git stash
命令(关于stash命令将在下篇文章中详细介绍)$ git add index.txt
$ git commit -a -m 'added on [issue 53]'
$ git checkout master
Switched to branch 'master'
切换成功后在master分支上,此时的工作目录和你在开始iss53问题前一模一样
当你切换分支的时候,Git 会重置你的工作目录,使其看起来像回到了你在那个分支上最后一次提交的样子。
接下来你要修复这个紧急问题,来建立一个hotfix分支,在该分支上解决问题。
$ git checkout -b hotfix
Switched to a new branch 'hotfix'
$ vim index.html
$ git commit -a -m 'fixed the broken email address'
[hotfix 1fb7853] fixed the broken email address
1 file changed, 2 insertions(+)
现在你在hotfix分支上修改完成,并且运行正确,可以将hotfix分支合并回你的master分支了。
使用git merge
命令来达到上述目的
$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast-forward
index.html | 2 ++
1 file changed, 2 insertions(+)
由于你想要合并的分支 hotfix 所指向的提交 C4 是你所在的提交 C2 的直接后继, 因此 Git 会直接将指针向前移动。
换句话说,当你试图合并两个分支时, 如果顺着一个分支走下去能够到达另一个分支,那么 Git 在合并两者的时候, 只会简单的将指针向前推进(指针右移)。
因为这种情况下的合并操作没有需要解决的分歧——这就叫做 “快进(fast-forward)”。
然后切换回iss53来继续刚刚的问题。并做一些修改。现在已经成功运行iss53了。打算将hotfix分支合并到master分支上,检出你想合并入的分支,运行git merge
即可
$ git checkout iss53
Switched to branch "iss53"
$ vim index.txt
$ git commit -a -m 'finished the new footer [issue 53]'
[iss53 ad82d7a] finished the new footer [issue 53]
1 file changed, 1 insertion(+)
$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.
index.txt | 1 +
1 file changed, 1 insertion(+)
这和你之前合并 hotfix 分支的时候看起来有一点不一样。 在这种情况下,你的开发历史从一个更早的地方开始分叉开来(diverged)。
master 分支所在提交并不是 iss53 分支所在提交的直接祖先,Git 不得不做一些额外的工作。 出现这种情况的时候,Git 会使用两个分支的末端所指的快照(C4 和 C5)以及这两个分支的公共祖先(C2),做一个简单的三方合并。
$ git log --graph --pretty=oneline --abbrev-commit
当解决完紧急问题后,因为hotfix分支已经不再需要它了,那么就可以删除它了,使用git branch -d hotfix
命令来删除分支。
$ git branch -d hotfix
Deleted branch hotfix (3a0874c).
现在修改合并进来,也不再需要iss53分支了,那么也可以删除iss53这个分支了。
$ git branch -d iss53
人生不如意之事十之八九,假设你在iss53上同样修改了在hotfix上做了修改的文件index.txt
,关键它们对同一个部分做了不同的修改,这个时候就会产生合并冲突。
$ git merge iss53
Auto-merging index.txt
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
此时 Git 做了合并,但是没有自动地创建一个新的合并提交。 Git 会暂停下来,等待你去解决合并产生的冲突。
查看状态,查看冲突文件
$ git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
Unmerged paths:
(use "git add ..." to mark resolution)
both modified: index.txt
no changes added to commit (use "git add" and/or "git commit -a")
$ git cat index.txt
Git has a mutable index called stage.
Git tracks changes of files.
<<<<<<< HEAD
Creating a new branch is quick & simple.
=======
Creating a new branch is quick AND simple.
>>>>>>> feature1
Git用<<<<<<<,=======,>>>>>>>
标记出不同分支的内容
也就是你的 master 分支所在的位置,因为你在运行 merge 命令的时候已经检出到了这个分支)在这个区段的上半部分(======= 的上半部分),而 iss53 分支所指示的版本在 ======= 的下半部分。 为了解决冲突,你必须选择使用由 ======= 分割的两部分中的一个,或者你也可以自行合并这些内容。
我们修改如下后保存:
Creating a new branch is quick and simple.
修改完成后记得提交
$ git status //查看状态看冲突文件是否暂存
On branch master
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)
Changes to be committed:
modified: index.txt
$ git add index.txt
$ git commit -m "conflict fixed"
[master cf810e4] conflict fixed
工作完成
说到git 怎么能不介绍一下版本回退呢。改bug改着,分支合并着运行不了了,哪怕现在改的一些东西没有了,让我回到那个能运行的也好
reset简直就是救命稻草啊!
git reset
命令恢复到版本$ git reset --hard HEAD^
$ git reset --hard 3628164
版本号没必要写全,前几位就可以了,Git会自动去找。当然也不能只写前一两位,因为Git可能会找到多个版本号,就无法确定是哪一个了。
git log
命令查看版本号$ git log
commit cb926e7ea50ad11b8f9e909c05226233bf755030
Author: Michael Liao <[email protected]>
Date: Mon Aug 19 17:51:55 2013 +0800
到此,这篇文章就已经结束了,希望对大家git的学习有所帮助!