Intermingling merge-basing two history tails in Git

我是研究僧i 提交于 2020-01-14 03:13:09

问题


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.


回答1:


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.



来源:https://stackoverflow.com/questions/43959753/intermingling-merge-basing-two-history-tails-in-git

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!