git 分支
git 中的分支,其实本质上仅仅是个指向 commit 对象的可变指针。git 会使用 master作为分支的默认名字。在若干次提交后,你其实已经有了一个指向后一次提交对象的master 分支,它在每次提交的时候都会自动向前移动
默认有一个master分支 主分支
[root@ci-node1 git_test]# git statu on branch master nothing to commit, working tree clean
master是我们的分支,这个分支总是指向最后一次提交,在master分支上
head 代表当前分支 ,这个head在哪个分支上,这个分支就是当前分支
[root@ci-node1 git_test]# git log --oneline --decorate ac31205 (head -> master) commit a 353666d a af5856a modify a 52e8981 rename a.txt to a cc8bd80 rename a to a.txt 73d7230 commit a
红色的地方 是master指向的最后一次commit,当前分支指向master
git可以有多个分支,但是操作的时候,只能同时在一个分支,在哪个分支这个分支就是当前分支,当前分支用head表示
创建新分支
我们可以使用 git branch 命令创建一个新的分支指针
// 创建分支 [root@ci-node1 git_test]# git branch testing you have new mail in /var/spool/mail/root //查看当前有多少个分支 *在哪里 代表当前分支在哪 [root@ci-node1 git_test]# git branch * master testing
这会在当前 commit 对象上新建一个分支指针
master分支和testing分支 都指向最后一个提交commit
[root@ci-node1 git_test]# git log --oneline --decorate ac31205 (head -> master, testing) commit a 353666d a af5856a modify a 52e8981 rename a.txt to a cc8bd80 rename a to a.txt 73d7230 commit a
git 保存着一个名为 head 的特别指针。在 git 中,它是一个指向你正在工作中的本地分支的指针(译注:将 head 想象为当前分支的别名。)。运行 git branch 命令,
仅仅是建立了一个新的分支,但不会自动切换到这个分支中去,所以在这个例子中,我们依然还在master 分支里工作
切换分支
要切换到其他分支,可以执行 git checkout 命令。我们现在转换到新建的 testing 分支:
[root@ci-node1 git_test]# git checkout testing switched to branch 'testing' [root@ci-node1 git_test]# git branch master * testing
这样 head 就指向了 testing 分支
查看分支
列出所有本地分支 git branch
[root@ci-node1 git_test]# git branch master * testing
切换到testing分支,我们在testing分支做些操作
分支合并
我们在前面的基本上,在 testing 分支创建新文件 test,然后做一次 commit
[root@ci-node1 git_test]# touch test
[root@ci-node1 git_test]# git add .
[root@ci-node1 git_test]# git commit -m "commit test on branch testing"
[testing 9892af9] commit test on branch testing
1 file changed, 0 insertions( ), 0 deletions(-)
create mode 100644 test
[root@ci-node1 git_test]# git status on branch testing nothing to commit, working tree clean [root@ci-node1 git_test]# ll total 4 -rw-r--r-- 1 root root 9 mar 15 18:14 a -rw-r--r-- 1 root root 0 mar 16 22:47 test
testing分支指向新的commit 当前分支是testing,master还是指向之前commit
[root@ci-node1 git_test]# git log --oneline --decorate 9892af9 (head -> testing) commit test on branch testing ac31205 (master) commit a 353666d a af5856a modify a 52e8981 rename a.txt to a cc8bd80 rename a to a.txt 73d7230 commit a
提交后的结果:
现在 testing 分支向前移动了一格,而 master 分支仍然指向原先 git checkout 时所在的 commit 对象。现在我们回到 master 分支看看
[root@ci-node1 git_test]# git checkout master switched to branch 'master' [root@ci-node1 git_test]# git branch * master testing [root@ci-node1 git_test]#
master分支和testing分支指向不同commit,他们内容不一样,在testing分支创建的test文件,在master分支是看不到的
[root@ci-node1 git_test]# ll total 4 -rw-r--r-- 1 root root 9 mar 15 18:14 a
结论:多人协作的时候,每个人对内容做修改时候,拉出来一个分支,各改各的,相互之间不影响
没有看到testing分支,master分支看不到后面。testing可以看到master分支
[root@ci-node1 git_test]# git log --oneline --decorate ac31205 (head -> master) commit a 353666d a af5856a modify a 52e8981 rename a.txt to a cc8bd80 rename a to a.txt 73d7230 commit a
刚才的操作我们其实做了两件事,第一把 head 指针移回到 master 分支,第二把工作目录中的文件换成了 master 分支所指向的快照的内容。也就是说,现在开始所做的改动,将始于本项目中一个较老的版本。它的主要作用是将 testing 分支里作出的修改暂时取消,
这样你就可以向另一个方向进行开发
在master分支上创建新文件 然后commit
[root@ci-node1 git_test]# touch master [root@ci-node1 git_test]# git add . [root@ci-node1 git_test]# git commit -m "commit master on branch master" [master 241209e] commit master on branch master 1 file changed, 0 insertions( ), 0 deletions(-) create mode 100644 master
[root@ci-node1 git_test]# git log --oneline --decorate 241209e (head -> master) commit master on branch master ac31205 commit a 353666d a af5856a modify a 52e8981 rename a.txt to a cc8bd80 rename a to a.txt 73d7230 commit a
现在我们的仓库提交历史产生了分叉,我们可以在不同分支之间来回切换,做修改相互不影响,也可以在适当的时机把他们合并到一起。
现在我们把 testing 分支的内容合并到master 分支上。
形成一个共同整体,主分支是master,其他分支都合并到主分支
//切换到 master 分支 [root@ci-node1 git_test]# git branch * master testing
//合并 testing 分支到 master,输入提示信息
按回车显示输入框 ,要输入备注信息,相当于commit命令 -m,记录下要干嘛的
[root@ci-node1 git_test]# git branch
* master
testing
[root@ci-node1 git_test]# git merge testing
merge branch 'testing'
# please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# lines starting with '#' will be ignored, and an empty message aborts
# the commit.
写完 vim wq保存
再看到 合并完成信息
[root@ci-node1 git_test]# git merge testing merge made by the 'recursive' strategy. test | 0 1 file changed, 0 insertions( ), 0 deletions(-) create mode 100644 test you have new mail in /var/spool/mail/roo
testing分支的test文件 合并到master分支,合并以后testing分支上的内容在master分支上有了
[root@ci-node1 git_test]# ll total 4 -rw-r--r-- 1 root root 9 mar 15 18:14 a -rw-r--r-- 1 root root 0 mar 18 00:18 master -rw-r--r-- 1 root root 0 mar 18 00:20 test [root@ci-node1 git_test]# git branch * master testing [root@ci-node1 git_test]#
当前分支在master分支上
通过查看 commit 信息我们可以看到,testing 分支做的那次 commit 已经合并到了 master 的 commit 日志中了,而且合并后重新生成了一次 commit
[root@ci-node1 git_test]# git log --oneline --decorate 3b06f44 (head -> master) merge branch 'testing' // master分支上做合并 testing分支合并到master分支 又做了一次提交 当前分支在master分支上 241209e commit master on branch master // master分支上做了提交 9892af9 (testing) commit test on branch testing // testing分支上做了提交 ac31205 commit a 353666d a af5856a modify a 52e8981 rename a.txt to a cc8bd80 rename a to a.txt 73d7230 commit a
合并之后testing分支 内容 没有动的,我们还可以切换到testing分支
[root@ci-node1 git_test]# git checkout testing switched to branch 'testing'
[root@ci-node1 git_test]# ll total 4 -rw-r--r-- 1 root root 9 mar 15 18:14 a -rw-r--r-- 1 root root 0 mar 18 00:20 test [root@ci-node1 git_test]#
[root@ci-node1 git_test]# git log --oneline --decorate 9892af9 (head -> testing) commit test on branch testing ac31205 commit a 353666d a af5856a modify a 52e8981 rename a.txt to a cc8bd80 rename a to a.txt 73d7230 commit a
还有一种情况
在两个分支对同一个文件做修改
有时候合并操作并不会如此顺利,如果在不同的分支中都修改同一个文件的同一部分,git 就无法干静地把两者合并了。
这时 git 做了合并,但没有提交,它会停下来等你解决冲突。要看看哪些文件在合并时发生冲突,我们使用 git status 查阅
我们master 分支和testing分支 都有一个a文件 ,我们对master,testing分支上的a文件做修改
a文件的内容
[root@ci-node1 git_test]# cat a test bbb
当前分支master分支:
追加master到a文件 提交commit
[root@ci-node1 git_test]# echo "master" >>a [root@ci-node1 git_test]# git add . [root@ci-node1 git_test]# git commit -m "modify a on master branch" [master 7fd08f1] modify a on master branch 1 file changed, 1 insertion( ) [root@ci-node1 git_test]# git log --oneline --decorate 7fd08f1 (head -> master) modify a on master branch 3b06f44 merge branch 'testing' 241209e commit master on branch master 9892af9 (testing) commit test on branch testing ac31205 commit a 353666d a af5856a modify a 52e8981 rename a.txt to a cc8bd80 rename a to a.txt 73d7230 commit a
当前分支在testing:
切换分支到testing
[root@ci-node1 git_test]# git checkout testing switched to branch 'testing' [root@ci-node1 git_test]# git branch master * testing [root@ci-node1 git_test]# cat a test bbb
追加test内容到a文件 并提交commit
[root@ci-node1 git_test]# echo "test" >>a [root@ci-node1 git_test]# git add . [root@ci-node1 git_test]# git commit -m "modify a on testing branch" [testing 1114bde] modify a on testing branch 1 file changed, 1 insertion( )
现在分别再master,testing分支上 修改a文件,并提交commit,
现在再把testing分支 合并到master分支上
切换到master分支
[root@ci-node1 git_test]# git checkout master switched to branch 'master'
操作合并命令,出现报错
[root@ci-node1 git_test]# git merge testing auto-merging a conflict (content): merge conflict in a automatic merge failed; fix conflicts and then commit the result.
看看工作区的状态 git status
在git merge 有冲突情况下,在执行 git merge时候是不成功的,执行失败的,把有冲突的文件里面相关的内容 标识在a文件
[root@ci-node1 git_test]# git status on branch master you have unmerged paths. (fix conflicts and run "git commit") (use "git merge --abort" to abort the merge) unmerged paths: (use "git add..." to mark resolution) both modified: a // 已经修改a no changes added to commit (use "git add" and/or "git commit -a")
有冲突,要自己手动解决冲突,必须要人工解决冲突,打开a文件
他把冲突部分都列出,
解决办法:自己去解决这个文件,把这个文件内容改到自己认为正确的内容
[root@ci-node1 git_test]# vim a test bbb // 上面是没冲突的内容 <<<<<<< head // 当前分支master 有master内容 master ======= test >>>>>>> testing // 当前分支testing 有test内容
文件正确内容,两个分支合并后的文件的正确内容,然后wq保存
test bbb master test
然后提交commit
[root@ci-node1 git_test]# git add . [root@ci-node1 git_test]# git commit -m "merge testing to master both modify a" [master cc7da0e] merge testing to master both modify a
在看看git log ,git status
[root@ci-node1 git_test]# git status on branch master nothing to commit, working tree clean [root@ci-node1 git_test]# git log --oneline --decorate cc7da0e (head -> master) merge testing to master both modify a // 当前分支是master 指向最后一次commit 1114bde (testing) modify a on testing branch // 在testing分支上改了a文件 7fd08f1 modify a on master branch // 在master分支上改了a文件 3b06f44 merge branch 'testing' 241209e commit master on branch master 9892af9 commit test on branch testing ac31205 commit a 353666d a af5856a modify a 52e8981 rename a.txt to a cc8bd80 rename a to a.txt 73d7230 commit a
有两种情况冲突:
1.没有冲突的合并,合并完做一次commit
2.有冲突,要自己解决文件冲突,然后自己再做一次commit
删除分支
分支合并完成后,即可以删除分支。
[root@ci-node1 git_test]# git branch -d testing deleted branch testing (was 1114bde).
再查看当前分支,只有master分支
[root@ci-node1 git_test]# git branch * master