Olivier Girardot
Olivier Girardot

Reputation: 409

I am working on a branch, and I want to go back to master ignoring all the changes I did on the branch

I was working on a branch yesterday, and, on second thoughts, I wanted to try a completely different approach. Which meant going back to master to recover my original code, and start over from a new branch. It turns out that my master branch had kept all the changes I made to my code in the branch. From what I understand, it's because I didn't commit my branch, is that correct ?

Basically, git only "validates" a branch once you commit it, otherwise it's like you are still working from the master, am I right?

Upvotes: 1

Views: 2813

Answers (2)

CodeTalker
CodeTalker

Reputation: 1791

Assuming you created a branch (temp_work) from a committed master branch and you worked in the temp_work branch. Now you did not commit the temp_work, you want to go back to the master branch ignoring work done in temp_work.

------> master
           \
            \-----> temp_work
                          ^
                          |
                        Head

If you switch back to master without committing on temp_work, all your changes will be visible in master branch too. This is because you did not commit in temp branch.

To switch to original master branch contents ignoring all changes in the temp_branch, you do in two ways

Solution 1

  • Commit temp_work.
git add .
git commit -m "temp_work"
  • Switch to master branch

git checkout master

  • Delete temp_work branch (if you don't need it anymore)

git branch -D temp_work

Solution 2 (The one I use)

  • Switch to temp_work branch

git checkout temp_work

  • Stage all changes and Stash all your changes
git add .
git stash
  • Switch to master branch

git checkout master

  • Delete the top stashed work

git stash drop

Upvotes: 3

CodeWizard
CodeWizard

Reputation: 142114

Before answering, let's add some background, explaining what this HEAD is.

First of all what is HEAD?

HEAD is simply a reference to the current commit (latest) on the current branch.
There can only be a single HEAD at any given time (excluding git worktree).

The content of HEAD is stored inside .git/HEAD and it contains the 40 bytes SHA-1 of the current commit.


detached HEAD

If you are not on the latest commit - meaning that HEAD is pointing to a prior commit in history it's called detached HEAD.

Enter image description here

On the command line, it will look like this - SHA-1 instead of the branch name since the HEAD is not pointing to the tip of the current branch:

Enter image description here

Enter image description here


A few options on how to recover from a detached HEAD:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

This will checkout new branch pointing to the desired commit.
This command will checkout to a given commit.
At this point, you can create a branch and start to work from this point on.

# Checkout a given commit.
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# Create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

You can always use the reflog as well.
git reflog will display any change which updated the HEAD and checking out the desired reflog entry will set the HEAD back to this commit.

Every time the HEAD is modified there will be a new entry in the reflog

git reflog
git checkout HEAD@{...}

This will get you back to your desired commit

Enter image description here


git reset --hard <commit_id>

"Move" your HEAD back to the desired commit.

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts if you've modified things which were
# changed since the commit you reset to.
  • Note: (Since Git 2.7) you can also use the git rebase --no-autostash as well.

git revert <sha-1>

"Undo" the given commit or commit range.
The reset command will "undo" any changes made in the given commit.
A new commit with the undo patch will be committed while the original commit will remain in the history as well.

# Add a new commit with the undo of the original one.
# The <sha-1> can be any commit(s) or commit range
git revert <sha-1>

This schema illustrates which command does what.
As you can see there, reset && checkout modify the HEAD.

Enter image description here

Upvotes: 1

Related Questions