【Git原理与使用】多人协作
多人协作
- 1.多人协作一
- 1.1准备工作
- 1.2协作开发
- 1.3将内容合并进master
- 2.多人协作二
- 2.1协作开发
- 2.3将内容合并进master
- 3.远程分支删除后,本地 git branch -a 依然能看到的解决办法
1.多人协作一
1.1准备工作
到目前为止对于Git提供给我们的大部分实用操作已经学的差不多了
- 基本完成 Git 的所有本地库的相关操作,git基本操作,分支理解,版本回退,冲突解决等等
- 申请码云账号,将远端信息clone到本地,以及推送和拉取
是时候干最重要的一件事情了,实现多人协作开发!
-
目标:远端master分支下file.txt文件新增代码 “aaa”、“bbb”
-
实现:由开发者1新增 “aaa”,由开发者2新增 “bbb”
-
条件:在一个分支下协作完成
当前我们在Linux环境下已经将远端仓库克隆到本地了可以充当开发者1,接下来我们在 windows 环境下,再 clone 同一个远端仓库,来充当开发者2。
条件是在一个分支下协作完成,这个分支肯定不是master分支,是我们自己要创建的分支,之前就说过master分支是一个稳定的分支,不要在master分支上直接修改。
重新创建一个分支是在远程创建还是本地创建都可以,下面我们都会用到。这里我现在远程创建分支在拉到本地。
现在我们画一下当前仓库的状态,当前远程仓库里有master分支和dev分支,本地仓库除了本地master分支还有远程仓库的master分支。
查看本地分支
git branch
查看远程分支
git branch -r
查看本地和远程分支
git branch -a
目前我们是看不到远端的dev分支,我们可以进行pull操作,之前我们拉取是
git pull origin [分支]
但是我们其实可以直接使用git push拉取相关内容
git push
发现远程仓库的dev分支被我们拉取了
为什么可以直接使用git pull就可以拉下来呢?
之前说的push和pull都是针对分支的操作,必须让两个分支建立连接才可以push和pull,克隆远端仓库会默认将远端master分支和本地master分支连接,之前我们
push使用的命令是 git push origin master ,对于push操作我们这里给它指定了远程仓库和远程分支,对于这种push操作其实不需要提前建立连接的。
当push使用的命令是 git push 才需要建立两个分支建立连接,有了这个连接push的时候Git才知道我们是从那个分支上push到那个分支。
同理对于pull也是一样的!
拉取成功后,对于开发者1就有了这么多东西,接下来还需要让开发者2也需要拥有同样的东西。
可以在windows任意目录下按下shift + 右键,找到PowerShell窗口。然后可以把远端仓库克隆到本地来
注意,我们这里是模拟了两个用户,实际开发中,每个用户都有自己的gitee/github账号,如果要多人进行协同开发,必须要将用户添加进开发者,用户才有权限进行代码提交:
1.2协作开发
现在我们先模拟开发者1要完成给远程master分支下file.txt文件新增代码 “aaa”。
目前本地分支只有master,远程不仅有master还有dev分支
之前说过我们必须在本地仓库进行操作然后在push到远程仓库的某一个分支下,因此我们不能直接切到远程dev分支下修改,并且我们也要维持本地master分支的稳定,因此我们可以创建出一个本地的dev分支。这里我们在学一个命令,我们可以创建出本地分支后远程分支连接起来。
git checkout -b [本地分支] origin/[远程分支]
查看本地分支和远程分支连接情况
git branch -vv
发现本地master和远程master建立起连接,本地dev和远程dev建立起连接。
建立连接的好处就是等会push的时候,可以直接使用git push命令,同样对于pull也是一样的。
然后我们就可以对file.txt进行修改,add,commit,最后push了。
可以看到远程仓库dev分支下file.txt已经有了aaa代码
接下来开发者2在file.txt文件新增bbb,也要完成相同的操作。
刚才开发者1在本地创建dev分支就和远程dev分支建立起了连接,这里开发者2先创建本地dev分支,不和远程dev分支建立起连接,我们看接下来去发生什么情况。
这里我们想直接使用git pull从远端拉取内容是失败的,因为当前分支没有追踪某些信息的。
那如何去追踪某些信息呢?
这里我们就要使用下面的命令,让本地的分支和远程的某个分支建立起连接
git branch --set-upstream-to=origin/[远程分支] [本地分支]
我们直接在记事本中添加,然后add,commit,push
这里我们push但是远程拒绝了我们的操作,这是因为当前的分支和远程的分支是有一些差异的。
差异在远程仓库dev分支它是有aaa,而开发者2的本地仓库dev分支是有bbb的,这两句代码都是在file.txt文件中存在的。在一个文件下并且在同一行此时它俩是有一个冲突的!所以Git拒绝了我们推送,Git并不知道是保持aaa还是bbb。Git不能帮我们解决我们需要人工手动去解决。
上面已经提示我们了,先使用git pull将远程仓库dev分支的内容先拉到本地进行冲突的解决,然后push到远程即可。
拉下来之后发现确实有冲突,如何解决冲突我们之前也说过了,改成自己想要的即可。
解决冲突之后然后在进行add,commit,push
在一次就推送成功了
最后一步就是将dev分支合并到master分支上
1.3将内容合并进master
目前远端仓库dev分支是有aaa和bbb的,master并没有,接下来就是将dev分支合并到master分支上。
对于merge操作是有两个选择可以执行的。
第一种方式是对于本地来说的,就是让本地的master 合并一下 dev分支,然后再将本地master分支push到远端master分支。
第二种方式是对于远端来说的,提交一个Pull Requests申请单,等管理员审批,如果同意之后就会帮我们合并。
我们推荐第二种方式!
这里我们先看第二种方式对于远端来说:
填写PR申请单的内容,就提交一下。等到管理员审批。审批通过,就可以帮我们合并了。
第一种方式对于本地来说,
目前本地仓库有dev分支和master分支,首先master分支先合并dev分支,然后push操作到远端master。
对于master分支合并dev分支之前我们就有一个建议,master直接合并dev可能会出现冲突,我们可以让dev分支先来合并master分支,有冲突我们可以在dev分支上解决,解决冲突后我们切换到master分支,在让master合并dev。但是这里还有一点要注意的是让dev合并master,如果本地master不是最新的,我们即使让master合并dev也不是最新的,然后将本地master分支push到远端master分支就有可能出现冲突,为了不影响远程master稳定性,我们在让dev合并master之前,先切换到master分支进行pull操作,然后再进行dev合并mastert,master合并dev,推送master。
这里我们让开发者1进行上述操作,但是开发者1本地dev分支上file.txt文件只有aaa没有bbb,因此我们还需要先pull操作拉取远端dev分支,然后在进行上述操作。不管对于开发者1还是开发者2来说都要先进行这一步。
切换到master分支,pull一下,让本地master是最新的代码
切换到dev合并master
切换到master合并dev
push操作
我们看到远程master分支确实看到了aaa,bbb代码
远端master分支已经合并了dev分支,dev分支就没用了,我们就可以把dev分支删除了。
总结一下,在同一分支下进行多人协作的工作模式通常是这样:
- 首先,可以试图用 git push origin branch-name 推送自己的修改;
- 如果推送失败,则因为远程分支比你的本地更新,需要先用 git pull 试图合并;
- 如果合并有冲突,则解决冲突,并在本地提交;
- 没有冲突或者解决掉冲突后,再用git push origin branch-name推送就能成功!
- 功能开发完毕,将分支 merge 进 master,最后删除分支。
在同一分支下进行多人协作的模式其实是不常见的,其实多人协作一般是在不同分支下去操作的。
2.多人协作二
- 目标:远程master分支下新增function1 和funcition2 文件
- 实现:由开发者1新增function1,由开发者2新增function2
- 条件:在不同分支下协作完成
2.1协作开发
这里和前面实现是大致一样的,唯一不同的是之前多人协作开发条件是在同一个分支下协作完成,这里的多人协作开发条件是在不同分支下协作完成的。什么意思呢?开发者1要新增function1那我们就给开发者1创建一个分支,在这个分支下开发者1新增function1。对于开发者2来说也同样创建一个分支,在这个分支下开发者2新增function2。所以就是各自让某一个功能私有某一个分支。
前面我们是在远程仓库创建好分支后拉取到本地,这里我们通过本地创建分支然后将本地分支推送到远程分支。不过我们最推荐的还是在远程创建好分支后拉取到本地,因为这样远程分支是基于远程master创建除了的,master是一个最新最全最稳定的,所以这样创建出来的分支也是最新最全最稳定的。本地创建分支并不能保证本地master是最新的代码。要保证本地master是最新要使用pull操作。
开发者1在本地创建feature1分支,新增function1功能。
这里我们不能直接使用git push,因为我们创建本地分支的时候并没有和远程分支建立起连接,这里我们可以使用下面命令进行推送。
git push origin [远程分支]
可以看到推送成功,并且远程新建一个分支feature1
对于开发者1来说它完成了自己的工作,并且将featrue1推送到远端
对于开发者2来说也要完成类似的操作,但是对于开发者2来说本地的master可能并不是最新的代码,所以在本地分支然后推送到远端,首先要切换到master进行pull操作保证它是最新。然后基于本地master新建一个分支一定是最新最全的代码。
创建feature2分支,进行fuction2开发,最后进行push
远程仓库也有feature2分支了
有没有注意到在这种多人协作开发中,我们并没有解决任何冲突!不像第一种多人协作开发者2进行push会发生冲突,把冲突解决然后才能push。即使是我们针对同一个文件进行开发也不会有冲突,原因就是各自分支是自己私有独立的。
但天有不测风云,开发者2突然生病了,但需求还没开发完,需要你帮他继续开发,于是他便把feature2 分支名告诉你了。这时你就需要在自己的机器上切换到 feature2 分支帮忙继续开发。这样其实又演变成了多名开发者在同一个分支上进行协作开发的场景。我们在来熟悉一下这个流程。
对于开发者1来说它现在看不到远端featrue2分支,
那如何将远程feature2拉下来呢?可以直接使用
git pull
我们之前可没有将本地feature1和远程feature1建立连接,这里直接pull可以吗?
虽然下面提醒我们需要先建立连接,但是上面说的有一个新的远程feature2分支
我们看到确实是把feature2分支拉下来了
这里就有疑问了,我们并没有建立连接,为什么可以使用git pull命令呢?
对于git pull来说有两种情况,
第一种:拉取分支内的内容,我们必须要建立连接才能使用git pull。
第二种:拉取远程仓库的内容(某个分支),是不用让分支先建立连接的。
因为开发者1要帮开发者2进行开发,所以我们新建一个本地feature2分支进行开发。
这时,开发者2已经修养的差不多,可以继续进行自己的开发工作,那么他首先要获取到你帮他开发的内容,然后接着你的代码继续开发。或者你已经帮他开发完了,那他也需要在自己的电脑上看看你帮他写的。
但是这里直接pull并没有成功,这是因为之前建立本地feature2之后并没有和远程feature2建立连接。
建立好连接之后在使用git pull命令拉取,就可以看到开发者1帮忙开发的代码了
然后开发者2继续开发,最后push
对于开发者2也完成了自己要开发的内容
feature1和feature2都完成了自己的内容,接下来就是将feature1和feature2都合并到master。
2.3将内容合并进master
这里我们演示PR申请单。
先让feature2合并进master分支
把申请单填好就进行提交
然后就由审查和测试人员进行审查了,没有问题就通过
然后点击合并分支
就把feature2合并到master了
我们在看一下这个流程
接下来虽然也可以将feature1分支也像刚才那样merge到master分支,但是我们这里在多说一些细节问题
当前对于master分支来说,多了一个feature2提交。此时我们想让feature1合并到master会不会产生冲突呢?
可能会发生冲突的!如果没有在同一个文件内修改就没有冲突,但是就怕有冲突,那么此时又回到之前的要解决冲突,这个冲突我们要在feature1解决不要破坏master分支的稳定性。所以先让feature1分支合并master分支,有冲突我们在feature1分支解决,不影响master。
冲突解决完之后,我们在让master合并feature1
其实对于feature2分支合并到master我们也建议用刚才的流程,先让feature2合并一下master,然后master在合并feature2,只不过刚才我们省略了让feature2合并一下master这一步,直接让master在合并feature2了。
feature2合并master分支,这一步我们要在本地完成 ,然后再推送给远端的feature2,然后再用PR申请单让master合并feature2。
首先要保证本地master分支是最新的
切换到feature1分支去合并master分支,然后push一下,此时远程feature1分支就是最新的了
然后我们在用PR让master合并feature1,
到这里feature1和feature2就完成了各自的功能,那么我们可以直接在远程仓库中将它们删掉。
3.远程分支删除后,本地 git branch -a 依然能看到的解决办法
当前我们已经删除了远程的几个分支,使用 git branch -a 命令可以查看所有本地分支和远程分支,但发现很多在远程仓库已经删除的分支在本地依然可以看到。
随着时间推移本地仓库就有很多已经被删除的远程分支,如何解决呢?
使用命令 git remote show origin ,可以查看remote地址,远程分支,还有本地分支与之相对应关系等信息。
git remote show origin
可以看到dev/feature1/feature2三个分支已经陈旧了,可以使用下面命令就不显示已经陈旧的分支了。
git remote prune origin
本地的分支可以使用下面的命令删除
git branch -d [分支]