Why does git status show branch is up-to-date when changes exist upstream?

Git

Git Problem Overview


Changes exist upstream in a tracked branch, but when I type git status it indicates that my local branch is up-to-date. Is this new behavior, did I change a config setting, or is something wrong?

Thanks for the help.

ubuntu@host:/my/repo# git status
On branch master
Your branch is up-to-date with 'origin/master'.

nothing to commit, working directory clean


ubuntu@host:/my/repo# git pull
remote: Counting objects: 11, done.
remote: Compressing objects: 100% (11/11), done.
remote: Total 11 (delta 6), reused 0 (delta 0)
Unpacking objects: 100% (11/11), done.
From bitbucket.org:my/repo
   1234567..abcdefg  master     -> origin/master
Updating 1234567..abcdefg
Fast-forward
 file1        |  1 -
 file2        | 43 +++++++++++++++++++++++++++++++++++++++++++
 file3        | 21 ++++++++++++---------
 file4        | 21 ++++++++++++---------
 4 files changed, 67 insertions(+), 19 deletions(-)
 create mode 100644 file5

Git Solutions


Solution 1 - Git

What the status is telling you is that you're behind the ref called origin/master which is a local ref in your local repo. In this case that ref happens to track a branch in some remote, called origin, but the status is not telling you anything about the branch on the remote. It's telling you about the ref, which is just a commit ID stored on your local filesystem (in this case, it's typically in a file called .git/refs/remotes/origin/master in your local repo).

git pull does two operations; first it does a git fetch to get up to date with the commits in the remote repo (which updates the origin/master ref in your local repo), then it does a git merge to merge those commits into the current branch.

Until you do the fetch step (either on its own or via git pull) your local repo has no way to know that there are additional commits upstream, and git status only looks at your local origin/master ref.

When git status says up-to-date, it means "up-to-date with the branch that the current branch tracks", which in this case means "up-to-date with the local ref called origin/master". That only equates to "up-to-date with the upstream status that was retrieved last time we did a fetch" which is not the same as "up-to-date with the latest live status of the upstream".

Why does it work this way? Well the fetch step is a potentially slow and expensive network operation. The design of Git (and other distributed version control systems) is to avoid network operations when unnecessary, and is a completely different model to the typical client-server system many people are used to (although as pointed out in the comments below, Git's concept of a "remote tracking branch" that causes confusion here is not shared by all DVCSs). It's entirely possible to use Git offline, with no connection to a centralized server, and the output of git status reflects this.

Creating and switching branches (and checking their status) in Git is supposed to be lightweight, not something that performs a slow network operation to a centralized system. The assumption when designing Git, and the git status output, was that users understand this (too many Git features only make sense if you already know how Git works). With the adoption of Git by lots and lots of users who are not familiar with DVCS this assumption is not always valid.

Solution 2 - Git

This is because your local repo hasn't checked in with the upstream remotes. To have this work as you're expecting it to, use git fetch then run a git status again.

Solution 3 - Git

While these are all viable answers, I decided to give my way of checking if local repo is in line with the remote, whithout fetching or pulling. In order to see where my branches are I use simply:

git remote show origin

What it does is return all the current tracked branches and most importantly - the info whether they are up to date, ahead or behind the remote origin ones. After the above command, this is an example of what is returned:

  * remote origin
  Fetch URL: https://github.com/xxxx/xxxx.git
  Push  URL: https://github.com/xxxx/xxxx.git
  HEAD branch: master
  Remote branches:
    master      tracked
    no-payments tracked
  Local branches configured for 'git pull':
    master      merges with remote master
    no-payments merges with remote no-payments
  Local refs configured for 'git push':
    master      pushes to master      (local out of date)
    no-payments pushes to no-payments (local out of date)

Hope this helps someone.

Solution 4 - Git

I have faced a similar problem, I searched everywhere online for solutions and I tried to follow them. None worked for me. These were the steps I took to the problem.

Make new repo and push the existing code again to the new repo

git init doesn’t initialize if you already have a .git/ folder in your repository. So, for your case, do -

(1) rm -rf .git/

(2) git init

(3) git remote add origin https://repository.remote.url

(4) git commit -m “Commit message”

(5) git push -f origin master

Note that all git configs like remote repositories for this repository are cleared in step 1. So, you have to set up all remote repository URLs again.

Also, take care of the -f in step 5: The remote already has some code base with n commits, and you’re trying to make all those changes into a single commit. So, force-pushing the changes to remote is necessary.

Solution 5 - Git

"origin/master" refers to the reference poiting to the HEAD commit of branch "origin/master". A reference is a human-friendly alias name to a Git object, typically a commit object. "origin/master" reference only gets updated when you git push to your remote (http://git-scm.com/book/en/v2/Git-Internals-Git-References#Remotes).

From within the root of your project, run:

cat .git/refs/remotes/origin/master

Compare the displayed commit ID with:

cat .git/refs/heads/master

They should be the same, and that's why Git says master is up-to-date with origin/master.

When you run

git fetch origin master

That retrieves new Git objects locally under .git/objects folder. And Git updates .git/FETCH_HEAD so that now, it points to the latest commit of the fetched branch.

So to see the differences between your current local branch, and the branch fetched from upstream, you can run

git diff HEAD FETCH_HEAD

Solution 6 - Git

Let look into a sample git repo to verify if your branch (master) is up to date with origin/master.

Verify that local master is tracking origin/master:

$ git branch -vv
* master a357df1eb [origin/master] This is a commit message

More info about local master branch:

$ git show --summary
commit a357df1eb941beb5cac3601153f063dae7faf5a8 (HEAD -> master, tag: 2.8.0, origin/master, origin/HEAD)
Author: ...
Date:   Tue Dec 11 14:25:52 2018 +0100

    Another commit message

Verify if origin/master is on the same commit:

$ cat .git/packed-refs | grep origin/master
a357df1eb941beb5cac3601153f063dae7faf5a8 refs/remotes/origin/master

We can see the same hash around, and safe to say the branch is in consistency with the remote one, at least in the current git repo.

Solution 7 - Git

Trivial answer yet accurate in some cases, such as the one that brought me here. I was working in a repo which was new for me and I added a file which was not seen as new by the status.

It ends up that the file matched a pattern in the .gitignore file.

Solution 8 - Git

in this case use git add and integrate all pending files and then use git commit and then git push

git add - integrate all pedent files

git commit - save the commit

git push - save to repository

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGregBView Question on Stackoverflow
Solution 1 - GitJonathan WakelyView Answer on Stackoverflow
Solution 2 - GitRyanView Answer on Stackoverflow
Solution 3 - GitSkycubeView Answer on Stackoverflow
Solution 4 - GitAdesoftView Answer on Stackoverflow
Solution 5 - GitMarek StanleyView Answer on Stackoverflow
Solution 6 - GitthemefieldView Answer on Stackoverflow
Solution 7 - GitkrustyengineerView Answer on Stackoverflow
Solution 8 - GitAirton SilveiraView Answer on Stackoverflow