Hacker News new | ask | show | jobs
by ajays 4052 days ago
I'm an SVN user, and I'll have to move to git some day, but it's not winning any points for me :-( . I got bit by it recently. I had cloned a repo, and then a few weeks later, did

    % git status
    On branch master
    Your branch is up-to-date with 'origin/master'.
    nothing to commit, working directory clean
I assumed the working copy was up-to-date, as git states.... but alas, no. I had to do a "git pull" to get the latest changes. Why doesn't git tell you that your copy is out of date?
8 comments

Git does not check with the remote unless you tell it to. So "origin/master" points to what master on origin pointed to the last time git contacted the origin remote.

To have git contact the remote again, you can do "git fetch origin" (or just "git fetch"). Then git will tell you your copy is out of date compared to origin/master, if there's been commits on origin since.

If you commit things, then your copy will be ahead of origin/master, so origin/master is what is out of date and you need to git push:

    ~/dotfiles % git status            ✓✗ master:c024cb4 - dotfiles 
    On branch master
    Your branch is ahead of 'origin/master' by 1 commit.
      (use "git push" to publish your local commits)
Yeah, but your branch isn't up-to-date is it? It's bad wording.
It's up to date with origin/master, which is the local copy of the remote master. 'git fetch' updates those local copies. 'git pull' does a fetch and then merges origin/master into master.

It makes sense when you consider that there are other ways that origin/master could be updated. You could apply commits that someone emailed you (a common workflow in the Linux kernel that git was designed to support), or someone could push commits directly to you over SSH or the filesystem.

`git fetch` and `git push` talk to the remote(s) (if any) that you have configured. Most (all?) other commands are local operations. `git status` compares your working copy to your local `.git/` database.

If you want `git status` to compare `.git/` with the state of a remote, you must first `git fetch` the state of a remote into your local `.git/`. And you may have multiple remotes, as well...

I've used git for years after having spent years with SVN. no one taught me SVN and never really read much documetation. It was so simple and straightforward. Git introduces a lot of new power and features, but nowhere near the cost increase of the learning to use it. FWIW, I always hoped Mercurial would win. It's at near feature parity with git, but is far easier to use.
>I always hoped Mercurial would win.

We're definitely staging a comeback. Mercurial's development is lively and interesting, and with the backing of the likes of Google, Facebook, Mozilla, and Atlassian, we definitely are seeing lots of good stuff in hg.

Because git lied to you. When it says "you are up-to-date with origin/master" it did not actually check that it is up to date with the code on the origin. This is one reason why Git is inhumane. It's reasonable that it didn't check with the remote repo, but its misleading use of the word "origin" does not help new users.
> It's reasonable that it didn't check with the remote repo, but its misleading use of the word "origin" does not help new users.

But 'origin' is just the name of the remote repository, not something hardwired into git, right? (Maybe this response is undercut by the fact that it is the default name.)

As others have said, you'd need to do 'git fetch' first before 'git status' would report a difference.

The reason git doesn't do this automatically is because, in its simple model, it doesn't waste time trying to connect to the remote 'origin' or any other remotes you may have configured every time you do 'git status', which is most often used to check what you've modified locally.

I can understand why this would be jarring coming from SVN, where you always want to be checking against the remote/server. Since git has a copy of all history locally, remotes are de-emphasized compared to centralized VCSs.

Git maintains a local copy of remote branches (to some extent, I'm not sure of the mechanics) and I believe you can cause it to update that with 'git remote update', 'git fetch' and a couple of other tools.
If you have a branch called "master", whose HEAD is currently "a4300d840a4d01767cb2e768e51f7e88cb40e8cb", for example, all that means is that there is a text file called ".git/refs/heads/master" which has the contents "a4300d840a4d01767cb2e768e51f7e88cb40e8cb".

That's all there is to a branch. Do:

    cat .git/refs/heads/master
in any git repo you have on your machine and see (compare it with 'git log')

If you have a remote branch that points to the same commit, all that means is that there is a text file called ".git/refs/remotes/origin/master" which has the contents "a4300d840a4d01767cb2e768e51f7e88cb40e8cb". Again, that's all there is to a remote branch.

Well, ok, there's also an entry in your ".git/config" file that gives the URI for "origin" (or whatever you've named your remote server; origin is the default).

All these files are just text files. Have a look at them in your favourite text editor (or with less or whatever).

Same reason your OS won't upgrade your packages unless you update the package list from the repository. I can empathize with the confusion coming from SVN.
I think it's safest to assume that any `git` command that doesn't by necessity make a request to the remote repo (like `git {fetch,pull,push}` and others) does not make a request to the remote repo.