Git中的代码分支的代码同步

当提交代码到远程分支,经常会遇到提交的时候被拒绝的情况

$ git push origin master
To git@gitee.com:micaixiaoduanku/Demo.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'git@gitee.com:micaixiaoduanku/Demo.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.

这种情况是由于本地分支代码的版本已经落后远程分支代码版本这个时候通常会有三种选择
1,pull远程代码,再本地做merge后push到远程分支
2,直接进行一个merge远程分支的操作,再做提交
3,进行一次rebase再做提交
这三种操作方式操作方式和结果是有区别的,下面做一个总结
准备工作:
我在码云上创建一个空仓库,并且clone下来

$ git clone git@gitee.com:micaixiaoduanku/Demo.git
Cloning into 'Demo'...
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3/3), done.
Checking connectivity... done.
$ mv Demo Demo1
$ git clone git@gitee.com:micaixiaoduanku/Demo.git
Cloning into 'Demo'...
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3/3), done.
Checking connectivity... done.
$ mv Demo Demo2
$ ls
Demo1   Demo2

如上所示,目前本地拥有2个仓库的clone版本Demo1和Demo2.
下面我创建一个fileA文件并提交到远程分支master上面

$ cd Demo1
$ ls
README.md
$ touch fileA
$ git add .
$ git commit -m "add fileA from Demo1"
[master f8a717c] add fileA from Demo1
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 fileA
$ git push origin master
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 273 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@gitee.com:micaixiaoduanku/Demo.git
   35e89fa..f8a717c  master -> master

接下来进入Demo2仓库,创建一个fileB文件并提交

$ touch fileB
$ git add .
$ git commit -m "add fileB from Demo2"
[master 8761ffb] add fileB from Demo2
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 fileB

这个时候去push到远程master分支上面会出现,文章开始所描述的情况

$ git push origin master
To git@gitee.com:micaixiaoduanku/Demo.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'git@gitee.com:micaixiaoduanku/Demo.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.

第一种操作,根据提示进行pull

$ git pull origin master

出现了一个提示

Merge branch 'master' of gitee.com:micaixiaoduanku/Demo

# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.

上面的意思是,这里进行了一个merge远程分支master的操作,并且是作为一次commit, 当然你可以删除这个Message忽略这次merge.(如果忽略这次merge,需要自己手动进行merge, 待会儿我会补充这种情况如何处理,下面先看不删除Message的情况)
接着我们进行再进行push操作

$ git push origin master
Counting objects: 4, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 559 bytes | 0 bytes/s, done.
Total 4 (delta 0), reused 0 (delta 0)
To git@gitee.com:micaixiaoduanku/Demo.git
   f8a717c..3b567c1  master -> master

这下成功了,看看提交记录

$ git log
commit 3b567c182ad6e262404ce60d7ec82447c837c98a
Merge: 20fe0ea f8a717c
Author: huangli <huangli@bilibili.com>
Date:   Fri Jan 19 16:02:38 2018 +0800

    Merge branch 'master' of gitee.com:micaixiaoduanku/Demo

commit 20fe0ea4baca93380b12836c026b15681b5c6905
Author: huangli <huangli@bilibili.com>
Date:   Fri Jan 19 15:58:58 2018 +0800

    add fileB from Demo2

commit f8a717cb55e6e75163d66e4d62d2af0f84d96eb0
Author: huangli <huangli@bilibili.com>
Date:   Fri Jan 19 15:57:56 2018 +0800

    add fileA from Demo1

这种情况有提交“Merge branch 'master' of gitee.com:micaixiaoduanku/Demo”的提交记录,其实我本意并不希望出现这个提交记录,我只希望有一条“add fileB from Demo2”的提交记录,在刚才pull的过程中,我拉下来了远程仓库的fileA文件,这是一个merge的过程,在git中merge是一个commit的操作,切记(这点和SVN不同),也许有同学会问到,那我如果删除前面提到commit的Message会不会就不会有这条提交记录了?我们来试试看
我在删除Merge branch 'master' of gitee.com:micaixiaoduanku/Demo 会得到这条提示

error: Empty commit message.
Not committing merge; use 'git commit' to complete the merge.

再来看看log

$ git log
commit 8cda7fa99bdae380b8486c70402c16664ed338e6 (HEAD -> master)
Author: 351573105 <351573105@qq.com>
Date:   Sat Jan 20 20:51:47 2018 +0800

    add fileB from Demo2

commit 00d805930f9bd5b1dff5beb2027c3b8b7c3238c4
Author: Eric <micaixiaoduanku@sina.cn>
Date:   Sat Jan 20 20:43:03 2018 +0800

    Initial commit

果然,没有那条我讨厌的merge log了,这个时候我再看看本地分支的status

$ git status
On branch master
Your branch and 'origin/master' have diverged,
and have 1 and 1 different commits each, respectively.
  (use "git pull" to merge the remote branch into yours)

All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

Changes to be committed:

    new file:   fileA

我晕,merge下来的fileA是在暂存区,还没有commit, 看来是逃不过这条commit message的。

总结:pull这种方式会存在一个merge的过程,这个merge过程是会当成一个commit提交的,这样会造成一个结果是:我把fileA merge过来了并提交了,那么log中将会出现一个 merge的commit里面包含增加fileA文件,那么pull下来的log记录将会和“add fileA from Demo1” 中提交fileA的这条记录有冲突,试想一下,目前3个同事协同开发,同事A, 创建一个文件A并提交,同事B, 创建文件B并提交(这个时候也要进行同步,但是他用的rebase, 不会有多条commit记录),重点看同事C , 创建文件C并提交,他进行了pull操作,然后merge了文件A和文件B, 这是两条提交记录,一条是添加文件C,另外一条是文件A和文件B的一条merge commit, 这个时候提交记录看上去就很奇怪。

  • 一是同事A和同事B的内容重复
  • 二是你明明只想提交一个文件C,却顺带提交了文件A和文件B
    这也是在这种情况下建议用rebase的原因.

第二种操作,直接进行merge

切换到Demo1,编辑fileA

$ vim fileA

添加一行

Demo1 修改fileA

然后往远程分支上面提交

$ git add .
$ git commit -m "Demo1 修改 fileA"
[master 78cbea3] Demo1 修改 fileA
 1 file changed, 1 insertion(+)
$ git push origin master
To git@gitee.com:micaixiaoduanku/Demo.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'git@gitee.com:micaixiaoduanku/Demo.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.

这个时候又不同步了,会叫你进行pull的情况,这个时候我们选择去merge远程分支
先执行git fetch命令(fetch是获取远程仓库所有信息,但是不会merge到本地仓库,这是它和pull的区别,pull是会进行merge的)

$ git fetch
remote: Counting objects: 4, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (4/4), done.
From gitee.com:micaixiaoduanku/Demo
   f8a717c..3b567c1  master     -> origin/master

再执行

git merge origin/master 
Merge remote-tracking branch 'origin/master'

# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.

同样会出现之前进行pull操作的情况,但这个时候它默认的message不是“Merge branch 'master' of gitee.com:micaixiaoduanku/Demo”,看出区别了吗?一个pull的message是merge远程的分支,而fetch后再merge的message是merge的origin/master远程跟踪, 它实质上是一种本地merge(本地分支和本地分支进行merge, pull是本地分支和远程分支进行merge). 随后我们看下log

$ git log
commit 3efb4143cb6ff5fd9c1f96d3acdf6a31c7466402
Merge: 78cbea3 3b567c1
Author: huangli <huangli@bilibili.com>
Date:   Fri Jan 19 16:12:47 2018 +0800

    Merge remote-tracking branch 'origin/master'

commit 78cbea3d1f3203517fcb63c06d2cbe1ad93bacc5
Author: huangli <huangli@bilibili.com>
Date:   Fri Jan 19 16:10:49 2018 +0800

    Demo1 修改 fileA

commit 3b567c182ad6e262404ce60d7ec82447c837c98a
Merge: 20fe0ea f8a717c
Author: huangli <huangli@bilibili.com>
Date:   Fri Jan 19 16:02:38 2018 +0800

    Merge branch 'master' of gitee.com:micaixiaoduanku/Demo

commit 20fe0ea4baca93380b12836c026b15681b5c6905
Author: huangli <huangli@bilibili.com>
Date:   Fri Jan 19 15:58:58 2018 +0800

同样会多一条merge的commit记录.
最后再进行push

$ git push origin master
Counting objects: 5, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 542 bytes | 0 bytes/s, done.
Total 5 (delta 1), reused 0 (delta 0)
To git@gitee.com:micaixiaoduanku/Demo.git
   3b567c1..3efb414  master -> master

总结: 这种方式和pull很像,区别就是一个远程直接merge,一个是先fetch再进行本地merge. 同样它也会产生一个merge操作后commit日志,这点是对于有提交记录洁癖的人不太妥当.

第三种操作,进行ReBase

什么是rebase?http://gitbook.liuhui998.com/4_2.html
再切换回Demo2,修改fileA文件,在第一行写“Demo2 修改fileA”,然后提交到远程分支.

$ vim fileA
$ git add .
$ git commit -m "Demo2 修改fileA"
[master 2aac6c6] Demo2 修改fileA
 1 file changed, 1 insertion(+)
$ git push origin master
To git@gitee.com:micaixiaoduanku/Demo.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'git@gitee.com:micaixiaoduanku/Demo.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.

这个时候先进行一次fetch操作

$ git fetch
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 5 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (5/5), done.
From gitee.com:micaixiaoduanku/Demo
   3b567c1..3efb414  master     -> origin/master

接着rebase

$ git rebase origin/master
First, rewinding head to replay your work on top of it...
Applying: Demo2 修改fileA
Using index info to reconstruct a base tree...
M   fileA
Falling back to patching base and 3-way merge...
Auto-merging fileA
CONFLICT (content): Merge conflict in fileA
Failed to merge in the changes.
Patch failed at 0001 Demo2 修改fileA
The copy of the patch that failed is found in:
   /Users/huangli/Desktop/mygit/test/Demo2/.git/rebase-apply/patch

When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".

fileA出现了冲突,我们先去解决冲突

<<<<<<< 3efb4143cb6ff5fd9c1f96d3acdf6a31c7466402
Demo1 修改fileA
=======
Demo2 修改fileA
>>>>>>> Demo2 修改fileA

看看目前status

$ git status
rebase in progress; onto 7d18bfc
You are currently rebasing branch 'master' on '7d18bfc'.
  (fix conflicts and then run "git rebase --continue")
  (use "git rebase --skip" to skip this patch)
  (use "git rebase --abort" to check out the original branch)

Unmerged paths:
  (use "git reset HEAD <file>..." to unstage)
  (use "git add <file>..." to mark resolution)

    both modified:   fileA

no changes added to commit (use "git add" and/or "git commit -a")

目前处于一个rebasing状态,接下来要做的是,解决冲突后执行一个"git rebase --continue",好,我们先解决一下冲突,修改成如下

Demo1 修改fileA
Demo2 修改fileA

然后执行

$ git rebase --continue
fileA: needs merge
You must edit all merge conflicts and then
mark them as resolved using git add

提示说还需要add过后表明解决了冲突,ok, 我先add.

$ git add fileA
$ git rebase --continue
Applying: Demo2 修改fileA

最后来看看提交记录.

$ git log
commit 884a0b87c06dcecf1792cb0c900d26cb3f2f0a88 (HEAD -> master)
Author: 351573105 <351573105@qq.com>
Date:   Sat Jan 20 22:10:27 2018 +0800

    Demo2 修改fileA

哈哈,终于没有令代码洁癖厌烦的merge commit log了。
总结: 在解决本地分支和远程分支代码不同步的时候使用rebase的优势显而易见,它既可以完成代码的merge工作,同时可以不出现merge commit log记录,从而保证提交记录的整洁。所以多人协同在同一条分支下面进行开发的情况下,出现分支代码不同步的情况下,一定要使用rebase进行的冲突处理.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,047评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,807评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,501评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,839评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,951评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,117评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,188评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,929评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,372评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,679评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,837评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,536评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,168评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,886评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,129评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,665评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,739评论 2 351

推荐阅读更多精彩内容

  • 四、 分支开发工作流 现在你已经学会新建和合并分支,那么你可以或者应该用它来做些什么呢? 在本节,我们会介绍一些常...
    常大鹏阅读 2,097评论 3 24
  • 多种多样的工作流使得在项目中实施Git时变得难以选择。这份教程提供了一个出发点,调查企业团队最常见的Git工作流。...
    JSErik阅读 4,389评论 2 8
  • 以下笔记主要参考gitgot,大致了解git使用和原理。 第一部分我们从个人的视角去研究如何用好Git,并且揭示G...
    carolwhite阅读 2,370评论 0 1
  • Add & Commit git init 初始化一个 Git 仓库(repository),即把当前所在目录变成...
    冬絮阅读 4,804评论 0 8
  • 昨天店里迎来一对六十来岁的夫妇,穿着朴素,干净整洁,具备乡土气息,女士在门口货架处看衣服,男士站在门外,因为客户多...
    毓美阅读 306评论 0 0