问题及现象

当某一分支(假设为main)的本地仓库和远程仓库都基于同一个提交进行了修改,并分别创建了新的提交时,在本地执行git push origin main会提示先要执行git pull合并远程代码。



如下示例:

# 本地修改与远程仓库不一致时,推送代码到远程仓库时提示先要执行git pull操作
$ git push origin main
warning: redirecting to https://gitlab.com/zhangsan/testversion.git/
To http://gitlab.com/zhangsan/testversion.git
! [rejected] main -> main (fetch first)
error: failed to push some refs to 'http://gitlab.com/zhangsan/testversion.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.

如果此时我们按照提示信息执行:git pull origin main,可能会发生2件事情:

(1)代码冲突,这个不一定会出现,如果本地修改跟远程仓库中的修改不在一个文件中,就不会出现冲突

(2)在本地解决冲突(如果存在)后提交时会出现一个“Merge branch ...”的日志,看起来不友好,可读性非常差,同时分支的历史看起来也很乱

操作详情如下:

$ git pull origin main
warning: redirecting to https://gitlab.com/zhangsan/testversion.git/
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 307 bytes | 23.00 KiB/s, done.
From http://gitlab.com/zhangsan/testversion
* branch main -> FETCH_HEAD
f2576b1..4dc87e6 main -> origin/main
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.

显然,出现了冲突,解决冲突并提交最新修改。

$ git commit -a
# 解决冲突后执行“git commit -a”时默认会生成一个“Merge branch...”日志,看起来并不友好
Merge branch 'main' of http://gitlab.com/zhangsan/testversion into main # Conflicts:
# index.html
#
# It looks like you may be committing a merge.
# If this is not correct, please run
# git update-ref -d MERGE_HEAD
# and try again. # Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch main
# Your branch and 'origin/main' have diverged,
# 提交后查看日志,这样的日志不友好,而且显得很乱
$ git log --oneline
ea5ceab (HEAD -> main) Merge branch 'main' of http://gitlab.com/zhangsan/testversion into main

分支历史看起来也有点乱:

原因分析及解决办法

之所以存在本地执行git push时提示需要先执行git pull合并远程代码,是因为在本地和远程分别基于一个相同的提交进行了修改,这与基于某个相同的提交创建2个新分支进行修改是一个道理。

实际上这种情况在实际开发中会经常遇到,比如:在开发新的功能时通常都是基于当前master最新的提交拉出一个新的分支进行修改并提交。假如张三和李四需要同时开发2个不同的需求,那么张三和李四都会基于master拉出新的开发分支进行修改,如果张三先开发并测试完毕就会将代码推送到远程master,等李四开发并测试需要推送到远程master时,执行git push操作一定会提示先要执行git pull拉取远程最新的代码进行合并。

为了避免出现合并日志不友好和分支历史不整洁的问题,在执行git pull时使用-r选项,即:git pull origin main -r,或者:git pull origin main --rebase

执行git pull origin main -r时与在本地执行git rebase的效果是一样的,解决好冲突之后需要执行git rebase --continue,这样就可以保持提交日志的可读性,也可以使得分支历史干净。

# 本地修改与远程不一致时执行“git pull origin main -r”提示存在冲突
$ git pull origin main -r
warning: redirecting to https://gitlab.com/zhangsan/testversion.git/
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 272 bytes | 10.00 KiB/s, done.
From http://gitlab.com/zhangsan/testversion
* branch main -> FETCH_HEAD
ea5ceab..6b252fe main -> origin/main
error: could not apply 90f947e... fix: add div13
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply 90f947e... fix: add div13
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html

手动解决冲突之后,先要执行git add命令添加修改过的文件,再次实行git rebase --continue合并冲突,此时不在会出现“Merge branch ...”这样的不友好日志。

$ git rebase --continue
fix: add div13 # Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# interactive rebase in progress; onto 6b252fe
# Last command done (1 command done):
# pick 90f947e fix: add div13
# No commands remaining.
# You are currently rebasing branch 'main' on '6b252fe'.
#
# Changes to be committed:
# modified: index.html Successfully rebased and updated refs/heads/main.

此时再来看分支历史也非常简洁:

使用总结

1.尽快合并远程最新代码,为了确保这一点每次在本地修改之前都先执行一次git pull操作。

假设在本地分支b1上开发一个新的功能,尽快将远程master分支的代码拉取到本地并与本地b1分支做rebase操作,操作顺序可以总结为:

git checkout master
git pull origin master
git checkout b1
git rebase master

2.合并相同分支的远程代码时使用“-r”选项(git pull origin 分支名称 -r),保持提交日志的可读性和分支历史的简洁性。

3.git pull不带-r选项时本质上是:git fetch + git merge,带上-r选项时为:git fetch + git rebase

【参考】

https://www.qikegu.com/docs/4381 Git – 拉取(git pull)时的冲突

如何避免Git合并远程分支时出现可读性差的日志的更多相关文章

  1. git 合并远程分支

    假设远程分支 dev-by-wbw  本地分支dev-by-wgg 在本地新建一个与远程的分支dev-by-wbw相同(被合并的版本)的分支dev-by-wbw git checkout - b or ...

  2. git在本地分支上 git pull远程分支时,状况

    git 在pull或者合并分支的时候有时会遇到这个界面.可以不管(直接下面3,4步),如果要输入解释的话就需要: 1.按键盘字母 i 进入insert模式 2.修改最上面那行黄色合并信息,可以不修改 ...

  3. git使用,多分支合并代码解决冲突,git删除远程分支,删除远程master默认分支方法

    git使用,多分支合并代码解决冲突,git删除远程分支,删除远程master默认分支方法提交代码流程:1.先提交代码到自己分支上2.切换到devlop拉取代码合并到当前分支3.合并后有变动的推送到自己 ...

  4. git 合并本地分支到远程分支

    第一种方法: git 快速合并本地分支到远程分支1.git branch -a 查看所有分支2.git checkout origin/分支名称3.git checkout 分支名称完成 ------ ...

  5. 删除本地git的远程分支和远程删除git服务器的分支【转】

    转- 删除本地git的远程分支和远程删除git服务器的分支 在项目中使用git管理代码后,有些时候会创建很多不同名称的分支,以此区分各个分支代码功能. 而随着代码的合并,以前的分支就可能不再需要保存了 ...

  6. git对远程分支和tag的操作

    技术 Git查看.删除.重命名远程分支和tag 11/17/2012zrong7条评论69,235 次查看 本站文章除注明转载外,均为本站原创或者翻译. 本站文章欢迎各种形式的转载,但请18岁以上的转 ...

  7. git 更新远程分支

    使用git的时候,有时候会出现远端更新了一个分支,但是从本地想checkout一个远程分支时,会出现如下错误: fatal: git checkout: updating paths is incom ...

  8. 【Git】远程分支

    [Git]远程分支 转载:https://www.cnblogs.com/yangchongxing/p/10239270.html 目录 ============================ 1 ...

  9. Git切换远程分支

         1. 切换git远程分支,使用命令:git checkout -b 分支名称.    注意:切换远程分支一定要带伤-b 参数,只有切换本地分支的时候才不需要 -b参数,-b 的意思是 bas ...

  10. 180623、Git新建远程分支和删除

    Git新建远程分支和删除 现在我在master分支上,工作目标是干净的,也没有需要commit的: $ git branch * master release $ git status On bran ...

随机推荐

  1. [转帖]jmeter编写测试脚本大全

    目录 一.背景 二.按照功能划分 2.1 加密处理.验签处理 2.2 jmeter 使用beanshell 编写脚本 2.3 jmeter脚本报错大全 2.4 jmeter打印log 2.5 jmet ...

  2. 申威下单盘SSD与四块盘RAID5的性能测试结果

    申威下单盘SSD与四块盘RAID5的性能测试结果 背景 背景不在说了 申威服务器.. 结论 天坑 做了raid写入性能下降明显. 充分怀疑驱动不行. 四快盘的raid5 跟单盘的读几乎没区别. 感觉这 ...

  3. [转帖]Linux学习14-ab报错apr_pollset_poll: The timeout specified has expired (70007)

    https://www.cnblogs.com/yoyoketang/p/10255100.html 前言 使用ab压力测试时候出现报错apr_pollset_poll: The timeout sp ...

  4. JVM启动速度大页内存验证

    大页内存设置 先查看 cat /proc/meminfo |grep -i huge 获取大页内存的大小信息. AnonHugePages: 42022912 kB HugePages_Total: ...

  5. Linux 开启防火墙 避免非干系人误操作的处理

    公司里面进行系统集成测试. 不想让开发能够更改我的服务器信息, 但是改密码又太麻烦了. 想了想还是用 防火墙好一些. 第一步 开启防火墙 systemctl enable firewalld syst ...

  6. 微软Windows Sever系统也将强制要求TPM及CPU兼容

    https://www.cnbeta.com/articles/tech/1238647.htm 去年微软推出Win11系统时,TPM安全模块以及Intel 8代酷睿/AMD锐龙2代及以上的硬件要求引 ...

  7. [译]深入了解现代web浏览器(三)

    本文是根据Mariko Kosaka在谷歌开发者网站上的系列文章https://developer.chrome.com/blog/inside-browser-part3/ 翻译而来,共有四篇,该篇 ...

  8. 2024年最新的Python操控微信教程

    自从微信禁止网页版登陆之后,itchat 库实现的功能也就都不能用了,那现在 Python 还能操作微信吗?答案是:可以! 在Github上有一个项目叫<WeChatPYAPI>可以使用 ...

  9. 关于async函数的错误处理

    1. 关于async函数的错误处理 有些时候,我们请求的接口可能会报错: 从而导致后面的代码无法去执行: 这样就会造成页面上某些状态出错! 那么怎么样才能 既能捕获到错误 还能让代码往后面执行呢 2. ...

  10. interface{}类型 + fmt.Sprintf() 导致栈逃逸

    作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 对部分代码进行了栈逃逸检查: go build -gcfl ...