如何让Git兑现未被要求取消的合并? [英] How to make Git honor a cancelled merge that was not asked for?

查看:225
本文介绍了如何让Git兑现未被要求取消的合并?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我现在已经遇到过这种情况了大约3到4次了。有时候,Git会想要执行合并。它发生在响应 git commit< filename> -m 后跟一个 git push



我知道一个合并即将发生是因为Git将消息编辑器加入其中。所以我执行一个 CTRL + C 以试图阻止它。



我并不在乎为什么或者让我进入这个州的原因。当事情需要合并时,我只想停下来。我 不要 ,因为它会污染签入,污染历史记录并且有时会添加尚未准备好的内容。

但是,我发现Git仍在执行合并。授予:合并https://github.com/weidai11/cryptopp的分支'master'



一旦我 CTRL + C ,合并应该 不是 继续。如何让Git兑现没有被要求的取消合并?

解决方案

git push 通常应该会失败。

为了推动,你不能缺少服务器提交的任何提交。



在你发布的例子中,你似乎已经提交了 d091b80 217cb1f 在两台不同的机器或两个不同的本地副本上。 当您试图推送 217cb1f ,服务器已经有 d091b80 ,而你没有在你的本地分支中。



在git可以推送到服务器之前,您需要从服务器中提取其他提交。



通常情况下,你会手动。出于某种原因,您的 git push 似乎在调用 git pull



虽然我找不到具体的选项来启用这种行为(并且也不会建议这样做),但我可以看到有些人会希望git以这种方式行事。

如果你使用其他人的配置文件作为git或shell,我会看看是否有任何可能导致这种奇怪行为的东西。



那么合并提交通常如何实现呢?抛开push命令的怪异行为,并假设您手动进行了pull:



Git pull导致意外的合并提交



Git pull执行两件事:


  • 它获取远程文件

  • 它将远程分支合并到您的本地分支中



如果您的本地计算机上没有新的提交,快速转发将包含来自服务器的更改。这意味着您的本地分支将被简单地设置为与远程分支相同的修订版本(可视化只需在单一道路上稍微走一点)。假设你已经在你的本地分支上提交了一个提交,而同事(或你自己在另一台机器上)已经将另一个更改推送到服务器上的远程分支:


这两个分支现在已经分道扬(了(在这里将一条路分成两部分)。当git pull试图将它们合并在一起时,它将需要进行合并提交(将两条道路合并为一条)。



或者,您可以执行 git pull --rebase 或者在你的git config中设置相应的设置。这将告诉git将您的本地更改应用到服务器的末端。

请注意,重新绑定会使解决冲突更加困难,而且通常比合并更复杂。






尽可能早地推动分支转移。
如果您还没有创建任何新的本地提交,那么您之前从服务器发生的 pull 更改也是一个好主意正在提交。这样,你可以防止你的分支转移。



一个好办法是:

<$ p $ git stash#这会将未提交的更改保存为草稿
git pull#从远程
获取新提交git stash pop#恢复未提交的更改






在编辑提交消息时中止合并




  1. 清空编辑缓冲区中的提交消息,保存并退出。

    任何注释(以#开头)都可以保留它们在评估之前被git删除(尽管这个行为可以在配置中改变)。
    如果你是vim用户,我相信 dG:x

  2. 运行 git merge --abort

    这将使git尝试恢复工作副本的预合并状态。

    该命令在git 1.7.4或更高版本中可用。有关更多信息,请参阅 man entry for git-合并






为什么Ctrl + C不能如果不是所有的情况下都是这样的话,那么只要按下 Ctrl + C 做你的期望。当git启动命令行编辑器(如vim,emacs或nano)时,编辑器将成为该shell的活动/当前进程。
$ b Ctrl + C 会发送 SIGINT 发信号给当前进程。意思是发送 SIGINT 到你的编辑器,而不是git。



如果你要使用编辑器, (退出并返回0以外的退出代码),那可能(虽然我没有测试过)中止提交。

编辑器会保存一个空缓冲区并退出。

如果你配置git启动一个GUI编辑器,它仍然是最前面的过程, SIGINT 仍然应该放弃提交。



请注意,在所有三种情况下,您的工作副本中可能会有其他分支的更改,您需要清理它们(请参阅步骤2)。






对于我个人(以及许多广泛的git用户),这种行为是我想从git获得的。如果您有不同的看法,可以此处提交错误报告或功能请求。


I've run into this situation about 3 or 4 times now. On occasion, Git will want to perform a merge. It happens in response to a git commit <filename> -m <message> followed by a git push.

I know a merge is about to occur because Git spins up the editor for the message. So I perform a CTRL + C in an attempt to stop it.

I don't really care why or what got me into the state. When things have to be merged, I just want to stop. I do not want it to occur because it pollutes the check-ins, pollutes the history and sometimes adds stuff that's not ready.

However, I see that Git still performs the merge. Confer: Merge branch 'master' of https://github.com/weidai11/cryptopp.

Once I CTRL + C, the merge should not proceed. How to make Git honor a cancelled merge that was not asked for?

解决方案

git push should normally fail if there are any new commits on the remote, that you don't have on your local branch yet.

In order to push, you cannot be missing any commits that the server has.

In the example you posted, you seem to have made the commits d091b80 and 217cb1f on two different machines or two different local copies.

When you were trying to push 217cb1f, the server already had d091b80, while you didn't have it in your local branch.

Before git can push to the server, you will need to pull that other commit from the server.

Usually that is something, that you would do manually. For some reason it seems like your git push is somehow invoking a git pull.

While I couldn't find a specific option to enable this sort of behavior (and wouldn't suggest doing so either), I can see that some people would want git to behave this way.
If you are using another persons config files for git or for your shell, I would have a look if there is anything that might cause this weird behavior.

So how does the merge commit generally come about? Set aside the weird behavior of the push command and assume you had manually done a pull:

Git pull causes an unexpected merge commit

Git pull is doing two things:

  • It fetches the remote
  • It merges the remote branch into your local branch

If there you have no new commits on your local machine, then you have a linear history and changes from the server will be included by fast-forwarding. This means that your local branch will simply be set to the same revision as the remote branch (visualise just having to walk down a little further on a single road).

Imagine you have made a commit on your local branch, while a colleague (or yourself on a different machine) has pushed another change to the remote branch on the server:
The two branches have now wandered into separate ways (visualise one road splitting into two here). When git pull tries to merge them together it will need to make a merge commit (visualise two roads merging into one).

Alternatively you could do git pull --rebase or set the corresponding setting in your git config. This will tell git to apply your local changes to the "end of the road" of the server.
Note though, that a rebasing makes conflict resolution much harder and is generally more complicated than merges.


Pushing as early as possible minimises branch diversion. If you haven't made any new local commits yet, it is also a good idea to pull changes from the server before you are making a commit. That way, you are preventing your branches from diverting.

A good way to do this is:

git stash       # This saves your uncommitted changes away as a draft
git pull        # Gets new commits from the remote
git stash pop   # Restores your uncommitted changes


Abort a merge, while already editing the commit message

  1. Empty the commit message in your editors buffer, save and exit.
    Any comments (prefixed with #) can stay as they are removed by git before evaluating (though this behaviour can be changed in the config).
    If you are vim user, I believe dG:x to be the fastest way to do this.
  2. Run git merge --abort
    This will make git try to restore the pre-merge state of your working copy.
    This command is available in git 1.7.4 or higher. For more info have a look at the man entry for git-merge.


Why Ctrl+C does not do what one might expect

Simply pressing Ctrl+C will (in most, if not all cases) not do what you expect. When git launches a command line editor (such as vim, emacs or nano) that editor becomes the active/current process of that shell.

Press Ctrl+C will send a SIGINT signal to the current process. Meaning, sending SIGINT to your editor and not to git.

If you were to use an editor, that fails (quits and returns an exit code other than 0) when receiving that signal, that might (though I have not tested it) abort the commit.
As will an editor, that saves an empty buffer and quits.
If you configure git to launch a GUI editor it will remain the frontmost process and a SIGINT should still abort the commit.

Note, that in all three cases you will likely have the changes from the other branch in your working copy and you will need to clean them up (see step 2).


For me personally (and a lot of extensive git users), this behaviour is what I would want from git. If you see that differently, you could file a bug report or feature request here.

这篇关于如何让Git兑现未被要求取消的合并?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆