Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to rebase after git-subtree add?

I'm trying to learn the new git-subtree command which was added in Git 1.7.11. I seem to lose ability to rebase after I add a subtree. I have the primary repository with README file and a library repository which also has a README file. I add it to lib directory with subtree add:

$ git subtree add -P lib/mylib myliborigin master 

This works fine, but now the history looks like this:

*   22c1fe6 (HEAD, master) Merge commit 'b6e698d9f4985825efa06dfdd7bba8d2930cd40e' as 'lib/mylib' -  |\                                                                                                                 | * b6e698d Squashed 'lib/mylib/' content from commit d7dbd3d * b99d55b Add readme * 020e372 Initial 

Now when I want to rebase my repo against origin/master and it fails because the squash commit is applied directly against its parent commit which does not apply, because it is applied to the root of the repo and not the prefix I gave it to it when adding the subtree.

The reason for this is pretty clear if I look at the squash commit. There is no information about the prefix. It is just the original mylib commits squashed together. Only the next merge commit knows anything about it, but rebase does not take it to account here.

Are there any workarounds (besides never rebasing over the subtree commits)?

like image 970
Epeli Avatar asked Oct 12 '12 11:10

Epeli


People also ask

What is the golden rule of rebasing?

The Golden Rule of Rebasing reads: “Never rebase while you're on a public branch.” This way, no one else will be pushing other changes, and no commits that aren't in your local repo will exist on the remote branch.

How do you continue rebasing?

After changes have been made, the changes need to be staged to the commit and then the rebase can resume using git rebase --continue . There is also the option of running git rebase --abort while resolving conflicts in a rebase, which will cancel the rebase and leave the branch unchanged.


1 Answers

This works in simple cases:

git rebase --preserve-merges master 

Thanks to @Techlive Zheng in the comments.


You may see

fatal: refusing to merge unrelated histories Error redoing merge a95986e... 

Which means that git failed to automatically apply your subtree. This puts you in the situation @ericpeters described in his answer. Solution:

Re-add your subtree (use the same command you originally used):

git subtree add -P lib lib-origin master 

Continue the rebase:

git rebase --continue 

And you're all set!


If you're wondering if it worked successfully, you can compare with your original version after rebasing to make sure you didn't change anything:

git diff <ref-before-rebase> <ref-after-rebase> -- . 

(the -- . at the end instructs git to only diff the files in your current directory).


If all else fails and you don't care about preserving the commits themselves, you can simply git cherry-pick the original subtree commit.

The commit message will look something like Add 'lib/' from commit '9767e6...' -- that's the one you want.

like image 137
Kevin Cooper Avatar answered Sep 18 '22 15:09

Kevin Cooper