专栏名称: 安东尼_Anthony
今天看啥  ›  专栏  ›  安东尼_Anthony

Git 中的分支创建和冲突解决(命令行)

安东尼_Anthony  · 简书  ·  · 2018-01-12 23:13

注:文章图片和部分内容来自廖雪峰的git教程,鼎力推荐!!!学习交流所用 传送门

git的分支操作

可以通过https://github.com/CameloeAnthony/GitTest 进行操作练习,首先在命令行,将远程仓库(github上的项目)clone到本地.

$ git clone https://github.com/CameloeAnthony/GitTest.git
1 查看远程分支(git branch -a)

这里可以看到我本地和远程分支如下:(前面带*号的代表你当前工作目录所处的分支)

$ git branch -a
  dev-activity
  dev-app
  develop
*  master
  test
  remotes/origin/HEAD -> origin/master
  remotes/origin/dev-activity
  remotes/origin/dev-app
  remotes/origin/develop
  remotes/origin/master
  remotes/origin/test
  remotes/origin/mydev
2 查看本地分支(git branch)

这是目前在我本地的分支, 工作目录分支在master分支:

$ git branch
  dev-activity
  dev-app
  develop
* master
  test
3 切换分支(git checkout 分支名)

比如这里切换mydev分支,本地没有,会"自动获取"远程分支

$ git checkout mydev
Switched to branch 'mydev'
Your branch is up-to-date with 'origin/mydev'.

再次查看分支,已经切换到mydev了

$  git branch
  dev-activity
  dev-app
  develop
  master
  test
* mydev

可以在github上看到分支情况


这里获取一个远程没有的分支, 这里会找不到

$ git checkout develop01
error: pathspec 'develop01' did not match any file(s) known to git.

是因为远程仓库没有嘛? 我在github(远程仓库)创建了一个branchCreateRemote,然后我再次尝试切换到远程分支,同样会找不到

$ git checkout branchCreateRemote
error: pathspec 'branchCreateRemote' did not match any file(s) known to git.

这是因为git在获取远程仓库(github)上的分支的时候(第一次clone到本地的时候),是把分支信息也一次性clone到了本地,而不是每次checkout的时候去请求的。问题迎刃而解 git
pull 再次把远程信息获取过来,现在可以checkout到新分支了。

$ git pull
From https://github.com/CameloeAnthony/GitTest
 * [new branch]      branchCreateRemote -> origin/branchCreateRemote
Already up-to-date.
4 在本地创建分支(git branch 分支名)
$  git branch test01  

当然我们也可以加上-b

$ git checkout -b test01
Switched to a new branch 'test01'

git checkout命令加上-b参数表示创建并切换,相当于以下两条命令:

$ git branch test01
$ git checkout test01
Switched to branch 'test01'
5 把本地的分支推到远程仓库( git push origin 分支名)
$ git push origin test01
6 删除本地分支( git branch -d 分支名)

这里就把本地的test01分支删除了

$ git branch -d test01
Deleted branch test01 (was 641b395b).

如果你在test01上,就不能准确删除,需要先切换到其他分支,才能删除test01分支哦。

7 删除远程分支( git branch -r -d 分支名)

操作6中我们把本地的test01 分支删了,这里使用下面两种方法删除远程的test01

#第一种方法
$ git branch -r -d origin/test01
Deleted remote-tracking branch origin/test01 (was d8e6798).
#第二种方法
$ git push origin :branch-name  

8 修改并提交( git add 文件名, git commit -m "提交说明)

首先我们切换到develop分支进行开发,这里模拟更改,增加一行文字。



这个时候没有提交更新,是不能切换分支的

$  git checkout master
error: Your local changes to the following files would be overwritten by checkout:
    README.md
Please commit your changes or stash them before you switch branches.
Aborting

这里提交develop

$ git add README.md
$ git commit -m "branch test on develop branch"
[develop fd94b13] branch test on develop branch
1 file changed, 1 insertion(+)

这里再次尝试切换到master分支,提示我们当前分支超出master分支1次提交(这是因为我们在develop分支上还没有push到远程仓库),不过这里成功切换到了master。


在develop分支做更改
git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

这里我们直接对master 分支进行更改并提交:


$ git add README.md
git commit -m  "branch test on master branch"
[master 27f26f4] branch test on master branch
1 file changed, 2 insertions(+), 1 deletion(-)

这里我们切换回develop分支还是master分支,我们发现我们的修改都在。这里工作就完成了吗?当然不是 。
我在我们的远程仓库(github)上可以看到develop和master的内容并没有提交上去。(哈哈,这是我以前刚学git的一个错误,总是忘记push)


9 合并(git merge)并解决冲突

针对上面,我们对master和develop分支分别做了一次更改。但是都还没有push到远程仓库,但是这不会影响本地的合并。


分别做了一次更改,目前在master分支

现在,我们把develop分支的工作成果合并到master分支上(合并(git merge)命令用于合并指定分支到当前分支。):

$ git merge develop
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.

这里报错了,我们打开文件,可以清晰的看到我们master上和develop上的两个修改。



Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容,这里合并,解决冲突。


10 push到远程仓库(github)

我们在9中完成了冲突的修改,这里我们提交master分支。

$ git add README.md 
$ git commit -m "merge and fix conflicts in develop and master"
$ git push origin master
Counting objects: 12, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (12/12), 1.03 KiB | 526.00 KiB/s, done.
Total 12 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), done.
To https://github.com/CameloeAnthony/GitTest.git
   d8e6798..687157a  master -> master

可以看到这里Github已经收到了更新



develop分支同样没有提交到github,这里也进行同样的提交(因为我们在8中已经commit了,所以这里不需要commit操作)。

$ git push origin develop

成功提交。

11 查看分支合并图(用git log --graph命令可以看到分支合并图)

在8中,我们看到我们在master(蓝色)和develop(红色)上分别做了修改,如下图


分别做了一次更改,目前在master分支

然后我们在9,10中merge develop到了master,如下图


将develop分支合并到了master分支

所以我们通过git log --graph命令可以看到分支合并图(下图) 可以和上图对应理解。

12 git工作现场保存(git stash )

我们对develop分支再次做更改



然后切换到master分支的时候回收到下面的提示,意思说在切换的之前要么git commit提交 更改,要么使用git stash 保存工作现场。

$ git checkout master
error: Your local changes to the following files would be overwritten by checkout:
    README.md
Please commit your changes or stash them before you switch branches.
Aborting

执行git stash

$ git stash
Saved working directory and index state WIP on develop: fd94b13 branch test on develop branch

然后现在就可以切换到其他分支,并做更改了。修改回来之后我们回到develop分支。我们可以通过git status查看当前分支状态,工作区间很干净

$ git status
On branch develop
nothing to commit, working tree clean

通过 git stash list 查看我们存储的工作区间

$ git stash list
stash@{0}: WIP on develop: fd94b13 branch test on develop branch

工作现场还在,Git把stash内容存在某个地方了,但是需要恢复一下,有两个办法:

一是用git stash apply恢复,但是恢复后,stash内容并不删除,你需要用git stash drop来删除;

另一种方式是用git stash pop,恢复的同时把stash内容也删了:

$ git stash pop
On branch develop
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   README.md

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (ae4c714f9643327a2739b3a323d0786fcb936756)

再用git stash list查看,就看不到任何stash内容了:

$ git stash list

可以多次stash,恢复的时候,先用git stash list查看,然后恢复指定的stash,用命令:

$ git stash apply stash@{0}

13 利用分支进行团队协作

13.1 几个工作环境

按照我这边的开发流程会分为这几个环境:
私人环境:比如我上面的mydev分支,是我开发的分支,然后开发好之后会将mydev的更改提交到开发环境(develop分支)。

开发环境:开发环境时程序猿们专门用于开发的服务器,配置可以比较随意,为了开发调试方便,一般打开全部错误报告和测试工具,是最基础的环境。开发环境的分支,比如我上面的develop分支。

测试环境:一般是克隆一份生产环境的配置,一个程序在测试环境工作不正常,那么肯定不能把它发布到生产服务器上,是开发环境到生产环境的过度环境。测试环境的分支一般是test分支,部署到公司私有的服务器或者局域网服务器上,主要用于测试是否存在bug,一般会不让用户和其他人看到,并且测试环境会尽量与生产环境相似。但是我们的项目按照客户要求,也会专门为内部客户配置测试环境。我在develop分支和别人的代码合并后会被推到test分支,公司会安排专门的人员进行test分支管理和合并测试。

生产环境: 生产环境是指正式提供对外服务的,一般会关掉错误报告,打开错误日志,是最重要的环境。部署分支一般为master分支。在test分支确认无误后会推到master分支。

三个环境也可以说是系统开发的三个阶段:开发->测试->上线,其中生产环境也就是通产说的真实的环境,最后交给用户的环境。

13.2 分支管理

在实际开发中,我们应该按照几个基本原则进行分支管理:

首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;

那在哪干活呢?每个人分别在自己的分支是干活,比如我自己的mydev分支,然后提交到develop分支(dev分支),dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;

你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。

所以,团队合作的分支看起来就像这样:

图片来自廖雪峰博客,这里没有单独添加test分支
13.3 推送分支

推送分支,就是把该分支上的所有本地提交推送到远程库。推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支上:

$ git push origin master

如果要推送其他分支,比如develop,就改成:

$ git push origin develop

master分支是主分支,因此要时刻与远程同步;

dev分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步;

bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个bug;

feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。

13.4 多人工作模式

多人协作的工作模式通常是这样:

  • 首先,可以试图用git push origin branch-name推送自己的修改;

  • 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;

  • 如果合并有冲突,则解决冲突,并在本地提交;

  • 没有冲突或者解决掉冲突后,再用git push origin branch-name推送就能成功!

  • 如果git pull提示“no tracking information”,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream branch-name origin/branch-name。

这就是多人协作的工作模式,一旦熟悉了,就非常简单。

参考文档

http://blog.csdn.net/arkblue/article/details/9568249
廖雪峰的Git教程
软件开发环境-开发环境、测试环境、生产环境的区别




原文地址:访问原文地址
快照地址: 访问文章快照