目前我写过有关Git的文章:
《【闲谈】Git连接GitHub》
《【Git】什么破玩意,pull不下来东西,不想用了》
《【Git】删除操作》
说来也惭愧,时隔一年我才学会。
当年我看廖大神的官方网站Git教程,虽说他自称是史上最浅显易懂的Git教程!但我还是没有学会到底怎样才能进行多人协作。时隔一年,或许是对计算机的理解更加深入一些,现在略微有点懂了,发此博客,以做总结。
我理解的Git团队协作有两种情况
1.公司内部,共用同一个GitHub账号
2.开源社区,各自用各自GitHub账号
当初我们单人使用GitHub的时候,使用过一个命令
ssh-keygen -t rsa
这个命令会在windows的C盘/用户/用户名/.ssh目录下生成两个文件:id_rsa.pub和id_rsa,不带后缀名的文件里面存的是私钥,后缀名为.pub的文件里面存的是公钥。私钥是私有的,我们保存在自己电脑上,不能给外人看。公钥是可以给外人看的,我们把公钥的内容复制一份,粘贴到GitHub设置SSH那里。
这里的私钥和公钥是一一对应的。
公钥是根据私钥经过特殊的算法产生的。公钥负责加密,私钥负责解密。
我们把公钥设置在GitHub账号上,等到我们第一次push文件到远程仓库的时候,会进行身份验证。验证的原理就是,看看你本地的私钥能否解密GitHub账号上的一个公钥,如果解密正确,身份验证通过,否则不通过。
再说白点,每个GitHub的repository就是一个仓库,英文也是这样翻译的。我们把东西存到仓库里面,然后上一把锁,这把锁就是公钥。等到我们取东西的时候,Github需要验证我们的身份,访问我们本地的私钥,如果私钥能够解开公钥,那就通过验证,否则不通过。
下面接着说我们这里的多人协作。
如果是公司内部人员,大家都是同事,都为了共同的利益而奋斗,所以可以共用同一个GitHub账号。
若要进行多人协作,只需要每个人把自己的公钥都添加到共用的GitHub账号里。
这里有个坑,就是,我原先一直是一个人在用Github,现在来了个公司共用的GitHub账号,当我把我的公钥尝试添加到共用GitHub账号时,GitHub提示Key is already in use,意思就是,这个公钥正在被使用。解决办法就是把我个人GitHub上设置的SSH删除,然后才能在别的地方使用这个公钥。
但是这样一来,我这台电脑就没法往我个人GitHub上push文件了。
估计这是人家Linus建议的吧,公司电脑干公司的活,自己电脑干自己的活,两者不要纠缠在一起,生活是生活,工作是工作:)
现在共用的GitHub上设置了张三、李四、王五三人的SSH公钥,他们三个就可以进行协作了。
假设这个共用的GitHub账号是littlecurl,邮箱是[email protected],并且有一个repository名字为test
我来描述一下协作流程:
首先是张三:
1、下载并安装git
2、在一个文件夹中右键,git bash here
3、ssh-keygen -t rsa 生成公钥和私钥
4、将张三的公钥内容设置到共用GitHub上
5、执行下面两句,进行身份验证
git congfig --global user.name "littlecurl"
git congfig --global user.email "[email protected]"
6、git clone https://github.com/littlecurl/test.git
7、在test目录下进行增删改查
8、git add .
9、git commit -m"张三修改了***"
10、git push origin master
过了几天,公司效益不错,扩展了一名员工,名叫李四,他有属于自己的电脑
1、下载并安装git
2、在一个文件夹中右键,git bash here
3、ssh-keygen -t rsa 生成公钥和私钥
4、将李四的公钥内容设置到共用GitHub上
5、执行下面两句,进行身份验证
git congfig --global user.name “littlecurl”
git congfig --global user.email "[email protected]"
6、git clone https://github.com/littlecurl/test.git
7、在test目录下进行增删改查
8、git add .
9、git commit -m"李四修改了***"
10、git push origin master
又过了几天,张三又修改了一些东西,想要push到远程仓库,发现报错了
! [rejected] master -> master (fetch first)
error: failed to push some refs to '[email protected]:littlecurl/test.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
意思就是拒绝了我的push,因为远程有一些东西是李四提交上去的,而张三本地没有那些东西。
提示:先把远程的pull下来,执行下面的命令
git pull origin master
出现了下面的图片
上面图片显示,让我填写一下本次Merge的原因。弹出的窗口是vim编辑模式,不会操作vim的还是先找个vim教程看一看吧。当然不一定非要用vim,在安装git的时候,是可以选择其他编辑模式的,比如notepad++
我写上了这次Merge的原因,保存退出,现在git bash 界面如下
现在,张三再看一下本地的文件,发现,既有自己写的东西,又有李四写的东西。张三检查了一下李四写的东西,发现有个错别字,并进行了修改,然后将所有东西都push到了远程GitHub
git push origin master
又过了几天,李四又写好一些东西,想要push到远程,遇到了和张三同样的报错
上面的操作都是在master分支上进行的,假如张三先写了功能A,李四后写了功能B,现在master上有A、B两个功能,如果我不想要功能A了,master进行回退的时候,会连带着功能B给回退掉。
这种情况下就需要引入多分支了。张三和李四分别开一个分支,在各自的分支上进行开发迭代,然后再分别进行merge到master上。
创建一个分支的命令是 git checkout -b 分支名
张三执行了下面的操作
git branch # 先看一下自己在哪个分支
git checkout -b zhangsan # 创建一个名为zhangsan的分支
git add 功能A.txt # 将写好的功能A代码add
git commit -m"功能A第一版" # 将写好的功能A第一版代码commit
git add 功能A.txt # 将写好的功能A代码add
git commit -m"功能A第二版" # 将写好的功能A第二版代码commit
接下来,张三与master进行merge操作
现在我们在zhangsan分支上,需要先回到master分支
git checkout master # 回到master分支
git merge --no-ff -m"merge 功能A with --no-ff" zhangsan # 在master上执行merge操作
git push origin master # 推送到远程
merge命令的详细解释,来自廖大神的分支管理策略一文
通常,合并分支时,如果可能,Git会用
Fast forward
模式,但这种模式下,删除分支后,会丢掉分支信息。如果要强制禁用
Fast forward
模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。
意思就是 git merge 带上 --no-ff 参数会保存分支的历史信息。如果不加,merge后就看不到分支信息了。
发现可以进行merge,但是没法进行push,原因在1.2节已经说过,就是因为远程的代码有张三push的代码,而李四的本地还没有那些代码,需要先执行一下pull操作
我们可以使用下面的命令,来查看一下历史commit版本
git log --graph --pretty=oneline --abbrev-commit
会得到像下面一样很漂亮的一个列表
然后我们就可以使用git reset --hard commit版本号 进行时光穿梭了
当然,我上面介绍的是一个简单版本的多人协作,廖大神给出了一个实际工作的多人协作图
分支策略
在实际开发中,我们应该按照几个基本原则进行分支管理:
首先,
master
分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;那在哪干活呢?干活都在
dev
分支上,也就是说,dev
分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev
分支合并到master
上,在master
分支发布1.0版本;你和你的小伙伴们每个人都在
dev
分支上干活,每个人都有自己的分支,时不时地往dev
分支上合并就可以了。所以,团队合作的分支看起来就像这样:
以上就是我理解的同一个GitHub账号的多人协作
有时候我们想进行给一个开源库添砖加瓦,或者修改Bug之类的操作。我们的SSH公钥无法加入开源库的GitHub上,那就需要下面这样操作:
以上就是我理解的不同GitHub账号之间的多人协作