上篇文章讲了单人单分支情况下的git基本操作,但是实际开发过程都是由多人共同开发一个项目,大家的代码都会合并到同一个仓库的同一分支下,然后将整个项目的代码放到编译系统进行编译,最终将编译出的镜像文件发布出来。
目录
一. 多人协作下的Git模型
如下图所示,假如有张三和李四两个人共同开发项目sampleproject,他们各自通过git clone命令将远程仓库sampleproject给同步到了自己的电脑中。
二. 远程仓库配置
除了仓库的owner外,要想让团队的其他成员也可以拥有该仓库的上传权限,需要将其他人添加到项目成员中。
如下图所示,点击“项目设置” —> “项目成员设置” —> “邀请用户”。邀请成功后,每个人就可以在自己的gitcode主页看到该项目。
当大家都把项目克隆下来后,大家的目录差不多都是下面这样:
注:团队所有成员都需要配置好各自的ssh密钥,否则在通过ssh克隆项目的时候就会出问题
三. 提交流程案例
1. 案例一:无冲突提交
1. 张三在1.txt中填入如下内容并进行了提交
2. 李四这时候也想在1.txt中添加自己的信息,于是
接下来李四就在1.txt中添加了自己的信息,并进行提交
查看分支图,可以看到张三和李四的提交
2. 案例二:有冲突提交(不完美解决)
接着上面的案例继续,在李四提交完后,张三又想在1.txt中添加自己身高的信息,于是文件的内容如下:
紧接着进行了提交,但是发现在push的时候被远程仓库拒绝了。红框中已经解释了是因为远程仓库的master分支又有人(李四)提交东西了,但是我们本地还是上次我们的提交(也就是在1.txt添加第一行和第二行信息的那笔提交)
于是乎,张三又进行了下面的操作
合并失败,然后打开1.txt文件,看一下冲突的内容
没办法,这时候张三只能去找李四商量一下,到底应该怎么写,最后两个人商量后决定这么写:
经过上面手动merge后再次提交,成功
3. 案例三:有冲突提交(完美解决)
首先通过第四部分 - 1.回退远程版本库的master分支
讲述的方法恢复到案例二开始的状态,接下来演示一下完美提交方案,大体是四个步骤
======================< 1.创建本地工作分支work,修改目标文件并提交到本地work分支 >===================
sun@sun-pc:~/myProjects/codechina/sampleproject$ git branch work #创建工作分支work
sun@sun-pc:~/myProjects/codechina/sampleproject$ git checkout work #切换到工作分支work
切换到分支 'work'
sun@sun-pc:~/myProjects/codechina/sampleproject$ vi 1.txt #修改1.txt内容
sun@sun-pc:~/myProjects/codechina/sampleproject$ git add 1.txt
sun@sun-pc:~/myProjects/codechina/sampleproject$ git commit -m "modify zhangsan height in branch work" #提交到本地work分支
[work 1c4181a] modify zhangsan height in branch work
1 file changed, 1 insertion(+)
======================< 2.切换到master分支,拉取最新代码 >========================================
sun@sun-pc:~/myProjects/codechina/sampleproject$ git checkout master #重新切换到master分支
切换到分支 'master'
sun@sun-pc:~/myProjects/codechina/sampleproject$ git pull origin master #拉取服务器maser分支代码
来自 gitcode.net:In_engineer/sampleproject
* branch master -> FETCH_HEAD
更新 497d396..ce9f545
Fast-forward
1.txt | 2 ++
1 file changed, 2 insertions(+)
sun@sun-pc:~/myProjects/codechina/sampleproject$
======================< 3.切换到work分支进行rebase并进行冲突解决 >=================================
sun@sun-pc:~/myProjects/codechina/sampleproject$ git checkout work #再次切换到work分支
切换到分支 'work'
sun@sun-pc:~/myProjects/codechina/sampleproject$ git rebase master #将work分支rebase到master分支上
首先,回退分支以便在上面重放您的工作...
应用:modify zhangsan height in branch work
使用索引来重建一个(三方合并的)基础目录树...
M 1.txt
回落到基础版本上打补丁及进行三方合并...
自动合并 1.txt
冲突(内容):合并冲突于 1.txt
error: 无法合并变更。
打补丁失败于 0001 modify zhangsan height in branch work
用 'git am --show-current-patch' 命令查看失败的补丁
手工解决所有冲突,执行 "git add/rm <冲突的文件>" 标记
冲突已解决,然后执行 "git rebase --continue"。您也可以执行
"git rebase --skip" 命令跳过这个提交。如果想要终止执行并回到
"git rebase" 执行之前的状态,执行 "git rebase --abort"。
sun@sun-pc:~/myProjects/codechina/sampleproject$ vi 1.txt #上一步合并有冲突,所以手动修改(merge)文件
sun@sun-pc:~/myProjects/codechina/sampleproject$ git add 1.txt #因为前面rebase失败导致现在处于一个用于
#变基的临时分支,直接git add将修改加进暂存区
sun@sun-pc:~/myProjects/codechina/sampleproject$ git rebase --continue #使用continue选项继续前面的rebase
应用:modify zhangsan height in branch work #rebase成功
======================< 4.切换到master分支进行merge并提交到远程服务器 >===============================
sun@sun-pc:~/myProjects/codechina/sampleproject$ git checkout master
切换到分支 'master'
您的分支与上游分支 'origin/master' 一致。
sun@sun-pc:~/myProjects/codechina/sampleproject$ git merge work
更新 ce9f545..6a0f51d
Fast-forward
1.txt | 2 ++
1 file changed, 2 insertions(+)
sun@sun-pc:~/myProjects/codechina/sampleproject$ git push origin master
对象计数中: 3, 完成.
Delta compression using up to 16 threads.
压缩对象中: 100% (3/3), 完成.
写入对象中: 100% (3/3), 337 bytes | 337.00 KiB/s, 完成.
Total 3 (delta 0), reused 0 (delta 0)
To gitcode.net:In_engineer/sampleproject.git
ce9f545..6a0f51d master -> master
sun@sun-pc:~/myProjects/codechina/sampleproject
完事之后看到分支图还是一条直线,张三和李四所有的提交都可以看到,并且没有产生异常分支
注意:如果提交时使用git commit --amend
而不是git commit
,最好不要用案例三的方法。
四. 提交回退
1. 将本地仓库分支和远程仓库分支,回退到某次提交状态
接着案例二讲,张三和李四解决了冲突问题并提交了修改,还没等两个人高兴,看了一下分支图后又发现了一个新的问题。分支图居然分叉了,又新出现了一条绿色的分支,两个人立刻认识到这样提交可不行。目前项目结构还算简单,如果人数更多或者分支更多(真实开发过程中除了master分支依据实际情况还会建立:develop分支,bugfix分支,release分支,feature分支等)的话,如此的提交方式会让分支图惨不忍睹,估计大家都会疯掉
没办法,两人找前辈请教怎么弄比较好,前辈一看到这个分支图强迫症立刻就犯了,说怎么提交的问题先放一放,先把这个分支给回退到李四的第一笔提交,要不看着难受,于是操作了起来:
上gitcode平台查看分支图,发现已经回退到李四的第一笔提交
注:如果git push -f
被拒绝并提示没有权限,则需要给张三添加一下权限(项目设置->仓库->保护分支)
2. 回退特殊情况的提交
回退的主要依据是commit id,然而有些情况下通过git log查不到之前的commit id。例如通过git commit --amend
的提交,新的commit id会覆盖之前的。怎么办呢?这个时候可以通过索引记录进行查询之前的commit id,见下面讲解
1. 使用git reflog
查询操作的索引记录,如下图所示,其中小括号里有分支名的索引id就是commit id的前7位,同样可以用于git reset。当前所在索引id为5042372(②处),找到想回退到的地方(①处,索引id为51054e4)
2. 使用git reset
回退到第一次提交的状态
# 如果不加--hard,那么工作区的更改会被保留
git reset --hard 51054e4