这到底是怎么发生的呢?

我在一个回购工作由自己的时刻,所以这是我的工作流程:

改变文件 提交 重复1-2次直到满意 推送至master

然后,当我执行git状态时,它告诉我我的分支领先X次提交(大概与我所做的提交数量相同)。是不是因为当您推送代码时,它实际上并没有更新本地缓存的文件(在.git文件夹中)?git拉似乎“修复”这个奇怪的消息,但我仍然好奇为什么会发生这种情况,也许我使用git错误?


包括在消息中打印的分支

我在当地的分公司走在主人前面

你在哪里推/拉当前的分支

我推送到GitHub,并拉到我碰巧在那个时间点上工作的任何一台计算机,我的本地副本总是完全最新的,因为我是唯一一个在它上工作的人。

它实际上并不检查远程回购

这就是我的想法,我想我要确保我对它的理解是正确的。

你是否给它传递了一些额外的参数?

不是我能看到的,也许我这边有什么奇怪的配置?

$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
nothing to commit (working directory clean)

它只是提醒你当前分支和运行当前轨迹的分支之间的区别。请提供更多信息,包括什么分支打印在消息中,你在哪里推/拉当前分支。


我认为你误解了信息——你的分支不是在master前面,它是master。它位于origin/master之前,后者是一个远程跟踪分支,用于记录您上一次推、拉或取时远程存储库的状态。它会告诉你你做了什么;你走到了遥控器前面,它在提醒你按。


如果你在执行git pull远程分支之后得到这条消息,试着用git fetch来跟踪它。(可选地,运行git fetch -p从repo中删除分支)

Fetch似乎更新了远程分支的本地表示,当您执行git拉远程分支时,这并不一定会发生。


有人说你可能误解了你的信息,你没有。这个问题实际上与<project>/有关。git /配置文件。它将是一个类似于下面的部分:

[remote "origin"]
    url = <url>
    fetch = +refs/heads/*:refs/remotes/origin/*

如果你从你的项目的.git/配置文件中删除了获取行,你就会停止“你的分支比'origin/master'领先N个提交”的烦恼。

我希望如此。:)


虽然这个问题有点老了……我也遇到过类似的情况,我的回答帮助我解决了一个类似的问题

首先尝试使用push -f或force选项

如果这不起作用,就有可能(就像我的情况一样)远程存储库(或者是显示在git remote -v上的对远程存储库的引用)可能没有得到更新。

上面的结果是你的推送同步你的本地/分支与你的远程/分支,然而,在你的本地回购缓存仍然显示以前的提交(本地/分支…如果只有一次提交被推)作为HEAD。

要确认上述操作,在不同的位置克隆回购,并尝试比较本地/分支HEAD和远程/分支HEAD。如果两者都相同,那么你可能会遇到我遇到的问题。

解决方案:

$ 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)

现在按如下方式执行push -f

git push -f github master ###注意你的命令不再有原点!

现在做个少不更事的拉 Git拉github master

在git状态接收

#在分支master上

没有要提交的内容(工作目录清洁)

我希望这对某些人有用,因为观看的数量是如此之高,以至于搜索这个错误几乎总是把这个线程列在顶部

有关详细信息,请参阅gitref


实际上,当我使用TortiseGIT进行切换/签出时,就发生了这种情况。

我的问题是,我基于另一个本地分支创建了这个分支。它在/中创建了一个“合并”条目。Git /config看起来是这样的:

[branch "web"]
    merge = refs/heads/develop
    remote = gitserver

每当我切换到“web”分支时,它都会告诉我,我比开发提前了100多个提交。好吧,我不再致力于开发,这是真的。我可以简单地删除这个条目,它似乎像预期的那样运行。它正确地跟踪远程引用,而不是抱怨落后于开发分支。

正如Vikram所说,当搜索这个问题时,这个Stack Overflow线程是谷歌的顶部结果,所以我想分享我的情况和解决方案。


我在一台Windows电脑上遇到了同样的问题。当我运行一个git拉origin master命令时,我会得到“在'origin/master'前面X次提交”警告。我发现,如果我不是运行git拉原点,没有指定分支,那么我将不再收到警告。


提示git pull或git fetch的答案是正确的。 当git状态看到。git/FETCH_HEAD和.git/refs/remotes/<仓库>/<分支>(例如。git/refs/remotes/origin/master)之间的差异时,就会生成该消息。

后一个文件记录了最后一次获取的HEAD(用于存储库/分支)。执行git获取将两个文件更新到分支的当前HEAD。 当然,如果没有东西要获取(因为本地存储库已经是最新的),那么.git/FETCH_HEAD就不会改变。


Use

git pull --rebase

——rebase选项意味着git会将你的本地提交移到一边,与远程同步,然后尝试从新的状态应用你的提交。


我在我的舞台服务器上有这个问题,我只做拉。 和硬复位帮助我清洁HEAD一样的遥控器。

git reset --hard origin/master

现在我又有了:

On branch master
Your branch is up-to-date with 'origin/master'.

使用这3个简单的命令

步骤1:git checkout <branch_name>

步骤2:git拉-s递归-X their

步骤3:git reset——hard origin/<branch_name> . zip

详情:https://stackoverflow.com/a/39698570/2439715

享受。


我浏览了本页上的每个解决方案,幸运的是@anatolii-pazhyn评论了,因为他的解决方案是有效的。不幸的是,我没有足够的声誉来支持他,但我建议先试试他的解决方案:

git reset --hard origin/master

这给了我:

HEAD is now at 900000b Comment from my last git commit here

我还建议:

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

你还可以使用:

git rev-list --count --left-right origin/master...HEAD
# if you have numbers for both, then the two repositories have diverged

祝你好运


就我而言,这是因为我改用了熟练使用

 git checkout -B master

把它的新版本拉出来,而不是

 git checkout master

第一个命令将master的头重置为最近的提交

我使用

git reset --hard origin/master

为了解决这个问题


我想重申上文@Marian Zburlia所提到的。它对我很有效,也会对其他人提出同样的建议。

Git拉源码开发

后面应该跟着$ git pull -rebase。

这将删除最近一次pull之后$ git状态上出现的注释。


如果在执行提交后收到此消息,为了取消分支中的文件跟踪,请尝试对任何文件进行一些更改并执行提交。显然,你不能做出单一的提交,其中只包括取消跟踪以前跟踪的文件。 最后这篇文章帮助我解决了整个问题https://help.github.com/articles/removing-files-from-a-repository-s-history/。我只需要从存储库历史中删除文件。


Git fetch将为你解决这个问题

如果我的理解是正确的,你的本地(缓存)源/主是过时的。该命令将从服务器更新存储库状态。


然后,当我执行git状态时,它告诉我我的分支领先X次提交(大概与我所做的提交数量相同)。

我的经验是在有许多分支的团队环境中工作。我们在自己的特性分支中工作(在本地克隆中),git状态显示我已经提前11次提交了。我的工作假设,就像问题的作者,是+11来自我自己的提交。

结果发现,我在几个星期前就把变更从通用开发分支拉到了我的功能分支中——但我忘了!当我今天重新访问我的本地功能分支并做了一个git拉源开发时,数量跃升至+41提交。在开发过程中已经做了很多工作,所以我的本地特性分支在原始存储库上甚至领先于特性分支。

因此,如果您收到这条消息,请回想一下您可能从您可以访问的其他分支(您自己的或其他分支)执行的任何拉/合并。该消息只是表明你需要git将这些拉回的更改从本地回购推回原始回购(“跟踪分支”),以使事情同步。


这对我很有效

Git重置-硬源/主

输出必须是这样的

关于分支开发 HEAD现在在ae1xc41z最后提交消息


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.


1 -p或——prune选项不是必需的,只建议在链接的答案中作为括号。请参阅下面较长的部分了解它的功能。


这到底是怎么发生的呢?

原来的问题是这样的:

这到底是怎么发生的呢?

这里的问题是,在git推送origin master之后,OP运行git状态,并看到消息On branch master后面跟着Your branch领先'origin/master' 1 commit。要正确地回答这个问题,我们需要把它分解成几个部分。

首先,每个(本地)分支都有一个上游设置

这种说法实际上有点太强烈了。在您自己的Git存储库中,您自己的每个本地分支都可以有一个设置,Git称之为上游。或者,这个分支没有上游。旧版本的Git在将此称为上游设置方面不太一致,但在现代Git中,它更加一致。我们还有git分支——set-upstream-to和git分支——unset-upstream用于设置或清除上游。

这些——set-upstream-to和——unset-upstream会影响当前分支。当前分支是你所在的那个,当git状态显示在分支xyzzy上时。你可以使用git checkout或git switch.2来选择这个分支不管你查过哪个分支,这就是你要查的

如果你使用——unset-upstream,这将移除当前分支的上游。没有了上游,这就停止了关于领先、落后或偏离的信息。但是这条消息是有用的,所以您可能不应该仅仅删除上游来阻止它发生。(如果你觉得它没什么用的话,可以随意忽略这条消息——毕竟这不是一个错误。)

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.

你可以设置upstream为:

另一个你自己的(本地)分支:git branch——set-upstream-to=experiment使你自己的本地实验成为当前分支的上游;或 任何远程跟踪名称,例如origin/main或origin/master或origin/xyzzy。这些是git分支-r输出的名称。Git将这些远程跟踪分支命名为(我喜欢在这里省略“分支”这个词),我们将在稍后详细讨论它们。

git status打印的前进、落后、最新或发散的消息来自于运行看起来有点神奇的命令:

git rev-list --count --left-right $branch...$upstream

其中$branch是当前分支的名称,$upstream是其上游设置的字符串(from git branch——set-upstream-to - above)。在这两个名字之间有三个点,count, left-right,三个点都需要get git rev-list来吐出这两个数字。


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.

如果处于分离HEAD模式,则没有上游——根据定义,因为没有分支——这个问题中的任何东西都不适用。


可达性

这部分有点技术性,我将把大部分内容外包给一个网站,Think Like (a) Git。在这里我将这样总结:分支名称(如main或xyzzy)和远程跟踪名称(origin/main, origin/xyzzy)是Git查找提交的方式。Git都是关于提交的。分支名称只在查找提交时起作用。当然,如果你找不到它们,你就有麻烦了,所以你的分支名称很重要。但关键是可达性,这是一个专业术语。

Git存储库中的每个提交都有编号,使用一个又大又丑的十六进制字母和数字字符串。这是提交的哈希ID, Git就是这样找到提交的。

每次提交都包含两件事:每个源文件的完整快照(以一种特殊的、压缩的、git化的和重复数据删除的形式),以及关于提交本身的一些信息:例如,告诉谁做的、什么时候做的和为什么做的元数据(他们的日志消息)。在元数据中,每个提交都保存了一些先前提交的提交号。这意味着一个提交可以找到另一个更早提交。

正如Think Like (a) Git所指出的,这有点像火车。一旦你上了火车,它就会很好,在这种情况下,它会自动带你回到之前的所有火车站。但首先你得找到去火车站的路。Git分支名可以做到这一点:它保存了分支上最新提交的哈希ID。

我们可以这样画:

... <-F <-G <-H   <--branch

分支名称分支保存了最新提交的哈希ID。我们说名称指向提交。不管哈希ID到底有多大,我们只是用字母H来代替它。

H是一个实际的提交,因此它有一个保存的快照(您的文件)和一些元数据。在元数据中,Git保存了之前提交的哈希ID。我们称其为早期提交G,我们说H指向G, Git可以通过分支名称指针找到H,这让Git可以访问提交,包括元数据,所以现在Git有了早期提交G的哈希ID。

G当然也是一个实际的提交:它有一个保存的快照和一些元数据。在G的元数据中,Git保存了之前提交F的哈希ID。我们说G指向F,现在Git可以使用这个保存的哈希ID找到F。

这将永远重复,或者更确切地说,直到我们完成第一次提交。该提交(假设我们在这里将其称为A)并不指向之前的提交,因为不存在更早的提交。

这个可达性的概念基本上是一个总结,如果我们从提交H开始(通过分支名称branch找到),然后向后工作,会发生什么。我们到达提交H,提交G,提交F,依此类推。

分支名称和远程跟踪名称

正如我们刚刚注意到的,分支名称保存了一些提交的原始哈希ID。这让Git找到提交。不过,关于分支名称还有另一个特殊特性。

当你使用git checkout或git switch进入一个分支,然后进行新的提交时,git会自动更新分支名称存储的哈希ID。也就是说,假设我们有一系列这样的提交:

...--F--G--H   <-- xyzzy (HEAD)

我们“在”xyzzy分支上,我喜欢给它加上一个特殊的名字HEAD。当图中有多个分支名称时,这很有用。注意H是目前最新的提交。但现在我们要做另一个,用通常的方法。

这个新的提交得到一个新的、唯一的、又大又丑的十六进制哈希ID,就像任何提交一样。Git确保新的提交向后指向提交H,因为这是我们用来进行新提交的提交。我们将使用字母I来表示这个新的提交。让我们画出来:

...--F--G--H   <-- xyzzy (HEAD)
            \
             I

这张图实际上是在提交中:Git已经完成了I,但还没有完成Git的提交操作。问你自己这个问题:我们以后如何找到commit I ?我们需要它的哈希ID。我们可以在哪里存储哈希ID?

如果你说:在分支名称中,你是对的。事实上,正确的分支名称(至少就Git而言)就是您现在“使用”的那个。这就是我们在这幅图中所附的HEAD。现在,作为git提交的最后一部分,git将I的哈希ID写到xyzzy这个名字中。这就要求提交I,像这样:

...--F--G--H
            \
             I   <-- xyzzy (HEAD)

现在图纸上没有扭结的原因了,所以我们可以把它理顺:

...--F--G--H--I   <-- xyzzy (HEAD)

这就是分支名称的工作原理。说到底,这真的很简单:它只需要你同时思考几件事。名称查找提交。它查找最新的提交。从这里开始,Git向后工作,因为每次提交都会找到之前的提交。

那远程跟踪的名字呢?这里的技巧是你的Git与其他Git对话。每个Git都有自己的分支名称。你有你的主人或主人;他们有自己的。你有你的木树枝,他们也可以有他们的。

你的Git可以随时调用他们的Git,并询问他们的分支名称。但是,这并不是很有效,而且如果你与internet切断了联系,就不能工作。4在任何情况下,Git都不会这样做。相反,当您的Git调用他们的Git并从他们那里获得所有分支名称和哈希id的列表时,您的Git将获取这些名称和哈希id并将它们存储在存储库中。这发生在运行git fetch.5时

但是有一个问题。他们的main或master,或者xyzzy,如果他们有一个,并不一定意味着和你的main, master或xyzzy是一样的。解决方案很简单:Git只是获取它们的分支名称,并将其转换为您的远程跟踪名称。

如果origin的主或主或xyzzy移动了,你只需要运行git fetch或git fetch origin,也许用——prune。你的Git调用他们的Git。它们列出分支名称并提交哈希id。你的Git从他们那里获得任何新的提交,如果有必要:他们有,而你没有。然后,Git将它们的分支名称转换为远程跟踪名称,并创建或更新远程跟踪名称,以便在运行Git获取时记住它们的分支名称指向的位置。

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.

修剪选项可能应该一直是默认的,但它不是,因此现在不能但是,您可以配置fetch。修剪为true并将其设置为默认值。


与2010年相比,这种情况在2021年并不常见。它在2005年Git首次发布时更为普遍。过去的情况是,比如说,在飞往Linux会议的航班上,你无论花多少钱都无法接入互联网。

选择取哪些名字,什么时候取,实际上是答案的一部分。随着时间的推移,它在git中发生了变化,并且仍然在发生一点点变化,尽管仍然存在各种限制。不过,我们不会讨论所有的细节。

git通常非常重视向后兼容性。它拿走了1。例如,将push.default的默认设置从匹配更改为简单。


git rev-list如何获得两个数字

前面,我注意到git状态打印的ahead、behind、latest或diverged消息是通过运行:

git rev-list --count --left-right $branch...$upstream

git rev-list在这里做的是统计可达提交。gitrevisions文档中描述的三点语法,产生了集合论中所谓的对称差分。然而,在非数学术语中,我们可以将其视为进行两次提交可达性测试, 我们可以这样画

          I--J   <-- xyzzy (HEAD)
         /
...--G--H
         \
          K   <-- origin/xyzzy

这里,提交J可以从分支名xyzzy到达,因为分支名指向那里。提交I可以从提交J到达,所以它也算数。这又回到了提交h,从图中可以看出,这有点特殊。

同时,可以通过远程跟踪名称origin/xyzzy访问提交K。提交H可以从k到达,从提交H开始,提交G和F等等都是可到达的。但是这两条“轨道”在提交H处连接起来:提交H和所有之前的提交都可以从这两个名称到达。

这使得I-J提交非常特殊,因为它们只能从名称xyzzy中访问,而K则非常特殊,因为它只能从名称origin/xyzzy中访问。三点表示法找到这些提交:只能从一个名称到达的提交,或者只能从另一个名称到达的提交。

如果我们把分支名称放在左边,把它的上游放在右边,并使用三点表示法,我们将找到这种情况下的所有这三个提交。使用——count使git的rev-list打印这个数字:3。使用——left-right可以让git rev-list变得更聪明:它应该计算因为左边名称(当前分支名称)而被计数的提交数,以及因为右边名称(上游)而被计数的提交数。所以有了这两个选项和三个点,我们得到:

2       1

作为输出,它告诉我们xyzzy上有两个提交不在origin/xyzzy上,还有一个提交在origin/xyzzy上,但不在xyzzy上。它们分别是提交j和i (xyzzy上)和K (origin/xyzzy上)。

如果没有——count选项,git rev-list将列出哈希id,前缀为<(左)或>(右)符号。使用git log代替git rev-list,如下所示:

git log --left-right xyzzy...origin/xyzzy

(再次注意这三个点:参见gitrevisions并搜索Symmetric Difference)我们将得到如图所示的三个提交,同样以<或>作为前缀。

这是一种查看哪些提交在分支上,哪些提交在上游上的简单方法。——decoration、——oneline和——graph通常更有用(在某些情况下,您可能还想添加——boundary)。

领先的,落后的,发散的或最新的

那么,假设我们运行:

git rev-list --count --left-right $branch...$upstream

(或者再次查看gitrevisions -使用右边的$branch@{upstream})并得到我们的两个计数。这些可以是:

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 '<upstream>'. 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.

现在我们要回到最初的问题。让我们假设当前分支的上层是一个远程跟踪名称。注意,git rev-list获得的计数是基于远程跟踪分支名称中的内容。

这到底是怎么发生的呢?

在OP的场景中,只有一个人在进行新的提交,并使用git push发送它们。如果我是一个人,我可能会从GitHub克隆一些东西,然后做一个或两个新的提交,然后git push origin master。

在现代Git中,Git状态会告诉我我是最新的。在非常旧的Git版本中,Git状态现在会告诉我我的master在origin/master之前。原因很简单:在以前,git push无法更新origin/master。运行git fetch origin,或者只是git fetch,让你自己的git调用GitHub上的git,读取他们的信息,并意识到你的git推送已经工作了。

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.

作为一般规则,如果您只是向他们的存储库添加新的提交,这种礼貌的请求会成功。如果你要求他们“丢失”一些提交,它就会失败:你会收到一个抱怨,说这是一个“非快进”。如果你是唯一一个向他们发送新提交的人,他们不应该有任何东西会以这种方式丢失,所以这应该总是有效的

如果推送失败,Git最好保持远程跟踪名称不变。你的Git从来没有从他们的Git中获得可以让你的Git更新它的信息。但如果成功了……好吧,他们只是将他们的分支名称设置为Git要求他们使用的哈希ID。现在Git知道它们的分支名称指向哪里了。Git应该更新远程跟踪名称。

在旧的Git版本中,你的Git根本不需要这么做。在Git版本1.8.2中,Git作者最终修复了这个问题:成功的Git推送会让Git更新远程跟踪名称,这是基于他们的Git同意Git提供的更新。所以这类事情不再经常发生了。


7:7从前光景不好的时候,人就直接放在库房里。在现代Git中,它们将它们放在隔离区域中,只有在实际接受新提交时才将它们迁移到存储库中。

当然,像GitHub这样的地方也提供了像受保护的分支这样的功能,比如对每一个推送都说不。我们还可以发明一些更奇特的场景,比如当你有多台计算机,你忘记了你通过计算机A进行了新的提交,现在尝试从计算机B进行提交。


如果你不是唯一一个做git push的人呢

假设Alice和Bob都克隆了一些GitHub存储库。这个存储库中的开发在分支dev上进行(用于开发)。所以Alice根据她的origin/dev制作了她自己的dev:

...--G--H   <-- dev (HEAD), origin/dev  [Alice's computer]

同样地,Bob也创造了自己的开发:

...--G--H   <-- dev (HEAD), origin/dev  [Bob's computer]

GitHub存储库开发也在H结束。(它们没有origin/dev: GitHub存储库不介意远程跟踪名称。)

Alice进行了一个新的提交,我们称之为I,然后在Alice的电脑上画出这样的图:

          I   <-- dev (HEAD)
         /
...--G--H   <-- origin/dev

与此同时,Bob进行了一个新的提交,我们称之为J:

...--G--H   <-- origin/dev
         \
          J   <-- dev (HEAD)

现在Alice和Bob都试图推动原始开发。他们中的一个先到达那里——可能是Alice:

...--G--H--I   <-- dev  [GitHub's systems]

Bob发送commit J到GitHub,看起来像这样:

          I   <-- dev
         /
...--G--H
         \
          J   ... polite request to set dev to J

如果GitHub这样做,这将“丢失”Alice的提交I,因为Git通过从名称开始并向后工作来查找提交。所以他们用“不是快进”的抱怨来拒绝这种推动。

Bob现在需要将提交I从GitHub拉到Bob自己的存储库中,这样Bob就可以看到:

          I   <-- origin/dev
         /
...--G--H
         \
          J   <-- dev (HEAD)  [Bob's computer]

Bob应该用git fetch或git fetch origin来做这个,也许用——prune(或用fetch。修剪设置为true)。现在,当Bob运行git status时,他将得到“diverged”消息。

现在轮到鲍勃了,他是推举比赛的输家,他要弄清楚如何将他的工作(提交J)与爱丽丝的工作(提交I)结合起来。两个主要的是git merge和git rebase。我们不会在这里讨论谁应该做什么、什么时候做以及为什么做,只是说明当您认为自己严格领先于其他一些Git时,这是另一种可能陷入“分歧”状态的方式。


只是说说我的遭遇。

我提交了一堆文件,意识到有一些文件我不想提交,所以我使用VS代码撤销上次提交,删除文件并添加到gitignore,然后强迫我再次提交。

这显然导致git认为我的提交仍然必须进行远程,因为本地文件以某种方式提交了。

通过撤销上次提交和取消当前gitignore中的文件来解决


我得到了以下与实际问题相关的问题,你的分支领先于'起源/测试/KB-200' 17次提交

原因:上周我创建了PR进行审查,然后我关闭了项目。然后今天,我打开了项目,在同一个分支(测试/KB-200)中做了轻微的改变,我首先运行git pull。这个拉包含了其他开发人员在项目中工作的18个新提交,这使得我的本地分支领先于远程分支,因此我得到了这条消息。所以我只需要运行以下命令:

git push origin testing/KB-200

然后所有的都是同步的和最新的。[关于分支测试/KB-200您的分支是最新的'origin/testing/KB-200']