简体   繁体   English

Git:将旧提交合并到当前头版本中

[英]Git: Merge old commit into current head version

Got a file that has two commits of interest, both on the Master branch, both only modifying a single file foo : a previous commit AA , and the current version in HEAD . 有一个文件有两个感兴趣的提交,都在Master分支上,都只修改单个文件foo :先前的提交AA ,以及HEAD的当前版本。 I would like to merge the two versions of the file, keeping bits of both, into HEAD on Master . 我想合并文件的两个版本,保留两者的位,进入Master HEAD

I did the simplest thing that I thought would work: 我做了一件我觉得最简单的事情:

git checkout -b merge-purgatory AA
git commit -m "pulled foo back from previous commit for merging into HEAD."
git checkout master
git merge merge-purgatory

Which simply overwrites the current HEAD version of foo with AA version. 这只是用AA版本覆盖当前HEAD版本的foo Tried the more verbose git checkout -m as well, same result: a dumb overwrite. 尝试了更详细的git checkout -m ,同样的结果:一个愚蠢的覆盖。

How do I force git to treat the AA version of foo as a conflicting merge with the current HEAD version? 我如何强制git将AA版本的foo视为与当前HEAD版本的冲突合并?

If git's merge isn't doing what you want, you could do the following instead: 如果git的合并没有做你想要的,你可以改为:

  1. Make sure that there are no uncommitted changes in the file foo , eg by making sure that git status is clean. 确保文件foo中没有未提交的更改,例如确保git status是干净的。
  2. Overwrite foo with the version from AA using: git show AA:foo > foo 使用AA的版本覆盖foogit show AA:foo > foo
  3. Selectively stage only the changes from foo that you want with: git add -p foo 有选择地只使用你想要的foo进行更改: git add -p foo
  4. Discard all the other changes to foo with git checkout -- foo 使用git checkout -- foo -foo丢弃foo所有其他更改
  5. Commit the staged changes: git commit 提交分阶段的更改: git commit

Alternatively, if you'd rather use a graphical diff tool (such as meld ), you could just do: 或者,如果您更喜欢使用图形差异工具(例如meld ),您可以这样做:

git show AA:foo > old-foo
meld old-foo foo

The previous answers do not keep the story of the change, so the fact that you used a previous commit to generate the new commit. 以前的答案不会保留更改的故事,因此您使用先前的提交来生成新的提交。 The following procedure will keep this story. 以下程序将保留这个故事。

git checkout -b merge-purgatory AA

here you need to slightly modify your file, for example you can add an empty line. 在这里你需要稍微修改你的文件,例如你可以添加一个空行。 Then 然后

git commit "pulled foo back from previous commit for merging into HEAD."
git checkout master
git merge --no-commit merge-purgatory

In this way the merge will fail and then all you need to do is to solve the conflict. 通过这种方式,合并将失败,然后您需要做的就是解决冲突。 This worked for me. 这对我有用。

git merge --no-commit merge-purgatory

would at least give you the opportunity to review:change the merge before committing it. 至少会给你机会审查:在提交之前更改合并。
See also techniques proposed in " How do you merge selective files with git-merge? ", based on cherry-picking or checkout. 另请参阅“ 如何使用git-merge合并选择性文件? ”中提出的技术,基于挑选或结帐。


Regarding forcing the manual merge, you could declare in a .gitatributes file , for that specific file, a merge policy set to unset . 关于强制手动合并,您可以在.gitatributes文件中声明该特定文件的合并策略设置为取消设置

Performing a three-way merge 执行三向合并

merge 合并

 The attribute merge affects how three versions of a file is merged when a file-level merge is necessary during git merge, and other commands such as git revert and git cherry-pick. 
Unset 

Take the version from the current branch as the tentative merge result, and declare that the merge has conflicts. 将当前分支中的版本作为暂定合并结果,并声明合并存在冲突。 This is suitable for binary files that does not have a well-defined merge semantics. 这适用于没有明确定义的合并语义的二进制文件。

I get rid of it using: 我使用以下方法摆脱它:

git checkout -f b855a13754fabf5cef6ff93ab00558608a839377 -- .

which forces the changes of the commit id into my current branch (master), then I created a new branch ( checkout -b ) from these applied changes and created a merge request from the latter. 这会强制将commit id更改为当前分支(master),然后我从这些应用的更改中创建了一个新分支( checkout -b ),并从后者创建了一个合并请求。

None of the above worked for me :-( 以上都不适合我:-(

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM