vashishatashu
vashishatashu

Reputation: 8142

What's the difference between `git reset --hard master` and `git reset --hard origin/master`?

I tried a lot of links on Stackoverflow/elsewhere to properly understand behaviour of

git reset --hard option

I know that:

What I don't understand are the following values:

  1. origin
  2. HEAD
  3. origin/master
  4. origin/branch

All seem to have same behavior i.e. they a point to latest commit on master.

Please explain what is the significance of all 4 value option provided above.

I would also like to know if I am on a specific branch how can I reset to the last commit on that very branch? If for example I am on v1.2, origin/v1.2 still takes me to latest commit on master.

Upvotes: 9

Views: 18938

Answers (2)

Tobia Tesan
Tobia Tesan

Reputation: 1936

master, HEAD, origin/something and maybe some tag, why not, may all point to the same commit, but they are most definitely not the same thing.

origin is usually the name of a remote repository.

You can see your remotes and configure new ones with git remote -v.

Try it (with -v) and it will probably make sense.

remote/somebranch points to the head of some branch on a remote repository.

origin/master points to the head of master on origin.

Is it the same as master?

Yes and no. If you pull your master branch, do some work and in the meantime somebody else commits on master and pushes to origin, they will differ.

When you do a git fetch origin, then, origin/master will have additional commits (will be ahead).

HEAD is simply "the current commit". Think of it as ..

See this question

Again, this could be the same as master, but if you check out another branch or commit or are in the middle of a rebase, well, it's not.

So try this on a fresh repository on which nobody else is working:

$ git checkout master
$ git log -1 --format="%H" HEAD
123abc
$ git log -1 --format="%H" origin/master
123abc

They are the same!

$ git diff origin/master

Of course their content is the same.

$ echo "foo" > foo
$ git add foo
$ git commit -m "Foo the thingy"
$ git log -1 --format="%H" HEAD
321bca
$ git log -1 --format="%H" origin/master
123abc

Ah, look, now they're different commits!

$ git push origin master
$ git log -1 --format="%H" HEAD
321bca
$ git log -1 --format="%H" origin/master
321bca

And now they aren't! we have pushed our latest commit and they both point to the same.

$ git checkout -b newbranch
$ echo "baz" > baz
$ git add baz
$ git commit -m "Baz the thingy with the stuff"
$ git branch -a
  master
* new_branch
  origin/master
$ git log -1 --format="%H"
789def
$ git log -1 --format="%H" master
321bca
git log -1 --format="%H" origin/master
321bca
git log -1 --format="%H" origin/new_branch
unknown revision or path not in the working tree.

Of course not. We haven't pushed new_branch to origin, it is only on our local machine

git checkout 123abc

We have just checked out 123abc, the old head of master. It is not the head of any branch, now, but we can check it out just the same.

Note: checking out 123abc. You are in 'detached HEAD' state, etc
$ git checkout -b old_master
$ git branch -a
  master
* new_branch
  origin/master
  old_master

Now guess what their SHA1 will respectively be?

Upvotes: 4

Mohammad AbuShady
Mohammad AbuShady

Reputation: 42789

First of all you need to understand that branch and tag names are just pointers to hash values, which represent a single commit, if you say that there's 4 options that have the same behaviour, then the first logical answer is because they all point to the same commit

  • origin I'm not sure about this but i think origin by it self will resolve to origin/HEAD which i think will be dependent on your github settings, in github you set a 'default branch', origin/head will resolve to origin/[default_branch], in your case im assuming it's master, so this is why it has the same effect as origin/master.

  • HEAD always points to the current commit, the one you are standing on, so a git reset --hard HEAD will permenantly remove all changes in tracked files and staged files changes, but not change the commit hash.

  • origin/master is last commit in the remote master branch since your last fetch/pull, each time you commit to master, your local master is updated and your origin/master is updated too, if someone else pushes to master your repo will have no idea that there is an update, unless you do a git fetch then your origin/master will move ahead of your master, or maybe even diverge.
    running a git reset --hard origin/master will have the same effect if you are currently are on the master branch and the master is in sync with origin/master

  • origin/branch I'm not sure what this represents, because there's no origin/branch by default, so I'm guessing you created a branch called branch and happens to be in the same commit as your master, to confirm you can try doing a git branch to see all your branches, i'm guessing you'll find one called branch

To see all this in a visual way, you could try running git log --graph --decorate --all or I prefer a visual tool like gitk, if you have the binary installed you would run gitk --all to see all branches relative to each other

Upvotes: 14

Related Questions