Git快速入门系列文章
- Git快速入门-安装配置篇
- Git快速入门-常用命令之独奏篇
- Git快速入门-常用命令之交响乐篇
- Git快速入门-git stash 暂存变更,git reset 撤销commit,git revert 回退远程版本库
Git入门系列第三篇,介绍日常开发中,与团队其他成员协作时常用的命令。
现在用户zhangsiwei 加入 f_test_1.2.0分支一起工作了。他执行git clone 把代码拉到本地后,执行git checkout命令切换到 f_test_1.2.0分支,如下
$ git checkout f_test_1.2.0
Branch f_test_1.2.0 set up to track remote branch f_test_1.2.0 from origin.
Switched to a new branch 'f_test_1.2.0'
$ git branch
* f_test_1.2.0
master
现在zhangsiwei 和 flysqrlboy 的工作区是相同的。假设这样一种场景:如果两人各自在本地版本库中进行独立的提交,然后再分别向共享版本库Github推送,会相互覆盖吗?通过下面的实践就能知道答案。
首先,zhangsiwei 修改了c.txt 的第一行,然后在本地版本库中提交,再把提交推送到Github。操作步骤如下:
(1)zhangsiwei修改c.txt 的第一行并提交到本地版本库
$ cat c.txt
add by flysqrlboy
test crlf
修改第一行后保存,如下
$ cat c.txt
add by flysqrlboy modify by zhangsiwei
test crlf
提交到本地版本库
$ git add c.txt
$ git commit -m 'zhangsiwei modify'
[f_test_1.2.0 a362394] zhangsiwei modify
1 file changed, 1 insertion(+), 1 deletion(-)
(2)zhangsiwei 将本地提交推送到Github上
$ git push origin f_test_1.2.0
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 312 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@github.com:flysqlrboy/learn-git.git
cff6bc9..a362394 f_test_1.2.0 -> f_test_1.2.0
通过上面的操作,用户zhangsiwei 已成功更新了远程Github上的代码。如果用户flysqrlboy不知道用户zhangsiwei所做的上述操作,仍在基于Github旧数据同步而来的本地版本库中进行改动,然后用户flysqrlboy向Github推送,会有什么结果?用下面的操作验证过下。
(3)用户flysqrlboy修改c.txt 的第二行并提交到本地版本库
$ cat c.txt
add by flysqrlboy
test crlf
修改第二行,如下
$ cat c.txt
add by flysqrlboy
test crlf modify by flysqrlboy
提交到本地版本库
$ git add c.txt
$ git commit -m 'flysqrlboy modify'
[f_test_1.2.0 f17bbfe] flysqrlboy modify
1 file changed, 1 insertion(+), 1 deletion(-)
(4)用户flysqrlboy将本地提交推送到服务器会出错
$ git push origin f_test_1.2.0
To [email protected]:zhangsiwei/test.git
! [rejected] f_test_1.2.0 -> f_test_1.2.0 (fetch first)
error: failed to push some refs to '[email protected]:zhangsiwei/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.
用户flysqrlboy的推送被拒绝,hint里说明了原因:远程版本库包含你本地没有的改动,通常是因为有其他人push了。需要先通过git pull 命令来合并之后再push。git pull 命令会把改动拉到本地,并进行自动合并。
$ git pull origin f_test_1.2.0
Enter passphrase for key '/c/Users/dellzj/.ssh/id_rsa':
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From [email protected]:flysqlrboy/learn-git
* branch f_test_1.2.0 -> FETCH_HEAD
cff6bc9..a362394 f_test_1.2.0 -> origin/f_test_1.2.0
Auto-merging c.txt
CONFLICT (content): Merge conflict in c.txt
Automatic merge failed; fix conflicts and then commit the result.
提示”CONFLICT (content): Merge conflict in c.txt”,自动合并过程出现了冲突。好,那就先解决冲突,执行命令 git mergetool 打开图形工具,默认会选择系统中已经安装的工具,如kdiff3。
执行 git mergetool 命令后,会提示使用kdiff3(kdiff3的安装请参考Git快速入门-安装配置篇),按回车后自动打开kdiff3窗口,如下
kdiff3上方三个窗口由左至右显示冲突文件的三个版本,分别是:
A:共同祖先版本
B:本地更改的版本(这里就是用户flysqrlboy更改的版本)
C:远程版本(这里就是用户zhangsiwei push到Github的版本)
kdiff3下方的窗口是合并后文件的编辑窗口。
通过下图红框内的箭头或者红框内的红色标记,选中某个冲突行(如第一行),然后选中紫框内的C,表示使用C窗口中的内容
作为合并后的内容。同样的操作,第二行则使用B窗口的内容。确定完成后点击保存按钮,关闭kdiff3窗口退出。
这时执行git status,会看到冲突已经解决。不过mergetool会产生一些临时文件,如*.orig,不要提交,手动删除即可。
执行git commit命令,会打开commit注释窗口(如下图),git已经为你准备好一个默认注释,就是刚刚合并冲突的注释。保存退出即可。
查看刚刚解决冲突的提交日志
$ git log --oneline
0ffed81 Merge remote-tracking branch 'refs/remotes/origin/f_test_1.2.0' into f_test_1.2.0
f17bbfe flysqrlboy modify
a362394 zhangsiwei modify
执行推送,这次成功了。
$ git push origin f_test_1.2.0
Counting objects: 10, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 667 bytes | 0 bytes/s, done.
Total 6 (delta 0), reused 0 (delta 0)
To git@github.com:flysqlrboy/learn-git.git
a362394..0ffed81 f_test_1.2.0 -> f_test_1.2.0
本文介绍了在多人团队协助时使用Git的常用命令,主要演示了多人修改同一个文件而产生冲突时如何使用kdiff3解决冲突的过程。
本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。