注:文章图片和部分内容来自廖雪峰的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上看到分支情况
![](https://img.haomeiwen.com/i1833901/3ad73d72cffe8755.png)
这里获取一个远程没有的分支, 这里会找不到
$ 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分支进行开发,这里模拟更改,增加一行文字。
![](https://img.haomeiwen.com/i1833901/6ffbe24bde91975a.png)
这个时候没有提交更新,是不能切换分支的
$ 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。
![](https://img.haomeiwen.com/i1833901/76c5133d86b3d093.png)
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 分支进行更改并提交:
![](https://img.haomeiwen.com/i1833901/16c7f603a2c39dee.png)
$ 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)
![](https://img.haomeiwen.com/i1833901/c53cc184034016d2.png)
9 合并(git merge)并解决冲突
针对上面,我们对master和develop分支分别做了一次更改。但是都还没有push到远程仓库,但是这不会影响本地的合并。
![](https://img.haomeiwen.com/i1833901/39edb453b8d253a7.png)
现在,我们把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上的两个修改。
![](https://img.haomeiwen.com/i1833901/6de8cedf4274538f.png)
Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容,这里合并,解决冲突。
![](https://img.haomeiwen.com/i1833901/d27fe6cdc8e63b82.png)
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已经收到了更新
![](https://img.haomeiwen.com/i1833901/6e95e09772ba4e36.png)
develop分支同样没有提交到github,这里也进行同样的提交(因为我们在8中已经commit了,所以这里不需要commit操作)。
$ git push origin develop
成功提交。
11 查看分支合并图(用git log --graph命令可以看到分支合并图)
在8中,我们看到我们在master(蓝色)和develop(红色)上分别做了修改,如下图
![](https://img.haomeiwen.com/i1833901/ab217d560955ce26.png)
然后我们在9,10中merge develop到了master,如下图
![](https://img.haomeiwen.com/i1833901/7f6fbe900f9986ff.png)
所以我们通过git log --graph命令可以看到分支合并图(下图) 可以和上图对应理解。
![](https://img.haomeiwen.com/i1833901/5fb964746d3d3c9d.png)
12 git工作现场保存(git stash )
我们对develop分支再次做更改
![](https://img.haomeiwen.com/i1833901/28d19b5426525750.png)
然后切换到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
分支上合并就可以了。
所以,团队合作的分支看起来就像这样:
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教程
软件开发环境-开发环境、测试环境、生产环境的区别
网友评论