开发者社区> developerguy> 正文

Undoing Merges

简介: I would like to start writing more here about general Git tips, tricks and upcoming features. There has actually been a lot of cool stuff that has hap...
+关注继续查看

I would like to start writing more here about general Git tips, tricks and upcoming features. There has actually been a lot of cool stuff that has happened since the book was first published, and a number of interesting things that I didn't get around to covering in the book. I figure if I start blogging about the more interesting stuff, it should serve as a pretty handy guide should I ever start writing a second edition.

For the first such post, I'm going to cover a topic that was asked about at a training I did recently. The question was about a workflow where long running branches are merged occasionally, much like the Large Merging workflow that I describe in the book. They asked how to unmerge a branch, either permenantly or allowing you to merge it in later.

You can actually do this a number of ways. Let's say you have history that looks something like this:

You have a couple of topic branches that you have developed and then integrated together by a series of merges. Now you want to revert something back in the history, say 'C10' in this case.

The first way to solve the problem could be to rewind 'master' back to C3 and then merge the remaining two lines back in again. This requires that anyone you're collaborating with knows how to handle rewound heads, but if that's not an issue, this is a perfectly viable solution. This is basically how the 'pu' branch is handled in the Git project itself.

$ git checkout master
$ git reset --hard [sha_of_C3]
$ git merge jk/post-checkout
$ git merge db/push-cleanup

Once you rewind and remerge, you'll instead have a history that looks more like this:

Now you can go back and work on that newly unmerged line and merge it again at a later point, or perhaps ignore it entirely.

Reverting a Merge

However, what if you didn't find this out until later, or perhaps you or one of your collaborators have done work after this merge series? What if your history looks more like this:

Now you either have to revert one of the merges, or go back, remerge and then cherry-pick the remaining changes again (C10 and C11 in this case), which is confusing and difficult, especially if there are a lot of commits after those merges.

Well, it turns out that Git is actually pretty good at reverting an entire merge. Although you've probably only used the git revert command to revert a single commit (if you've used it at all), you can also use it to revert merge commits.

All you have to do is specify the merge commit you want to revert and the parent line you want to keep. Let's say that we want to revert the merge of the jk/post-checkout line. We can do so like this:

$ git revert -m 1 [sha_of_C9]
Finished one revert.
[master 88edd6d] Revert "Merge branch 'jk/post-checkout'"
 1 files changed, 0 insertions(+), 2 deletions(-)

That will introduce a new commit that undoes the changes introduced by merging in the branch in the first place - sort of like a reverse cherry pick of all of the commits that were unique to that branch. Pretty cool.

However, we're not done.

Reverting the Revert

Let's say now that you want to re-merge that work again. If you try to merge it again, Git will see that the commits on that branch are in the history and will assume that you are mistakenly trying to merge something you already have.

$ git merge jk/post-checkout
Already up-to-date.

Oops - it did nothing at all. Even more confusing is if you went back and committed on that branch and then tried to merge it in, it would only introduce the changes since you originally merged.

Gah. Now that's really a strange state and is likely to cause a bunch of conflicts or confusing errors. What you want to do instead is revert the revert of the merge:

$ git revert 88edd6d
Finished one revert.
[master 268e243] Revert "Revert "Merge branch 'jk/post-checkout'""
 1 files changed, 2 insertions(+), 0 deletions(-)

Cool, so now we've basically reintroduced everything that was in the branch that we had reverted out before. Now if we have more work on that branch in the meantime, we can just re-merge it.

$ git merge jk/post-checkout
Auto-merging test.txt
Merge made by recursive.
 test.txt |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

So, I hope that's helpful. This can be particularly useful if you have a merge-heavy development process. In fact, if you work mostly in topic branches before merging for integration purposes, you may want to use the git merge --no-ff option so that the first merge is not a fast forward and can be reverted out in this manner.

Until next time.

 

https://git-scm.com/blog/2010/03/02/undoing-merges.html

 

git 撤销 merging,git取消merge


$ git pull origin test
// git pull合并代码的时候,若发生冲突,会处于merging状态,检查代码,发现自己的分支低于主分支,这个时候想撤销merge

// 撤销merge
$ git reset --hard HEAD (or sha_1)

 

 

 

用git提交代码时 冲突了 

于是分支名变成如下图所示

 

在命令行输入:

 git reset --hard head 就可以了

 

 

但是在这个过程中 可能会碰到一个问题,如下图:

这个意思是在C:\Users\Admin\git\phhhh\.git目录下已经有一个index.lock文件夹存在了,只需要去这个目录下删了这个文件夹,然后再输入 git reset --hard head 就ok了

 

 http://blog.csdn.net/Android_Amelia/article/details/49612631?locationNum=11&fps=1

 

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
18999 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
25240 0
阿里云服务器ECS登录用户名是什么?系统不同默认账号也不同
阿里云服务器Windows系统默认用户名administrator,Linux镜像服务器用户名root
13953 0
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
20697 0
使用SSH远程登录阿里云ECS服务器
远程连接服务器以及配置环境
13982 0
腾讯云服务器 设置ngxin + fastdfs +tomcat 开机自启动
在tomcat中新建一个可以启动的 .sh 脚本文件 /usr/local/tomcat7/bin/ export JAVA_HOME=/usr/local/java/jdk7 export PATH=$JAVA_HOME/bin/:$PATH export CLASSPATH=.
14117 0
使用OpenApi弹性释放和设置云服务器ECS释放
云服务器ECS的一个重要特性就是按需创建资源。您可以在业务高峰期按需弹性的自定义规则进行资源创建,在完成业务计算的时候释放资源。本篇将提供几个Tips帮助您更加容易和自动化的完成云服务器的释放和弹性设置。
18716 0
阿里云服务器安全组设置内网互通的方法
虽然0.0.0.0/0使用非常方便,但是发现很多同学使用它来做内网互通,这是有安全风险的,实例有可能会在经典网络被内网IP访问到。下面介绍一下四种安全的内网互联设置方法。 购买前请先:领取阿里云幸运券,有很多优惠,可到下文中领取。
19220 0
+关注
developerguy
A code cleanliness code farmers, A programmer concentrate on elegant design, A want to do with the product architect
1663
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载