2

I was working on master branch and didn't realize that. I made a local commit 'a'. After that I did git pull, which brought in commit 'b'. After that I made another local commit 'c'. So now my HEAD is at commit 'c'. How do I create another branch with commits 'a' and 'c'? Essentially these commits should be removed from local master and put to the new branch.

After that I need to create a pull request by pushing this branch.

krackoder
  • 2,841
  • 7
  • 42
  • 51
  • Possible duplicate of [git: how to move a branch's root two commits back](http://stackoverflow.com/questions/43531189/git-how-to-move-a-branchs-root-two-commits-back) – Code-Apprentice May 05 '17 at 03:26
  • Your situation is a little more complicated than the above link. Hopefully it will still give you a starting point. – Code-Apprentice May 05 '17 at 03:28

2 Answers2

1

There are many options for this in GIT. Here is another one. Following your example and assuming that you're currently on master branch you can:

  1. Create a branch you would like to work on out of the last "appropriate" commit (probably the one that appears before you did your commit 'a', let call it X, in reality it will have some SHA1):

    git checkout -b mygoodbranch X

  2. Now you will switch automatically to this branch and make sure (just for the sake of understanding) that the last commit is indeed X. To see the last commit type the following and check:

    git log -1

  3. Its time to somehow move only your commits, right? In git the branch is just a pointer to the graph of commits. That's why the branch creation is cheap and fast, BTW. So just create yet another pointer to one of commits when you create a branch. We will go with cherry-picking here. This notion basically means that you can just take any arbitrary commit and "cherry-pick" it to your branch. The commit will have the same message but different SHA1. So we will identify SHA1-s of only your commits a and c here (you don't really need commit b, because you want to keep your branch clean from other's commits, right)? While being on branch mygoodbranch type:

    git cherry-pick <sha1 of a>

    git cherry-pick <sha1 of b>

    Check the result:

    git log -3

    You'll see that indeed that your branch now contains commits a and c, but they have a different SHA1 than original commits. Its important to understand at this point that git thinks that a original and a in your branch are different commits (because same commits have same sha1 and this is obviously not the case here). But who cares, we're going to "reset" master to commit X and it will not contain original commits a b c anymore. What we're going to do is to move the pointer of the master's "HEAD" (the current master branch state) to commit X that has So we will:

  4. Switch back to master

    git checkout master

  5. Execute actual reset:

    git reset --hard x_sha1

  6. Check the results (while being on master of course):

    git log -1

    Done! I know this was much longer explanations than my colleagues provided. I just wanted to show that git has many different options to achieve what you want and you can always find the one that works for you best.

Mark Bramnik
  • 39,963
  • 4
  • 57
  • 97
  • So when I do `git reset --hard` in step 5, it resets the head with the remote head? and when I do `git log -1` i n step 6, I should see the SHA of commit b? – krackoder May 05 '17 at 04:50
  • Sorry its a formatting issue in SO probably. I meant that the last parameter is sha1 of commit x. Git reset will just move the pointer to wherever you tell it. Hope this helps – Mark Bramnik May 05 '17 at 04:56
0

See git: how to move a branch's root two commits back for some tips. Basically, I suggest creating a new branch at the current master, resetting master to its original commit then pulling the update to master and rebasing the new branch to edit its history to your satisfaction.

Community
  • 1
  • 1
Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268