Bootstrap

Git系列讲解(三):同一分支下多人协同开发

上篇文章讲了单人单分支情况下的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

五. 补充

1. 案例三流程的分支图解析

在这里插入图片描述

;