在Git中混合合并两条历史尾巴 [英] Intermingling merge-basing two history tails in Git

查看:124
本文介绍了在Git中混合合并两条历史尾巴的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个独立的历史Git仓库。经过大量研究和大量修补之后,我终于看到了这样的历史(使用 YYYY-DD 作为伪提交哈希):

  HEAD --- 2016-09 --- 2016-08 --- 2016-07 --- 2016-06 
\- ---- 2015-10 --- 2015-09

请注意,此历史似乎有两个根,因为 2015-10 序列被合并/嫁接到中间。重要的是, 2016-07 历史记录和 2015-10 历史记录中的文件完全包含不同的文件,没有任何共同之处。



我想将这个历史记录合并成一个完整的提交行,最新的,没有跳过(即消失的内容,后来再次出现)。换句话说,这是我最终想要的结果:

  HEAD --- 2016-09 ---(2016-08)--- 2016-07 --- 2016-06 --- 2015-10 --- 2015-09 

我把(2016-08)放在圆括号中,因为作为合并提交我甚至不认为我需要它,如果一切正常的话。



起初我认为做一个 git replace --edit 2016- 08 删除它的 2015-10 父项,然后一个 git replace --edit 2016-06 2015-10 作为其父母(请参阅 https:/ / stackove rflow.com/a/37001417/421049 ),果然,在完成后git filter-branch --tag-name-filter cat - --all

但是后来我开始思考:因为内容完全不同于两个尾巴, 2015-10 中的内容不会在 2016-06 中消失,然后回来在 2016-08 ? (我承认,我不能马上验证它是否现在做了,我抹掉了那次尝试,我今天晚上又累又不能这样做了。)我怎样才能有效地融合(在日常意义上)两条尾巴,就好像 2016-06 中的内容已添加到 2015-10 中的内容上?也就是说,无论替换 2016-06 的任何提交都将包含 2015-10 中的所有内容, 原始 2016-06 中的内容?不过,我希望新的 2016-06 具有其原始提交日期,日志消息等。

然后,在完成之后,如何从历史中删除合并提交 2016-08 ,因为它不再需要?我假设我可以使用 git rebase - 于2016-08〜2016-08 HEAD from https://stackoverflow.com/a/3705310/421049 。我在最初的尝试中尝试过,但它没有奏效---我认为它与 2016-07 中消失的内容有关, code> 2016-06 因为我只是按不同的顺序重新调整了尾巴,但我不确定。



我道歉如果这是一个重复的问题,但经过几个小时的工作并深入研究历史(并小心翼翼地用vi翻译),我有一点Git疲劳。

解决方案

关于一个简化的例子,我能够

  git checkout -b中级2016-07 
git rebase 2015-10

这会在2015-10年之前重新提交2016-07和2016-06的提交信息

  git checkout master 

假设您的主点指向2016-09或后代

  git rebase middle 

至极在我们刚刚创建的新中间顶部重播2016-09(或更多,取决于您的主人)。如果您说, 2016-07历史记录和2015-10历史记录中的文件 包含完全不同的文件,没有任何共同之处这应该给你一个很好的历史没有冲突。


I have two Git repositories with separate histories. After much researching and a lot of tinkering, I wound up with a history that looks like this (using YYYY-DD as pseudo commit-hashes):

HEAD---2016-09---2016-08---2016-07---2016-06
                     \-----2015-10---2015-09

Note that this history appears to have two "roots", as the 2015-10 sequence was merged/grafted into the middle. The important thing is that the files in the 2016-07 history and the 2015-10 history contain completely different files with nothing in common.

I would like to combine this history into one complete line of commits, in original commit order from oldest to newest, with no skips (i.e. disappearing content that reappears later). In other words, here is what I want to end up with:

HEAD---2016-09---(2016-08)---2016-07---2016-06---2015-10---2015-09

I put (2016-08) in parentheses, because as a merge commit I don't even think I need it if all goes correctly.

At first I thought do a git replace --edit 2016-08 to remove its 2015-10 parent, and then a git replace --edit 2016-06 to put the 2015-10 as its parent (see https://stackoverflow.com/a/37001417/421049), and sure enough, after doing a git filter-branch --tag-name-filter cat -- --all I got a single sequence that looked like what I wanted.

But then I started thinking: because the content was completely different in the two "tails", won't the content in 2015-10 "disappear" in 2016-06 and then "come back" in 2016-08? (I confess I can't immediately verify whether it did or not right now; I erased that attempt and I'm too tired to do it again tonight.) How can I effectively "merge" (in the everyday sense) the two tails, as if the content in 2016-06 was added onto the content in 2015-10? That is, whatever commit that replaces 2016-06 will have all the content in 2015-10 along with the content in the original 2016-06? However I want the new 2016-06 to have its original commit date, log message, etc.

Then, after that's done, how do I remove the "merge" commit 2016-08 from the history, as it's not needed anymore? I assume I can use git rebase --onto 2016-08~ 2016-08 HEAD from https://stackoverflow.com/a/3705310/421049. I tried it in the initial attempt, but it didn't work --- I assume it had something to do with the content that "disappeared" in 2016-07 and 2016-06 because I just restitched the tails in a different sequence, but I'm not sure.

I apologize if this is a duplicate question, but after hours of working with this and getting deep into histories (and gingerly poking around in vi), I have a little "Git fatigue" for the day. Thank you in advance.

解决方案

on a simplified example, i was able to

git checkout -b middle 2016-07
git rebase 2015-10

this replays your commits 2016-07 and 2016-06 on top of 2015-10

git checkout master

assuming your master points to 2016-09 or a descendant

git rebase middle

wich replays 2016-09 (or more, depending on your master) on top of the new middle we just created. this rebase will also discard the merge commit.

if, as you say, the files in the 2016-07 history and the 2015-10 history contain completely different files with nothing in common this should give you a nice history without conflicts.

这篇关于在Git中混合合并两条历史尾巴的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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