学习视频:http://edu.51cto.com/course/course_id-1838.html整理
Git学习—git分支
在git中branch就是一个文本,放了一个hash值;其中git branch命令会列出所有的branch
$ git branch * master $ git branch --list * master
创建branch命令就是git branch <branch_name>, 比如创建一个web分支
$ git branch web $ git branch
* master
web
可以看到web这个branch已经创建出来了,能用git branch命令列出来了。
从上面可以看到我们当前在*master这个branch, 如果我们切换到web这个branch,可以用命令git checkout web
$ git checkout web
Switched to branch ‘web‘
$ git branch --list
master
* web
可以看到web前面有个*号,代表web就是当前的branch.图解表示如下
如上图,其实web分支也是指向c这个commit对象的。验证下命令
进入./git/refs/heads文件夹下,可以看到web这个文件
通过命令
$ cat *
86a4a0ecd556382aac675869697e19b7dc3f37b7
86a4a0ecd556382aac675869697e19b7dc3f37b7
可以看到master文件和web文件内容都是相同的hash值,因此他们指向相同的commit对象,
$ git rev-parse web
86a4a0ecd556382aac675869697e19b7dc3f37b7
$ git rev-parse master
86a4a0ecd556382aac675869697e19b7dc3f37b7
通过上面的两命令也可以看出来。
但你通过命令
$ cat HEAD
ref: refs/heads/web
可以看出HEAD内容发生了变化,从原先head指向master改为指向了web分支,也就是上图变为了这个样子
$ git checkout master
Switched to branch ‘master‘
Your branch is up-to-date with ‘origin/master‘.
$ cat .git/HEAD
ref: refs/heads/master
$ git branch
* master
web
上面第一个命令是切换回master分支,后面两个证明了切换是成功的。
删除branch很简单:git branch -d web
$ git branch -d web
Deleted branch web (was 86a4a0e).
$ git branch
* master
~~~~
git checkout –b <branch> 命令可以创建一个branch分支,并且切换到这个分支,看下面的命令
$ git branch
* master
$ git checkout -b web
Switched to a new branch ‘web‘
$ git branch
master
* web
看到绿色web分支前面的*号了吧,这代表web分支被创建被切换到了这个分支。
在这个新分支中添加文件,并commit
$ echo "this is a java beginner project" > README.md
$ git status
On branch web
Untracked files:
(use "git add <file>..." to include in what will be committed)
README.md
nothing added to commit but untracked files present (use "git add" to track)
$ git add README.md
warning: LF will be replaced by CRLF in README.md.
The file will have its original line endings in your working directory.
$ git status
On branch web
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: README.md
然后尝试删除web分支
$ git branch -d web
error: The branch ‘web‘ is not fully merged.
If you are sure you want to delete it, run ‘git branch -D web‘.
看上面的提示就知道问题了吧,如果用-d删除一个分支,需要把这个分支合并;如果你想不合并删除,则要用-D参数
$ git merge web
Updating 86a4a0e..d1bc16f
Fast-forward
README.md | 2 ++
1 file changed, 2 insertions(+)
create mode 100644 README.md
$ git branch -d web
Deleted branch web (was d1bc16f).
上面的Fast-forward代表原先web分支父commit对象是master分支的的最近的 commit;如果web分支父commit对象不是master分支的的最近的 commit,则不是Fast-forward
3-way merge
上面的图是我根据录像介绍和自己的理解做的,比录像图在master和web分支分别多了一个commit, 在合并时候
1. 先把c和h做比较,然后生成一个patch
2. 把patch应用到e, 产生i这个commit对象,
3. master指针指向i这个对象
4. 如果指向git merge web和git branch –d web命令后,web分支被删除,
5. 并且f,g,h这些commit会被git的垃圾回收机制给销毁也被废弃掉了。
上面方法就是3-way merge
在我的实践中c的commit hash值是commit 971043d5f42cb3c917bfb1b75df9bedf91eef08a
我的web分支中h的commit hash值是commit e0da286c1621328a43dc1d5eaa7a57c28251f0d4
我的master分支中e的commit hash值commit 83424500c510ae68bbc25ee1e641f14e492bf132
$ git merge web
Auto-merging firstfile.txt
CONFLICT (content): Merge conflict in firstfile.txt
Automatic merge failed; fix conflicts and then commit the result.
我在merge时候,出现了merge冲突,需要手动解决,我就这样做了
$ 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: firstfile.txt
no changes added to commit (use "git add" and/or "git commit -a")
$ git add firstfile.txt
$ git commit -m "master branch: prompt merge conflict, so need to merge manually"
[master 8a63c46] master branch: prompt merge conflict, so need to merge manually
上面代表merge成功了,手动解决了。
$ git log
commit 8a63c46c7e757ec893c134542cb78fa4ee3d4f2f
Merge: 8342450 e0da286
通过上面log,可以看出commit i已经出现,并且他是合并commit e和commit h生产的,和我们上面的图就一致了
$ git branch -d web
Deleted branch web (was e0da286). //看括号的值,俨然就是web分支中的h commit hash值