在“选择性”之后重新合并。或“部分”合并 [英] Re-merging after "Selective" or "Partial" Merge

查看:111
本文介绍了在“选择性”之后重新合并。或“部分”合并的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个我可以重复使用的问题示例:

设置

  mkdir test-git 
cd test-git
git init
echo'Hello,world。'> file1.txt
git add。
git commit -m'init commit'
git branch branch2
git checkout branch2
echo'Hello,universe'> file1.txt
echo'Foobar'> file2.txt
git add。
git commit -m'commit 2'

我想将branch2合并到master中,但只是 file1.txt 的变化,所以我做了这些:

  git checkout master 
git merge branch2 --no-commit --no-ff
git reset --file2.txt
git commit -m'部分合并Branch2到Master!'

所以这里是我意识到这可能不是一个好主意......假设我改变了主意,我现在也想合并file2.txt。我可以运行:

$ g $ merge $ branch $
code


回应:已经过期。


如果我运行 git diff branch2 --name-status 它返回 D file2.txt ,所以我想当我搁置文件2 .txt它将此作为删除进行追踪?我仍然不完全明白为什么我不能合并,它不会添加文件(我明显不明白git的合并算法)。

不幸的是,我目前的情况比这更复杂,所以我不能完全反转提交。有没有简单的方法来重新组合 master branch2 之间的区别,而无需重写历史记录?

解决方案

在git中,合并提交应该具有来自其所有父母的所有必要更改。因此,如果提交者故意决定选择某个文件的某个版本,那么结果提交被视为正确合并,并且不可能执行进一步合并。



这种行为有其原因。假设在第一次合并提交之后,对 branch2 中的 file2.txt 进行了额外更改,然后执行另一次合并 branch2 master (一个相当典型的情况,不是吗?)。什么应该被视为 file2.txt 的正确状态。我期望第二次合并应该只包含两次合并之间所做的更改,对吗?但是你希望有一些其他的行为,当git收集自历史开始以来迄今为止未应用的所有对 file2.txt 的更改。这将是非常恼人的。



然而,你可以做一个另类合并。也就是说,在 master 分支(在你的例子中,'init commit')合并之前跳转到一个提交,然后发布 git merge 再一次。

如果历史重写不适合您的需要,您可以创建一个新分支 b3 在该提交处执行合并,然后将 b3 合并回主。当然,你会在 file2.txt 上收到一个合并冲突,并且应该通过提供一个适当的变体来解决它。


Here's a reproducible example of the problem I've gotten myself into:

Setup

mkdir test-git
cd test-git
git init
echo 'Hello, world.' > file1.txt
git add .
git commit -m 'init commit'
git branch branch2
git checkout branch2
echo 'Hello, universe' > file1.txt
echo 'Foobar' > file2.txt
git add .
git commit -m 'commit 2'

I wanted to merge branch2 into master but only the changes to file1.txt, so here's what I did:

git checkout master
git merge branch2 --no-commit --no-ff
git reset -- file2.txt
git commit -m 'Partially Merged Branch2 into Master!'

So here's where I realized that might not have been a good idea... Let's say I changed my mind and I now want to merge file2.txt in as well. I can run:

git merge branch2

Response: Already up-to-date.

If I run git diff branch2 --name-status it returns D file2.txt, so I guess when I unstaged file2.txt it tracked this as a deletion? I still don'y completely understand why I can't merge over and it wouldn't add the file (I obviously don't understand git's merge algorithm very well).

Unfortunately, my currently scenario is much more complicated than this so I can't exactly reverse the commit. Is there an easy way to remerge the differences between master and branch2, without rewriting history?

解决方案

In git a merge commit is supposed to have all necessary changes from all its parents. So if a committer deliberately decided to pick a certain version of a file like you did, then the resulting commit is considered as "a right merge" and it's impossible to perform "further merge".

This behavior has its reasons. Suppose one makes an additional change to file2.txt in branch2 after the 1st merge commit, and then perform another merge of branch2 into master (a quite typical situation, isn't it?). What should be considered as a correct state of file2.txt. I would expect that the second merge should contain only changes made between two merges, right? But you desire some other behavior, when git collects all the changes to file2.txt unapplied so far since the beginning of history. That would be quite annoying.

Nevertheless you can do an "alternative merge". That is, jump to a commit before the merge on master branch (in your example, 'init commit') and then issue git merge once again.

If history rewriting isn't appropriate for your needs, you might create a new branch b3 at that commit, perform the merge, and then merge b3 back to master. Definitely, you will receive a merge conflict on file2.txt and should resolve it by providing a "proper variant" for it.

这篇关于在“选择性”之后重新合并。或“部分”合并的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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