0

Some background:

  1. I forked from a upstream repository.
  2. Checkout develop branch from this fork a couple of weeks ago
  3. Performed some changes and checked in (Did not push yet)
  4. Meanwhile some other changes were pushed to develop branch of upstream.

Current situation.

Priority got changed and I had worked on another feature on same develop branch. I should have created a different branch but I continued to add that new feature of top of my current changes and checked in. This means my develop branch has all my 2 weeks changes + this one new feature.

What do I want to do ?

  1. I want to get the exact copy of upstream/develop onto my current (I do not want to create another branch) develop branch and apply only my latest change to it and push it.

  2. Apply my old two weeks work on top of this change on same branch. This I'll be pushing couple of days later.

Can somebody help me with git commands and explain what's happening at back ground ?

Things I tried. git reset --hard This tell me my head is detached.

git rebase -i upstream/branch. I think this is going to apply all my changes but I only want last change I did.

Robin Green
  • 32,079
  • 16
  • 104
  • 187
Jags
  • 47
  • 1
  • 6
  • 1
    I'm not 100% sure I follow you but it sounds like you have done work for two different things on the same branch. I would suggest a new branch for each feature, making 3 branches total and then cherry picking the changes needed for each feature to the correct branch. Then pushing those branches individually. With git there are often several ways to get the right result but they all can have different effects on the history. However, I personally don't see harm doing this, this way unless someone else has a better or more reasonable idea. – Michael Puckett II May 20 '18 at 19:01
  • Thanks for taking time and responding. Yes, you are correct. I have done two different work on same branch. When I do git reset --hard upstream/develop. Will this command erase my commits / changes I did ? – Jags May 20 '18 at 19:18
  • 1
    Possible duplicate of [When should I use git pull --rebase?](https://stackoverflow.com/questions/2472254/when-should-i-use-git-pull-rebase) – phd May 20 '18 at 19:52

1 Answers1

1

I imagine the commit graph corresponding to your situation to look like this:

        A--B--C--X [develop]
       /
o--o--o  <-- develop from couple of weeks ago
       \
        O--O [upstream/develop]

A--B--C is your two weeks work and X is your latest new feature.

Now you do the following:

1. Mark end of two weeks work

$ git branch twoweeks C

You need to figure out the hash of commit C and use it in the command, or alternatively, use a graphical repository browser to create the branch on that commit.

The branch is only temporary and will be removed again at the end, but we need it now to retain the two weeks work after the next step is done.

Result:

                X [develop]
               /
        A--B--C [twoweeks]
       /
o--o--o--O--O [upstream/develop]

2. Move new feature over

$ git rebase --onto upstream/develop twoweeks develop

Result:

        A--B--C [twoweeks]
       /
o--o--o--O--O [upstream/develop]
             \
              X [develop]

3. Move two weeks work over

$ git rebase develop twoweeks

Result:

o--o--o--O--O [upstream/develop]
             \
              X [develop]
               \
                A--B--C [twoweeks]

4. Clean up

  1. Push the new feature

    $ git checkout develop
    $ git push
    

    Result:

    o--o--o--O--O--X [upstream/develop] [develop]
                    \
                     A--B--C [twoweeks]
    
  2. Fast-forward local develop branch and remove temporary branch

    $ git checkout develop
    $ git merge --ff-only twoweeks
    

    (using --ff-only as sanity check, if it fails you did something wrong)

    $ git branch -d twoweeks
    

    Result:

    o--o--o--O--O--X [upstream/develop]
                    \
                     A--B--C [develop]
    

References

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
  • Thank you very much for taking time to respond. I did not really get git rebase --onto upstream/develop twoweeks develop part. I tried and it worked the way you said. is this what this command does ? 1. reset --hard upstream/develop 2. exclude all commit from twoweeks 3. include all commit from develop ? – Jags May 21 '18 at 02:19
  • I think I got it. Please correct me if I'm wrong. I think following command does this. (git rebase --onto upstream/develop twoweeks develop) 1. git reset --hard upstream/develop 2. Pick all commits between twoweeks and current head of develop and apply them on top of upstream/develop. – Jags May 21 '18 at 06:22
  • Although using rebase only modifies the branch after all commits have been applied to the new base, while using reset would move it at the start, which would make it more difficult to recover if something went wrong during the process. – mkrieger1 May 21 '18 at 21:04