Zach
Zach

Reputation: 63

Use of origin in Git commands

I'm new to Git and have a question. These two commands seem to be a common pairing:

git fetch --all
git reset --hard origin/master

If my goal is to reset a local clone to a clean state, how is this different than either of the following?

git fetch --all
git reset --hard master
# no origin

Or

git reset --hard origin/master
# no fetch

It seems like fetching first isn't needed if we are going to specify the remote directly anyway. Am I misunderstanding something? Is this a convention with a purpose or just a tradition/habit without basis?

Why I'm asking:

I'm writing scripts for a build machine. I want to fetch everything at one point in time, and then work from the local content for the duration of the build so there isn't a chance of changes being made part-way through a build. It seems like I would want to fetch from the remote once and not specify origin in commands after that. However, I'm having a hard time finding examples of that online, so I wasn't sure if there was something I was missing.

Upvotes: 0

Views: 67

Answers (1)

Schwern
Schwern

Reputation: 165586

First the basics of remote branches. Your repository looks something like this.

A - B - C [origin/master]
         \
          D - E [master]

master and origin/master are both branches, which are just labels that point at a commit. In this case, you've made two commits to master since the last time you fetched.

Git doesn't talk to the network unless you tell it to. It keeps track of the last time it looked at a remote repository with a "remote branch". origin/master is a "remote branch". It is your local copy of the master branch on the remote named origin updated the last time git fetch origin or git fetch --all was run (or git pull, which does a fetch).


git reset --hard origin/master

This is used to throw out all your local work. This will reset the current branch and working directory to where origin/master is, which is C. D and E will be lost.

A - B - C [origin/master]
         \
          D - E [master]

git reset --hard origin/master

A - B - C [origin/master]
          [master]

git reset --hard master

This will reset your current branch and working directory back to master. If you happen to be on master this will undo your uncommitted work. But if you're on a different branch, you just blew away your branch.

To throw out your uncommitted changes, the safer thing to do is git reset --hard HEAD. HEAD is a pointer to the currently checked out commit. It will work no matter what branch you're on. I have it aliased to clear.


I want to fetch everything at one point in time, and then work from the local content for the duration of the build so there isn't a chance of changes being made part-way through a build.

Git does not talk to the network unless you tell it to. There's two commands which will update your local repository, git fetch and git pull (which does a fetch). If you don't run those, your origin/ remote branches will not change.

If you fetch and checkout at the start of your build, you'll be fine. If you need to reset to a clean state you can run git reset --hard HEAD. You might also want to run git clean -dxf which will throw out any untracked or ignored files like build artifacts.

Upvotes: 2

Related Questions