1

I have a branch off of master, called A, that I wanted to create a new branch off of, B. Except I messed up and created B off of master.

Desired:

master
   \
    A
     \
      B

Actual:

master
 \  \
  A  B

B only has one commit that I need, but because it was based off of master and not A the diff is huge. To make things worse, I tried git rebase -i A and squashed everything except for the one commit I wanted seen, but this seemed to just rebase off of master again. So now I have a reflog that basically looks like this:

B@{0}: rebase: B onto master
B@{1}: commit
B@{2}: rebase: B onto master
B@{3}: branch B created

What I need to figure out is how to get just the one commit out and base it off of A so that I can make a pull request where the diff isn't huge.

Edit: might be good to note that A is not up-to-date with master, it is still many commits behind. So the erroneously rebased B is now "ahead" of A.

Josh K
  • 79
  • 1
  • 12
  • 1
    Does your `git reflog` still contain the unsquashed commits in B? If so, you might be able to use [cherry-pick](https://git-scm.com/docs/git-cherry-pick#_examples) to apply just those commits to A. – OSH Jul 14 '20 at 01:14
  • Note that B's reflog (`git reflog B`) will retain (for 30 days by default) all the original commits, pre-inappropriate-rebase, so that you can get them back. In this case I think `B@{3}` should be that one commit, or maybe it's `B@{1}`. – torek Jul 14 '20 at 15:34
  • @OSH this worked, thank you! – Josh K Jul 14 '20 at 17:58

2 Answers2

1

Here is how I solved my problem:

I created a new branch off of A, called C.

git checkout A
git checkout -b C

I then did git cherry-pick SHA-B where SHA-B is the SHA from the commit I wanted, which thankfully was saved in the reflog (B@{1} from the original post). Then all I had to do was resolve the conflicts and commit.

Josh K
  • 79
  • 1
  • 12
0

but because it was based off of master and not A the diff is huge

Still, you could try and generate a patch, using the right base

git format-patch --base=$(git merge-base A master) -M -C B~..B

Then you can use git am to apply it on top of A

If that B commit is the result of a rebase, you can indeed find it in the reflog (90 days by default before being purged).
You can use the date as well to pinpoint the right old B:

 git reflog --format='%C(auto)%h %<|(20)%gd %C(blue)%cr%C(reset) %gs (%s)' B

Then you can use the format-patch, replacing B~..B by the old B commit reference found in the reflog.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • When I do `git apply --stat patch_filename.patch`I still see a huge diff... is this expected, or should I only be seeing my intended commit here? – Josh K Jul 14 '20 at 17:37