When git reloads two branches with some shared history, is there an easy way to keep the shared story shared?

Suppose we have the following revision schedule:

AXZ--B \ \-C 

with A preceding both B and C. Next, suppose I rebase A from the upstream, creating a new commit A *, and then rearrange B and C to A *. The resulting resulting graph is as follows:

 A*-X'-Z'-B \ \-X"-Z"-C 

Please note that the shared story is no longer used. Is there an easy way to fix this other than, say, reinstalling B, and then explicitly overload C to Z '. In other words, is there a better way to automatically reinstall multiple branches at the same time in order to maintain a common history? It seems a little inconvenient to either artificially place the tag at the split point, or manually check the schedule to find out the sha1 commit on which you need to reinstall C to save the general history, not to mention the discovery of the possibility of errors, especially since I have to do it every time when I reinstall until I check for changes in the branch upstream.

+16
git git-rebase
Apr 11 '11 at 10:20
source share
2 answers
 git rebase --committer-date-is-author-date --preserve-merges --onto A* AC git rebase --committer-date-is-author-date --preserve-merges --onto A* AB 

This should contain shared commits having the same sha1, and any merges are preserved. Preserving mergers is not required in this case, but will become a problem with a less trivial story.

To do this for all branches containing A in their history, do:

 git branch --contains A | xargs -n 1 git rebase --committer-date-is-author-date --preserve-merges --onto A* A 

Hope this helps.

UPDATE:

This could be a cleaner syntax:

 for branch in $(git branch --contains A); do git rebase --committer-date-is-author-date --preserve-merges --onto A* A $branch; done 
+14
Apr 12 2018-11-11T00:
source share

Task in the general case

I was asked a similar problem: reloading the whole backstory - several branches with some connections between them resulting from the merge:

 A--B-B2-topicB \ / \-C-C2-topicC 

If I do multiple git rebase sequentially (for topicB and topicC), I doubt that merges between branches can be saved correctly. Thus, I would have to reload all the branches at once , hoping that this would restore them correctly.

Solution working in a specific subframe

In my case, I was fortunate that topicC was actually merged into topicB, so I could reinstall the whole background, I could just run

 git rebase -p A* topicB' 

(A * is the new base, as in your question), and then reset all the remaining ref segments (and tags) to the new corresponding commits (in the new history), for example

 git branch -f topicC C3' 

It worked. (Moving ref links and tags is possible with a script .)

A β€œsolution” for a general case inspired by this particular

If topicC was not merged into topicB, I could create a fake top commit to merge all the branches that I want to reinstall, for example:

 git checkout -b fake topicB git merge -s ours topicC 

and then reinstall it like this:

 git rebase A* fake 

and reset the theme goes to new commits, removes the fake branch.

+2
Mar 14 '12 at 17:00
source share



All Articles