-1

I created a feature branch from the master branch, made some changes. Then I forgot to stage and commit them into the feature branch, and hadn't touch the repository for a while.

Recently, I went back to the repository, without remembering what I did, and switched to the master branch. I guess that at that point the changes remained in the working directory, and I accidentally committed the changes into the master branch.

Now When I switch to the feature branch, the feature branch doesn't have the changes i.e. is like the original master branch, and the master branch has the changes i.e. is like what the feature branch should have been. I did a git diff feature..master, and the only difference between them is the changes.

How can I correct the mistake?

Thanks.

halfer
  • 19,824
  • 17
  • 99
  • 186
Tim
  • 1
  • 141
  • 372
  • 590
  • rename master to tmp, feature to master, tmp to feature http://stackoverflow.com/questions/6591213/how-do-i-rename-a-local-git-branch – Marcin Krasowski Apr 20 '17 at 23:20
  • @MarcinKrasowski although I guess that might work, I can't guarantee that the feature is exactly what the master should have been, and the master is exactly what the feature should have been. Is there a more conservative / safe way ? – Tim Apr 20 '17 at 23:26
  • This is another way to do it. You can do it without fear. Just in case, you have ```git reflog``` to get things the way they were originally. – eftshift0 Apr 21 '17 at 01:02
  • In this particular case, you can safely follow Marcin's suggestions since it appears that you did not make any commits to `feature`. Edmundo's answer results in the same thing with fewer commands. My answer below is more general purpose as it preserves any commits to `feature`, in the case that there are any. – Code-Apprentice Apr 21 '17 at 01:07
  • @Code-Apprentice Thanks. How can i verify that I didn't make any commit to the feature branch? – Tim Apr 21 '17 at 01:11
  • "I did a git diff feature..master, and the only difference between them is the changes." This suggests that there are no commits to the feature branch. You can use `git checkout feature` and `git log` to view the commit history to verify. – Code-Apprentice Apr 21 '17 at 01:12
  • For more detail, you can do `git log --all --graph --oneline --decorate` to see all commits in a graph format and annotated with branch names. – Code-Apprentice Apr 21 '17 at 01:16
  • @Code-Apprentice Thanks. The graph output is intuitive, though I don't know what the text within parentheses following commit names mean. For example, I have run the commands in Edmundo's reply. If I checkout feature and run `git log --all --graph --oneline --decorate`, the first two lines are ` e5ae861 (HEAD -> feature)...` and `3509baa (origin/master, master)...`. If I checkout master and run `git log --all --graph --oneline --decorate`, the first two lines are `e5ae861 (feature)...` and `3509baa (HEAD -> master, origin/master)... `. Some document that helps me understand the graph? – Tim Apr 21 '17 at 02:17
  • You can do `git help log` or google `git log` for the man pages for git log. You can also post a new question here on SO. This actually seems like a very good question that will be helpful to future git users. – Code-Apprentice Apr 21 '17 at 02:22

2 Answers2

1

I would do this: git checkout master git branch -f feature # move feature pointer to the commit it should be on git reset --hard HEAD~1 # set master one revision back, where it should be

eftshift0
  • 26,375
  • 3
  • 36
  • 60
  • This is only half the answer since it essentially throws away the changes that were accidentally committed to `master`. – Code-Apprentice Apr 21 '17 at 00:57
  • Not actually. What is happening is that the branch references are _switched_. feature ends up being where master is, then master end up where feature was in the beginning. All original commits are actually visible from *feature* in the end. – eftshift0 Apr 21 '17 at 01:00
  • Then it throws away all the changes in `feature` which were not yet in `master`. – Code-Apprentice Apr 21 '17 at 01:01
  • From the "starting scenario", feature is one revision behind master. By placing feature where master is (when I ask to do git branch -f feature) you are not leaving anything out. Feature is now magically right on top of the revision where master is. Then git reset --hard will take master one revision back in history. Nothing is lost. – eftshift0 Apr 21 '17 at 01:04
  • On my first reading, I thought that `feature` was ahead of master before the erroneous commit. – Code-Apprentice Apr 21 '17 at 01:06
1

I assume you want to accomplish two things:

  1. Move the changes that you accidentally committed to master so that they are on feature.
  2. Reset master back to its original location.

Here's how you do it:

  1. Create a temporary branch where master is currently:

    $ git checkout -b temp master
    
  2. Reset master back one commit:

    $ git checkout master
    $ git reset --hard HEAD~1
    
  3. Move the commit from the temporary branch on top of the feature branch:

    $ git checkout temp
    $ git rebase --onto feature master
    
  4. Move the feature branch to include all the changes:

    $ git checkout feature
    $ git merge temp
    
  5. Delete the temporary branch:

    $ git branch -d temp
    
Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268