How does this actually come about?
I am working in one repo by myself at the moment, so this is my workflow:
Change files Commit Repeat 1-2 until satisfied Push to master
Then when I do a git status
it tells me that my branch is ahead by X commits (presumably the same number of commits that I have made). Is it because when you push the code it doesn't actually update your locally cached files (in the .git folders)? git pull
seems to 'fix' this strange message, but I am still curious why it happens, maybe I am using git wrong?
including what branch is printed in the message
My local branch is ahead of master
where do you push/pull the current branch
I am pushing to GitHub and pulling to whichever computer I happen to be working on at that point in time, my local copy is always fully up to date as I am the only one working on it.
it doesn't actually check the remote repo
That is what I thought, I figured that I would make sure my understanding of it was correct.
are you passing some extra arguments to it?
Not ones that I can see, maybe there is some funny config going on on my end?
$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
nothing to commit (working directory clean)
push
and what are your remote and branch config settings?
git status
doesn't check the remote repository, git pull
does. If you have a tracking branch for a repository that you push to, git push
will update your local tracking branch to reflect the new state of the remote branch if your push is successful. This is why I asked about the asker's config because if it is not happening correctly there is probably a configuration error.
git status
? really? my git status
never tells me how far ahead my branch is .. are you passing some extra arguments to it?
git status
doesn't go to the remote repository to check whether the remote branch has been updated. It tells you how far ahead your local branch is compared to your locally stored remote tracking branch. The issue is that a normal git push
(as well as fetch and pull) should update the remote tracking branch and for the the asker this doesn't appear to be working. To see why we need to see both the exact form of git push
that is being used and the local repository's config but as the asker has already accepted an answer I can't see this happening now.
If you get this message after doing a git pull remote branch
, try following it up with a git fetch
. (Optionally, run git fetch -p
to prune deleted branches from the repo)
Fetch seems to update the local representation of the remote branch, which doesn't necessarily happen when you do a git pull remote branch
.
Use
git pull --rebase
The --rebase option means that git will move your local commit aside, synchronise with the remote and then try to apply your commits from the new state.
$ git pull --rebase Current branch xyz is up to date. $ git status On branch xyz Your branch is ahead of 'origin/xyz' by 6 commits. (use "git push" to publish your local commits) nothing to commit, working tree clean
git
, and don't ever mindlessly rewrite history!
Use these 3 simple commands
Step 1 : git checkout <branch_name>
Step 2 : git pull -s recursive -X theirs
Step 3 : git reset --hard origin/<branch_name>
More details : https://stackoverflow.com/a/39698570/2439715
Enjoy.
git reset --hard origin/master
cleared it up for me.
I think you’re misreading the message — your branch isn’t ahead of master
, it is master
. It’s ahead of origin/master
, which is a remote tracking branch that records the status of the remote repository from your last push
, pull
, or fetch
. It’s telling you exactly what you did; you got ahead of the remote and it’s reminding you to push.
This worked for me
git reset --hard origin/master
The output must look like
On branch dev HEAD is now at ae1xc41z Last commit message
git reset --hard origin master
but I stil had a commit ready to be pushed
Someone said you might be misreading your message, you aren't. This issue actually has to do with your <project>/.git/config
file. In it will be a section similar to this:
[remote "origin"]
url = <url>
fetch = +refs/heads/*:refs/remotes/origin/*
If you remove the fetch line from your project's .git/config file you'll stop the "Your branch is ahead of 'origin/master' by N
commits." annoyance from occurring.
Or so I hope. :)
ahead by x commits
message. I haven't seen the message in a while.
I had this issue on my stage server where I do only pulls. And hard reset helped me to clean HEAD to the same as remote.
git reset --hard origin/master
So now I have again:
On branch master
Your branch is up-to-date with 'origin/master'.
I went through every solution on this page, and fortunately @anatolii-pazhyn commented because his solution was the one that worked. Unfortunately I don't have enough reputation to upvote him, but I recommend trying his solution first:
git reset --hard origin/master
Which gave me:
HEAD is now at 900000b Comment from my last git commit here
I also recommend:
git rev-list origin..HEAD
# to see if the local repository is ahead, push needed
git rev-list HEAD..origin
# to see if the local repository is behind, pull needed
You can also use:
git rev-list --count --left-right origin/master...HEAD
# if you have numbers for both, then the two repositories have diverged
Best of luck
reset --hard origin/master
will destroy your local commits (the ones you haven't pushed yet)!
In my case it was because I switched to master using
git checkout -B master
Just to pull the new version of it instead of
git checkout master
The first command resets the head of master to my latest commits
I used
git reset --hard origin/master
To fix that
Note: this particular question is, at the time I write this answer, quite old. It was posted three years before the first release of a version of Git that fixed many of these problems. It seems worth adding a modern answer along with explainers, though. The existing accepted answer suggests running git fetch -p
,1 which is a good idea, although less-often required these days. It was much more necessary before Git version 1.8.2 came out; that Git was released three years after the original question.
1The -p
or --prune
option is not required and is suggested only parenthetically in the linked answer. See the longer sections below for what it does.
How does this actually come about?
The original question asks:
How does this actually come about?
The this in question is the fact that after git push origin master
, the OP runs git status
and sees the message On branch master
followed by Your branch is ahead of 'origin/master' by 1 commit.
To properly answer the question, we need to break it up into pieces.
First, each (local) branch has an upstream setting
This claim is actually just a bit too strong. Each of your own local branches, in your own Git repository, can have one setting that Git calls an upstream. Or, that branch can have no upstream. Old versions of Git were not very consistent about calling this an upstream setting, but in modern Git, it's more consistent. We also have git branch --set-upstream-to
and git branch --unset-upstream
for setting, or clearing, an upstream.
These --set-upstream-to
and --unset-upstream
affect the current branch. The current branch is the one you are on
, when git status
says on branch xyzzy
or whatever it is it says. You choose this branch with git checkout
or—since Git 2.23—git switch
.2 Whatever branch you checked out, that's the one you're on.3
If you use --unset-upstream
, this removes the current branch's upstream. With no upstream, this stops the message about being ahead or behind or diverged. But this message is meant to be useful, so you probably shouldn't just remove the upstream as a way to make it stop happening. (Do feel free to ignore the message—it's not a error after all—if you don't find it useful.)
If you run git branch --set-upstream-to=origin/xyzzy
, that sets the current branch's upstream to origin/xyzzy
. For a branch named xyzzy
, this would be the typical correct setting. Some acts of creating branches automatically set the (typically-correct) upstream, and some don't, so if you used a branch-creating operation that set the right upstream automatically, you need not do anything. If you want a different upstream, or if you used a branch-creating operation that set no upstream, you can use this to change the upstream.
The things you can set an upstream to are:
another of your own (local) branches: git branch --set-upstream-to=experiment makes your own local experiment the upstream of the current branch; or
any of your remote-tracking names, such as origin/main or origin/master or origin/xyzzy. These are the names output by git branch -r. Git calls these remote-tracking branch names (I like to drop the word "branch" here), and we'll talk about them more in a moment.
The ahead, behind, up-to-date, or diverged message that git status
prints is derived from running the somewhat magic-looking command:
git rev-list --count --left-right $branch...$upstream
where $branch
is the current branch name, and $upstream
is the string from its upstream setting (from git branch --set-upstream-to
above). There are three dots between the two names here, and the --count
, --left-right
, and three dots are all required to get git rev-list
to spit out the two numbers.
2If you have Git 2.23 or later, it's a good idea to move to git switch
because it avoids some tricky git checkout
behaviors that have historically led beginners into trouble (and occasionally even tripped up Git experts). However, if you are used to git checkout
, you can keep using it as long as you like, as it's still supported. The real problem is basically that git checkout
was overly powerful and could destroy work unexpectedly. The new git switch
is deliberately less-powerful and won't do that; the "destroy my work on purpose" operations were moved into git restore
.
3It's possible to be on no branch, in what Git calls detached HEAD mode. If you use git checkout
it can put you in this mode suddenly (though it prints a big scary warning, so if you don't see the scary warning, it didn't do that), but if you use git switch
, you must allow detached-HEAD mode with git switch --detach
. There's nothing wrong with this mode, you just need to be careful once you're in it, not to lose any new commits you make. It's easy to lose them if you're not careful. In normal mode, Git won't lose new commits like this.
If you're in detached HEAD mode, you have no upstream—by definition, because you have no branch—and none of the stuff in this question applies.
Reachability
This part is a bit technical and I will outsource much of it to a web site, Think Like (a) Git. I will summarize it here though like this: branch names (like main
or xyzzy
) and remote-tracking names (origin/main
, origin/xyzzy
) are how Git finds commits. Git is all about the commits. Your branch names only matter for finding your commits. Of course, if you can't find them, you're in trouble, so your branch names do matter. But the key is reachability, which is the technical term.
Each commit in a Git repository is numbered, with a big ugly hexadecimal string of letters and digits. This is the commit's hash ID and it's how Git really finds the commit.
Each commit contains two things: a full snapshot of every source file (in a special, compressed, Git-ified, and de-duplicated form), and some information about the commit itself: metadata telling who made it, when, and why (their log message), for instance. In the metadata, each commit holds the commit number(s) of some earlier commit(s). This means that one commit can find another—earlier—commit.
As Think Like (a) Git notes, this is a bit like a railway train. It's great once you're on the train, which in this case will take you backwards, automatically, to all the earlier train stops. But first you have to find your way to a train station. A Git branch name will do that: it holds the hash ID of the latest commit on your branch.
We can draw that like this:
... <-F <-G <-H <--branch
The branch name branch
holds the hash ID of the latest commit. We say that the name points to the commit. Whatever big ugly hash ID that really is, we've just used the letter H
to stand in for it here.
H
is an actual commit, so it has a saved snapshot—your files—and some metadata. In the metadata, Git saved the hash ID of an earlier commit. We'll call that earlier commit G
. We say that H
points to G
. Git can find H
by the branch name pointer, and that gives Git access to the commit, including the metadata, so now Git has the hash ID of earlier commit G
.
G
is of course also an actual commit: it has a saved snapshot and some metadata. In the metadata for G
, Git saved the hash ID of an earlier commit F
. We say that G
points to F
, and now Git can find F
using this saved hash ID.
This repeats forever, or rather, until we get to the very first commit ever. That commit (presumably we'd call it A
here) doesn't point backwards to an earlier commit, because there is no earlier commit.
This concept of reachability is basically a summary of what happens if we start at commit H
, as found by branch name branch
, and work backwards. We reach commit H
, which reaches backwards to commit G
, which reaches back to F
, and so on.
Branch names and remote-tracking names
As we just noted, a branch name holds the raw hash ID of some commit. That lets Git find that commit. There's one other special feature about a branch name though.
When you use git checkout
or git switch
to get on a branch, and then make a new commit, Git automatically updates the branch name's stored hash ID. That is, suppose we have a series of commits like this:
...--F--G--H <-- xyzzy (HEAD)
We're "on" branch xyzzy
, which I like to denote by attaching the special name HEAD
to it. This is useful when there's more than one branch name in the diagram. Note that H
is, at the moment, the newest commit. But now we'll make another one, in the usual way.
This new commit gets a new, unique, big ugly hexadecimal hash ID, just like any commit. Git makes sure that the new commit points backwards to commit H
, since that's the commit we used to make the new commit. We'll use the letter I
to represent this new commit. Let's draw it in:
...--F--G--H <-- xyzzy (HEAD)
\
I
This picture is actually mid-commit: Git has made I
, but isn't done with the git commit
action yet. Ask yourself this question: how will we find commit I
later? We're going to need it's hash ID. Where can we store a hash ID?
If you said: in a branch name, you're right. In fact, the right branch name—as far as Git is concerned, anyway—is the one you're "on" right now. That's the one we've attached HEAD
to in this drawing. So now, as the last part of git commit
, Git writes I
's hash ID into the name xyzzy
. This makes it point to commit I
, like so:
...--F--G--H
\
I <-- xyzzy (HEAD)
and now there's no reason for the kink in the drawing, so we can straighten it out:
...--F--G--H--I <-- xyzzy (HEAD)
That's how branch names work. It's really pretty simple, in the end: it just requires getting your head around several things at once. The name finds the commit. It finds the latest commit. From there, Git works backwards because each commit finds an earlier commit.
What about the remote-tracking names? Well, the trick here is that your Git talks to some other Git. Each Git has its own branch names. You have your master
or main
; they have theirs. You have your xyzzy
branch and they can have theirs too.
Your Git could call up their Git, all the time, every time, and ask them about their branch names. That's not very efficient, though, and does not work if you are cut off from the Internet.4 In any case, Git doesn't do that. Instead, when your Git calls up their Git and gets a list—from them—of all of their branch names and their hash IDs, your Git takes those names and hash IDs and stores them in your repository. This happens when you run git fetch
.5
There's a problem though. Their main
or master
, or their xyzzy
if they have one, doesn't necessarily mean the same commit as your main
or master
or xyzzy
. The solution is simple though: Git just takes their branch name and turns it into your remote-tracking name.
If origin
's main
or master
or xyzzy
has moved, you simply run git fetch
or git fetch origin
, perhaps with --prune
. Your Git calls up their Git. They list out their branch names and commit hash IDs. Your Git gets any new commits from them, if necessary: commits they have, that you don't. Then your Git turns their branch names into your remote-tracking names and creates or updates your remote-tracking names to remember where their branch names pointed, at the moment you ran this git fetch
.
If you use --prune
, this handles the case where they deleted some branch name(s). Let's say they had a branch named oldstuff
. You got it earlier so you have origin/oldstuff
in your remote-tracking names. Then they deleted oldstuff
, so this time they ... just don't have it any more. Without --prune
, your Git ignores this. You keep your old origin/oldstuff
even though it's dead now. With --prune
, your Git says: Oh, huh, this looks dead now and prunes it away: a remote-tracking name in your Git that doesn't correspond to one of their branch names, just gets deleted.
The prune option probably should have always been the default, but it wasn't and hence now can't be.6 You can, however, configure fetch.prune
to true
and make it your default.
4That's less common now in 2021 than it was back in 2010. It was substantially more common in 2005 when Git was first released. It used to be the case that, say, on an airline flight to a Linux conference, you couldn't get any access to the Internet, for any price.
5The choice of which names to take, and when to take them, is actually part of the answer here. It has changed over time in Git—and is still changing a little bit—although there are still various constraints. We won't go into all the details though.
6Git generally takes backwards-compatibility pretty seriously. It took the 1.x to 2.0 changeover to change the push.default
default setting from matching
to simple
, for instance.
How git rev-list gets the two numbers
Earlier, I noted that the ahead, behind, up-to-date, or diverged message that git status
prints is derived from running:
git rev-list --count --left-right $branch...$upstream
What git rev-list
does here is count reachable commits. The three-dot syntax, described in the gitrevisions documentation, produces what in set theory is called a symmetric difference. In non-math-jargon, though, we can just think about this as doing two commit reachability tests, which we can draw like this:
I--J <-- xyzzy (HEAD)
/
...--G--H
\
K <-- origin/xyzzy
Here, commit J
is reachable from your branch name xyzzy
, because the name points there. Commit I
is reachable from commit J
, so it counts as well. This leads back to commit H
—which as you can see from the graph, is a little special.
At the same time, commit K
is reachable from your remote-tracking name origin/xyzzy
. Commit H
is reachable from K
. From commit H
on back, commits G
and F
and so on are all also reachable. But the two "railroad tracks" join up at commit H
: commit H
and all earlier commits are reachable from both names.
This makes commits I-J
special in that they're reachable *only from the name xyzzy
, and K
special in that it's reachable *only from the name origin/xyzzy
. The three-dot notation finds these commits: the ones reachable only from one name, or only from the other.
If we put the branch name on the left, and its upstream on the right, and use the three-dot notation, we'll find all three of these commits for this case. Using --count
makes git rev-list
print this number: 3. Using --left-right
tells git rev-list
to be smarter, though: it should count how many commits are being counted because of the left name—the current branch name—and how many commits are being counted because of the right one, the upstream. So with both options—and the three dots—we get:
2 1
as the output, telling us that there are two commits on xyzzy
that aren't on origin/xyzzy
, and one commit that's on origin/xyzzy
that is not on xyzzy
. These are commits J
-and-I
(on xyzzy
) and K
(on origin/xyzzy
) respectively.
Without the --count
option, git rev-list
would list out the hash IDs, prefixed with <
(left) or >
(right) symbols. Using git log
instead of git rev-list
, as in:
git log --left-right xyzzy...origin/xyzzy
(again note the three dots: see gitrevisions and search for Symmetric Difference) we'll get the three commits shown, again prefixed with <
or >
as appropriate.
This is an easy way to see which commits are on your branch, and which commits are on the upstream. It's usually more useful with --decorate
, --oneline
, and --graph
(and you might want to add --boundary
as well in some cases).
Ahead, behind, diverged, or up-to-date
So, suppose we have run:
git rev-list --count --left-right $branch...$upstream
(or—see gitrevisions again—using $branch@{upstream}
on the right here) and gotten our two counts. These can be:
0 and 0: Our branch name and our remote-tracking name (or whatever is in the upstream) point to the same commit. Nobody is ahead or behind. The git status command will say Your branch is up to date with '
nonzero, zero: There are commits on the current branch that are not on the upstream. There are no commits on the upstream that are not on the current branch. So our branch is ahead of the upstream.
zero, nonzero: There are no commits on the current branch that are not on the upstream, but there are some on the upstream that are not on the current branch. This means our branch is behind the upstream.
nonzero, nonzero: This is like the diagram I drew above. Both the current branch and its upstream are simultaneously ahead-and-behind each other. The git status command will use the word diverged.
We're about to jump back to the original question now. Let's assume the upstrema of the current branch is a remote-tracking name. Note that the counts that git rev-list
got are based on what is in our remote-tracking branch names.
How does this actually come about?
In the OP's scenario, only one person is making new commits and sending them off with git push
. If I am the one person, I might git clone
something from GitHub, then make a new commit or two and git push origin master
.
In modern Git, git status
would tell me that I am up to date. In very old Git versions, git status
would now tell me that my master
is ahead of origin/master
. The reason why is simple: in the old days, git push
failed to update origin/master
. Running git fetch origin
, or just git fetch
, made your own Git call up the Git over at GitHub, read their information, and realize that your git push
had worked.
When you run git push
, you have your Git call up some other Git. Your Git then offers the other Git any new commits you have, that they don't, that they'll need to complete the git push
. They take those commits and put them somewhere.7 Then your Git asks their Git—politely asks, by default—if they would, please, if it's OK, set their branch name to refer to the latest commit, by its hash ID, as seen in your branch name. There's no remote-tracking stuff going on here. You are just asking them to set the same name you're using.
As a general rule, this kind of polite request succeeds if you're just adding new commits to their repository. It fails if you're asking them to "lose" some commits: you'll get a complaint about this being a "non-fast-forward". If you're the only one sending them new commits, they should never have anything to lose this way, so this should always work.8
If the push fails, it's appropriate for your Git to leave your remote-tracking name unchanged. Your Git never got the information from their Git that would let your Git update it. But if the push succeeds ... well, they just set their branch name to the hash ID that your Git asked them to use. So now your Git knows where their branch name points. Your Git should update your remote-tracking name.
In old Git versions, your Git just didn't bother doing this. In Git version 1.8.2, the Git authors finally fixed this: a successful git push
has your Git update your remote-tracking name, based on the fact that their Git agreed to the update your Git provided. So this sort of thing doesn't happen so much any more.
7In the bad old days, they put them straight into their repository. In modern Git, they put them in a quarantine area, and only migrate them into their repository if they actually accept the new commits.
8Of course, places like GitHub also offer features like protected branches, which just say no to every push, for instance. We can also invent fancier scenarios, such as when you have multiple computers and forget that you made and pushed new commits via Computer A, and now try to push from Computer B.
What if you're not the only one doing git push
Suppose that both Alice and Bob have cloned some GitHub repository. The development in this repository happens on branch dev
(for develop). So Alice makes her own dev
from her origin/dev
:
...--G--H <-- dev (HEAD), origin/dev [Alice's computer]
Bob, likewise, makes his own dev
:
...--G--H <-- dev (HEAD), origin/dev [Bob's computer]
The GitHub repository dev
ends at H
too. (They have no origin/dev
: the GitHub repository does not bother with remote-tracking names.)
Alice makes a new commit, which we'll call I
, and draw like this on Alice's computer:
I <-- dev (HEAD)
/
...--G--H <-- origin/dev
Meanwhile, Bob makes a new commit, which we'll call J
:
...--G--H <-- origin/dev
\
J <-- dev (HEAD)
Now both Alice and Bob try to git push origin dev
. One of them gets there first—perhaps Alice:
...--G--H--I <-- dev [GitHub's systems]
Bob sends commit J
, which to GitHub, looks like this:
I <-- dev
/
...--G--H
\
J ... polite request to set dev to J
If GitHub would do that, this would "lose" Alice's commit I
, because Git finds commits by starting from the names and working backwards. So they reject the push with the "not a fast forward" complaint.
Bob now needs to yank commit I
from GitHub into Bob's own repository, so that Bob sees:
I <-- origin/dev
/
...--G--H
\
J <-- dev (HEAD) [Bob's computer]
Bob should do this with git fetch
or git fetch origin
, perhaps with --prune
(or with fetch.prune
set to true
). Now when Bob runs git status
, he will get the "diverged" message.
It's now up to Bob, as the loser of the push race, to figure out how to combine his work (commit J
) with Alice's (commit I
). There are different ways to combine work. The two primary ones are git merge
and git rebase
. We won't address who should do what, when, and why here, just the fact that this is another way you might run into "diverged" status when you thought you were strictly ahead of some other Git.
I had this same problem on a Windows machine. When I ran a git pull origin master
command, I would get the "ahead of 'origin/master' by X commits" warning. I found that if I instead ran git pull origin
and did NOT specify the branch, then I would no longer receive the warning.
git fetch
behind the scenes.
I would like to reiterate the same as mentioned by @Marian Zburlia above. It worked for me and would suggest the same to others.
git pull origin develop
should be followed by $ git pull --rebase
.
This will remove the comments coming up on the $ git status
after the latest pull.
git fetch
will resolve this for you
If my understanding is correct, your local (cached) origin/master
is out of date. This command will update the repository state from the server.
It just reminds you the differences between the current branch and the branch which does the current track. Please provide more info, including what branch is printed in the message and where do you push/pull the current branch.
I actually had this happening when I was doing a switch/checkout with TortiseGIT.
My problem was that I had created the branch based on another local branch. It created a "merge" entry in /.git/config
that looked something like this:
[branch "web"]
merge = refs/heads/develop
remote = gitserver
Where whenever I switched to the "web" branch, it was telling me I was 100+ commits ahead of develop. Well, I was no longer committing to develop so that was true. I was able to simply remove this entry and it seems to be functioning as expected. It is properly tracking with the remote ref instead of complaining about being behind the develop branch.
As Vikram said, this Stack Overflow thread is the top result in Google when searching for this problem so I thought I'd share my situation and solution.
Then when I do a git status it tells me that my branch is ahead by X commits (presumably the same number of commits that I have made).
My experience is in a team environment with many branches. We work in our own feature branches (in local clones) and it was one of those that git status
showed I was 11 commits ahead. My working assumption, like the question's author, was that +11 was from commits of my own.
It turned out that I had pulled in changes from the common develop
branch into my feature branch many weeks earlier -- but forgot! When I revisited my local feature branch today and did a git pull origin develop
the number jumped to +41 commits ahead. Much work had been done in develop
and so my local feature branch was even further ahead of the feature branch on the origin
repository.
So, if you get this message, think back to any pulls/merges you might have done from other branches (of your own, or others) you have access to. The message just signals you need to git push
those pull
ed changes back to the origin
repo ('tracking branch') from your local repo to get things sync'd up.
Though this question is a bit old...I was in a similar situation and my answer here helped me fix a similar issue I had
First try with push -f
or force option
If that did not work it is possible that (as in my case) the remote repositories (or rather the references to remote repositories that show up on git remote -v
) might not be getting updated.
Outcome of above being your push synced your local/branch with your remote/branch however, the cache in your local repo still shows previous commit (of local/branch ...provided only single commit was pushed) as HEAD.
To confirm the above clone the repo at a different location and try to compare local/branch HEAD and remote/branch HEAD. If they both are same then you are probably facing the issue I did.
Solution:
$ git remote -v
github git@github.com:schacon/hw.git (fetch)
github git@github.com:schacon/hw.git (push)
$ git remote add origin git://github.com/pjhyett/hw.git
$ git remote -v
github git@github.com:schacon/hw.git (fetch)
github git@github.com:schacon/hw.git (push)
origin git://github.com/pjhyett/hw.git (fetch)
origin git://github.com/pjhyett/hw.git (push)
$ git remote rm origin
$ git remote -v
github git@github.com:schacon/hw.git (fetch)
github git@github.com:schacon/hw.git (push)
Now do a push -f
as follows
git push -f github master
### Note your command does not have origin
anymore!
Do a git pull
now git pull github master
on git status
receive
# On branch master
nothing to commit (working directory clean)
I hope this useful for someone as the number of views is so high that searching for this error almost always lists this thread on the top
Also refer gitref for details
push -f
unless you know what you are doing! At least do a push --force-with-lease
so that you don't overwrite others' commits!
The answers that suggest git pull
or git fetch
are correct.
The message is generated when git status
sees a difference between .git/FETCH_HEAD
and .git/refs/remotes/<repository>/<branch>
(e.g. .git/refs/remotes/origin/master
).
The latter file records the HEAD from the last fetch (for the repository/branch). Doing git fetch
updates both files to the branch's current HEAD.
Of course if there is nothing to fetch (because the local repository is already up-to-date) then .git/FETCH_HEAD
doesn't change.
.git/FETCH_HEAD
contains 9f7336c873ccffc772168bf49807e23ff74014d3 branch 'master' of URL
and .git/refs/remotes/origin/master
contains 9f7336c873ccffc772168bf49807e23ff74014d3
, yet I still receive the message and neither git pull
nor git fetch
solves it
I was getting the following which is related to the actual question Your branch is ahead of 'origin/testing/KB-200' by 17 commits
Reason: I created PR for review the last week and then I closed the project. Then today, I opened up the project to make a slight change in the same branch (testing/KB-200)
and I ran git pull
first. This pull contained 18 new commits by other developers working on the project this made my local branch ahead of my remote branch by those commits and therefore I was getting that message. So I just had to run the following command:
git push origin testing/KB-200
and then it was all sync and up to date. [On branch testing/KB-200 Your branch is up to date with 'origin/testing/KB-200']
If you get this message after doing a commit, in order to untrack file in the branch, try making some change in any file and perform commit. Apparently you can't make single commit which includes only untracking previously tracked file. Finally this post helped me solve whole problem https://help.github.com/articles/removing-files-from-a-repository-s-history/. I just had to remove file from repository history.
Just sharing what happened to me.
I committed a bunch of files and realized there are some files that I dont want to commit, so I used VS code to undo last commit
, removed the file and added to gitignore, then force-pushed my commit again.
This apparently caused git to think my commit still has to be made to remote, because locally the file was committed somehow.
Solved by undo last commit
and unstaging the file which is in gitignore now
Success story sharing