436

这实际上是如何发生的?

目前我自己在一个仓库中工作,所以这是我的工作流程:

  1. 更改文件
  2. 犯罪
  3. 重复1-2直到满意
  4. 推送到大师

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


包括消息中打印的分支

我的本地分支领先于主人

你在哪里推/拉当前分支

我正在推送到 GitHub 并拉到我当时正在使用的任何一台计算机上,我的本地副本始终是最新的,因为我是唯一一个在使用它的人。

它实际上并没有检查远程仓库

我就是这么想的,我想我会确保我对它的理解是正确的。

您是否向它传递了一些额外的论点?

不是我能看到的,也许我这边有一些有趣的配置?

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

21 回答 21

527

如果您在执行 a 后收到此消息git pull remote branch,请尝试使用 a 跟进它git fetch。(可选地,运行git fetch -p以从 repo 中修剪已删除的分支)

Fetch 似乎更新了远程分支的本地表示,当您执行git pull remote branch.

于 2010-07-24T05:26:11.887 回答
177

利用

git pull --rebase

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

于 2014-03-13T15:19:52.257 回答
121

使用这 3 个简单的命令

第 1 步git checkout <branch_name>

第 2 步git pull -s recursive -X theirs

第 3 步git reset --hard origin/<branch_name>

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

享受。

于 2016-09-26T08:59:58.120 回答
52

我认为您误读了消息-您的分支不是领先于master而是 master。它的前面origin/master,它是一个远程跟踪分支,它记录了从你最后一个pushpullfetch. 它准确地告诉你你做了什么;你走在遥控器前面,它在提醒你推。

于 2010-03-12T19:54:30.393 回答
40

这对我有用

git reset --hard origin/master

输出必须看起来像

On branch dev HEAD is now at ae1xc41z Last commit message

于 2019-05-29T07:25:42.687 回答
27

有人说你可能误读了你的信息,你不是。这个问题实际上与您的<project>/.git/config文件有关。其中将有一个与此类似的部分:

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

如果您从项目的 .git/config 文件中删除 fetch 行,您将停止“您的分支在 'origin/master' 之前N提交。” 烦恼的发生。

或者我希望如此。:)

于 2010-12-04T02:44:29.310 回答
25

我在我的舞台服务器上遇到了这个问题,我只做拉。硬重置帮助我将 HEAD 清理到与遥控器相同的位置。

git reset --hard origin/master

所以现在我又有了:

On branch master
Your branch is up-to-date with 'origin/master'.
于 2016-09-06T09:28:03.127 回答
12

我浏览了这个页面上的每一个解决方案,幸运的是@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

祝你好运

于 2016-12-06T08:31:52.817 回答
12

就我而言,这是因为我切换到 master 使用

 git checkout -B master

只是为了拉取它的新版本而不是

 git checkout master

第一个命令将主人的负责人重置为我最新的提交

我用了

git reset --hard origin/master

解决这个问题

于 2016-12-15T07:03:26.803 回答
8

注意:在我写这个答案的时候,这个特殊的问题已经很老了。它是在第一个版本的 Git 版本发布之前三年发布的,该版本修复了许多这些问题。 不过,似乎值得添加一个现代答案和解释器。 现有接受的答案建议 running git fetch -p, 1这是一个好主意,尽管这些天不太经常需要。在 Git 版本 1.8.2 出来之前,它是非常必要的;Git 是在最初的问题发布三年后发布的。


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


这实际上是如何发生的?

最初的问题是:

这实际上是如何发生的?

这个问题的事实是,在 之后git push origin master,OP 运行git status并看到On branch master后面的消息Your branch is ahead of 'origin/master' by 1 commit. 要正确回答问题,我们需要将其分解为多个部分。

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

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

这些--set-upstream-to--unset-upstream影响了当前的分支。当前分支是你的那个on,当git statuson branch xyzzy或者它说什么。您可以使用或(从 Git 2.23 开始)<code>git 开关选择此分支。2 无论您签出的哪个分支,都是您所在的分支。3git checkout

如果您使用--unset-upstream,这将删除当前分支的上游。没有上游,这会阻止关于领先或落后或分歧的信息。但是此消息是有用的,因此您可能不应该仅仅删除上游作为使其停止发生的一种方式。(请随意忽略该消息——毕竟这不是错误——如果你觉得它没有用处。)

如果您运行git branch --set-upstream-to=origin/xyzzy,则将当前分支的上游设置为origin/xyzzy。对于名为 的分支xyzzy,这将是典型的正确设置。某些创建分支的行为会自动设置(通常是正确的)上游,而有些则不会,因此如果您使用自动设置正确上游的分支创建操作,则无需执行任何操作。如果您想要一个不同的上游,或者如果您使用了没有设置上游的分支创建操作,您可以使用它来更改上游。

您可以将上游设置为:

  • 您自己的另一个(本地)分支:git branch --set-upstream-to=experiment使您自己的本地experiment成为当前分支的上游;或者
  • 您的任何远程跟踪名称,例如origin/mainororigin/masterorigin/xyzzy。这些是 输出的名称git branch -r。Git 调用这些远程跟踪分支名称(我喜欢在这里去掉“分支”这个词),稍后我们将详细讨论它们。

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

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

where$branch是当前分支名称,并且$upstream是来自其上游设置的字符串(从git branch --set-upstream-to上面)。这里两个名字之间有三个点,要吐出两个数字都需要--count, , 和三个点。--left-rightgit rev-list


2如果您拥有 Git 2.23 或更高版本,那么迁移到该版本是一个好主意,git switch因为它可以避免一些git checkout在历史上导致初学者陷入困境(有时甚至会绊倒 Git 专家)的棘手行为。但是,如果您习惯了git checkout,您可以继续使用它,只要您愿意,因为它仍然受支持。真正的问题基本上git checkout是太强大了,可能会意外地破坏工作。新git switch的故意不那么强大,不会那样做;“故意破坏我的工作”行动被移入git restore.

3在 Git 所谓的分离 HEAD模式下,可能不在任何分支上。如果你使用它可以让你突然进入这种模式(虽然它会打印一个很大的可怕警告,所以如果你没有看到可怕的警告,它没有这样做),但如果你使用,你必须允许分离头模式与。这种模式没有任何问题,你只需要小心,不要丢失你所做的任何新提交。如果您不小心,很容易丢失它们。在正常模式下,Git 不会像这样丢失新的提交。git checkoutgit switchgit switch --detach

如果您处于分离 HEAD 模式,则根据定义,您没有上游,因为您没有分支,并且此问题中的任何内容都不适用。


可达性

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

Git 存储库中的每个提交都有编号,带有一个大而难看的十六进制字母和数字字符串。这是提交的哈希 ID,它是 Git真正找到提交的方式。

每个提交包含两件事:每个源文件的完整快照(以特殊的、压缩的、Git 化的和去重的形式),以及关于提交本身的一些信息:元数据告诉谁做了它,时间和原因(他们的日志消息),例如。在元数据中,每个提交都包含一些较早提交的提交编号。这意味着一个提交可以找到另一个更早的提交。

正如Think Like (a) Git所说,这有点像火车。一旦你火车上,那就太好了,在这种情况下,它会自动带你倒退到所有较早的火车站点。但首先你必须找到火车站的路。Git 分支名称会这样做:它保存分支上最新提交的哈希 ID。

我们可以这样画:

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

分支名称branch包含最新提交的哈希 ID。我们说名称指向提交。无论真正的大丑哈希 ID 是什么,我们都只是H在这里用这个字母来代替它。

H是一个实际的提交,所以它有一个保存的快照——你的文件——和一些元数据。在元数据中,Git 保存了较早提交的哈希 ID。我们将其称为较早的提交G。我们说那H 指向 G。Git 可以H通过分支名称指针找到,这使 Git 可以访问提交,包括元数据,所以现在 Git 具有较早提交的哈希 ID G

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

这将永远重复,或者更确切地说,直到我们进行第一次提交。该提交(大概我们在A这里称其为)并不指向更早的提交,因为没有更早的提交。

这种可达性的概念基本上是对如果我们从提交开始会发生什么的总结H,如分支名称所发现的那样branch,然后向后工作。我们到达 commit H,向后到达 commit G,返回到F,依此类推。

分支名称和远程跟踪名称

正如我们刚刚提到的,分支名称包含某个提交的原始哈希 ID。这让 Git可以找到那个提交。不过,还有一个关于分支名称的特殊功能。

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

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

我们在“on”分支xyzzy,我喜欢通过附加特殊名称HEAD来表示它。当图中有多个分支名称时,这很有用。请注意,H目前是最新的提交。但是现在我们将按照通常的方式制作另一个。

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

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

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

如果你说:在一个分支名称中,你是对的。事实上,正确的分支名称——无论如何,就 Git 而言——是你现在“启用”的那个。这就是我们HEAD在这张图中附加的那个。所以现在,作为 的最后一部分git commit,Git 将I的哈希 ID 写入 name xyzzy。这使它指向 commit I,如下所示:

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

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

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

这就是分支名称的工作方式。最后,这真的很简单:它只需要你同时考虑几件事。该名称找到提交。它找到最新的提交。从那里开始,Git向后工作,因为每个提交都会找到更早的提交。

远程跟踪名称呢?好吧,这里的诀窍是您的 Git 与其他 Git 对话。 每个 Git 都有自己的分支名称。 你有你的 masteror main; 他们有他们的。你有你的 xyzzy分支,他们也​​可以有他们的。

你的 Git可以随时、每次都调用他们的 Git,并询问他们的分支名称。但是,这不是很有效,并且如果您与 Internet 断开连接,它也不起作用。4 无论如何,Git 不会那样做。相反,当您的 Git 调用他们的 Git 并从他们那里获取所有分支名称和哈希 ID 的列表时,您的Git 会获取这些名称和哈希 ID 并将它们存储在您的存储库中。当您运行时会发生这种情况git fetch5

不过有问题。他们的mainor master,或者xyzzy如果他们有的话,并不一定意味着与您的or or相同的提交。解决方案很简单:Git 只取他们的分支名称并将其转换为您的远程跟踪名称 mainmasterxyzzy

如果origin's mainor masterorxyzzy已移动,您只需运行git fetchor git fetch origin,也许与--prune. 你的 Git 调用他们的 Git。他们列出了他们的分支名称和提交哈希 ID。如有必要,您的 Git 会从他们那里获得任何新的提交:他们有的提交,而您没有。然后,您的 Git 将它们的分支名称转换为您的远程跟踪名称,并创建或更新您的远程跟踪名称以记住它们的分支名称指向的位置,在您运行此git fetch.

如果您使用--prune,这将处理他们删除某些分支名称的情况。假设他们有一个名为oldstuff. 你早点得到它,所以你有origin/oldstuff你的远程跟踪名称。然后他们删除 oldstuff了,所以这次他们......只是不再拥有它了。如果没有--prune,您的 Git 会忽略这一点。origin/oldstuff即使它现在已经死了, 你仍然保持旧的。使用 --prune,您的 Git 会说:哦,呵呵,这现在看起来已经死了并将其修剪掉:您的Git 中的远程跟踪名称与它们的分支名称之一不对应,只会被删除。

prune 选项可能应该一直是默认选项,但它不是,因此现在不能。6但是 ,您可以配置fetch.prune为默认值。true


4与 2010 年相比,现在 2021 年的情况不太常见。在 2005 年 Git 首次发布时,这种情况要普遍得多。过去的情况是,例如,在飞往 Linux 会议的航班上,您无法以任何价格访问 Internet。

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

6 Git 通常非常重视向后兼容性。例如,从 1.x 到 2.0 的转换将push.default默认设置从matching更改simple为 。


如何git rev-list得到这两个数字

早些时候,我注意到git status打印的前面、后面、最新或发散的消息来自运行:

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

这里git rev-list的作用是count reachable commitsgitrevisions 文档中描述的三点语法产生集合论中所谓的对称差分。但是,在非数学术语中,我们可以将其视为进行两次提交可达性测试,我们可以这样绘制:

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

J在这里,可以从您的分支 name 访问commit xyzzy,因为 name 指向那里。CommitI可以从 commit 到达J,所以它也很重要。这导致返回提交H——从图中可以看出,这有点特别。

同时,K可以从您的远程跟踪名称访问提交origin/xyzzy。提交H可以从K. 从 commit Hon back 开始,commitsG等等F都是可以访问的。但是两个“铁轨”在commit处合并H:commitH和所有早期的提交都可以从两个名称中访问。

这使得提交变得I-J特别,因为它们 *only 可以从 name 访问xyzzyK特别是它*only 可以从 name 访问origin/xyzzy。三点符号查找这些提交:只能从一个名称访问的提交,或者只能从另一个名称访问的提交。

如果我们把分支名称放在左边,把它的上游放在右边,并使用三点符号,我们将找到所有这三个提交。使用--count使得git rev-list打印这个数字: 3. 使用--left-righttellgit rev-list更聪明,但是:它应该计算由于左侧名称(当前分支名称)而被计数的提交数量,以及由于右侧名称而被计数的提交数量,上游的。因此,通过这两个选项和三个点,我们得到:

2       1

作为输出,告诉我们有两个提交 on xyzzythat are not on origin/xyzzy,一个提交 on origin/xyzzythat is not on xyzzy。这些分别是提交J- 和 - I(on xyzzy) 和K(on origin/xyzzy)。

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

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

(再次注意三个点:参见gitrevisions并搜索 Symmetric Difference)我们将获得显示的三个提交,再次以<or>为前缀。

这是查看哪些提交在您的分支上以及哪些提交在上游的简单方法。--decorate它通常与, --oneline, and 一起使用更有用(在某些情况下--graph您可能还想添加)。--boundary

领先、落后、分歧或最新

所以,假设我们已经运行:

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

(或者 -再次参见gitrevisions$branch@{upstream} -在此处使用右侧)并得到我们的两个计数。这些可以是:

  • 0and 0:我们的分支名称和我们的远程跟踪名称(或上游中的任何名称)指向同一个提交。没有人领先或落后。git status命令会说Your branch is up to date with '<upstream>'

  • 非零,零:当前分支上有不在上游的提交。上游没有不在当前分支上的提交。所以我们的分支领先于上游。

  • 零,非零:当前分支上没有不在上游的提交,但上游有一些不在当前分支上的提交。这意味着我们的分支上游之后。

  • 非零,非零:这就像我上面画的图。当前分支和它的上游都同时相互领先和落后。该git status命令将使用单词diverged.

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

这实际上是如何发生的?

在 OP 的场景中,只有一个人在进行新的提交并使用git push. 如果我是一个人,我可能会git clone从 GitHub 获取一些东西,然后进行一两次新的提交,然后git push origin master.

在现代 Git 中,git status会告诉我我是最新的。在非常旧的 Git 版本中,现在git status会告诉我 my领先于. master origin/master 原因很简单:以前git push 更新失败origin/master。运行git fetch origin,或者只是git fetch,让你自己的 Git 在 GitHub 上调用 Git,阅读他们的信息,并意识到你git push已经工作了。

当你运行时git push,你的 Git 会调用其他 Git。然后,您的 Git 会向另一个 Git 提供您拥有的任何新提交,而他们没有提交,他们需要完成git push. 他们接受这些提交并将它们放在某个地方。7 然后你的 Git 询问他们的 Git——礼貌地询问,默认情况下——如果他们愿意,请设置他们的 分支名称,通过其哈希 ID 引用最新的提交,如你的分支名称中所示。这里没有远程跟踪的东西。您只是要求他们设置您使用的相同名称。

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

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

在旧的 Git 版本中,你的 Git 只是懒得做这个。在 Git 版本 1.8.2 中,Git 作者最终解决了这个问题:git push基于他们的 Git 同意您的 Git 提供的更新这一事实,您的 Git 成功更新了您的远程跟踪名称。所以这种事情不会再发生了。


7在过去糟糕的日子里,他们将它们直接放入存储库中。在现代 Git 中,他们将它们放在隔离区,并且只有在他们真正接受新提交时才将它们迁移到他们的存储库中。

8当然,像 GitHub 这样的地方也提供了受保护的分支等功能,例如,它只是对每次推送说不。我们还可以创造更奇特的场景,例如当您拥有多台计算机并忘记您通过计算机 A 进行和推送新提交时,现在尝试从计算机 B 推送。


如果你不是唯一一个在做的人怎么办git push

假设 Alice 和 Bob 都克隆了一些 GitHub 存储库。此存储库中的开发发生在分支上dev(用于开发)。所以爱丽丝dev从她身上创造了自己的origin/dev

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

Bob,同样,制作了他自己的dev

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

GitHub 存储库也dev结束于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 都尝试git push origin dev. 其中一个最先到达那里——也许是爱丽丝:

...--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 现在需要从 GitHub 将提交 yankI到 Bob 自己的存储库中,以便Bob看到:

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

Bob 应该使用git fetchor来执行此操作git fetch origin,也许可以使用--prune(或fetch.prune设置为true)。 现在,当 Bob 运行时git status,他将收到“发散”消息。

现在轮到鲍勃,作为推动竞赛的失败者,要弄清楚如何将他的工作(提交J)与爱丽丝的(提交I)结合起来。有不同的方法可以组合工作。两个主要的是git mergegit rebase。我们不会在这里讨论谁应该做什么、什么时候做以及为什么做,只是当你认为自己完全领先于其他 Git 时,这是另一种可能会陷入“分歧”状态的事实。

于 2021-04-07T07:52:30.363 回答
4

我在 Windows 机器上遇到了同样的问题。当我运行一个git pull origin master命令时,我会收到“X 提交领先于'origin/master'”的警告。我发现如果我改为运行git pull origin并且没有指定分支,那么我将不再收到警告。

于 2013-09-11T18:30:01.547 回答
3

git fetch将为您解决这个问题

如果我的理解是正确的,那么您的本地(缓存)origin/master已过时。此命令将从服务器更新存储库状态。

于 2018-08-25T03:55:17.440 回答
2

它只是提醒您当前分支与执行当前轨道的分支之间的差异。请提供更多信息,包括消息中打印的分支以及您在哪里推/拉当前分支。

于 2010-03-12T12:21:02.843 回答
2

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

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

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

每当我切换到“web”分支时,它告诉我我在开发之前有 100 多个提交。好吧,我不再致力于开发,所以这是真的。我能够简单地删除此条目,它似乎按预期运行。它与远程参考正确跟踪,而不是抱怨在开发分支后面。

正如维克拉姆所说,这个 Stack Overflow 线程是谷歌搜索这个问题时的最高结果,所以我想我会分享我的情况和解决方案。

于 2013-09-10T18:57:22.420 回答
2

我想重申上面@Marian Zburlia 提到的相同内容。它对我有用,并且会向其他人提出相同的建议。

git pull origin develop

应紧随其后$ git pull --rebase

这将删除$ git status最新拉后出现的评论。

于 2017-11-20T16:29:42.623 回答
2

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

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

事实证明,我已经在develop几周前将更改从公共分支拉入了我的特性分支——但是忘记了!当我今天重新访问我的本地功能分支并进行了一次git pull origin develop操作时,这个数字跃升至 +41 次提交。很多工作已经完成develop,所以我的本地特性分支甚至比origin存储库上的特性分支更早。

因此,如果您收到此消息,请回想一下您可能从您有权访问的其他分支(您自己的或其他分支)所做的任何拉取/合并。该消息只是表明您需要将git push这些pulled 更改origin从本地存储库返回到存储库(“跟踪分支”)以使事情同步。

于 2019-02-20T20:14:00.190 回答
1

虽然这个问题有点老了......我遇到了类似的情况,我在这里的回答帮助我解决了我遇到的类似问题

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

如果这不起作用,那么(在我的情况下)远程存储库(或者更确切地说是对显示在 上的远程存储库的引用git remote -v)可能没有得到更新。

上述结果是您的推送将您的本地/分支与远程/分支同步,但是,本地存储库中的缓存仍将先前的提交(本地/分支的......如果仅推送单个提交)显示为 HEAD。

要确认上述在不同位置克隆 repo 并尝试比较本地/分支 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 ### 注意你的命令已经没有origin了!

git pull现在 做git pull github master

git status收到时

# On branch master

nothing to commit (working directory clean)

我希望这对某人有用,因为视图数量如此之多以至于搜索此错误几乎总是将此线程列在顶部

另请参阅gitref了解详情

于 2013-07-10T21:43:06.690 回答
1

建议git pullgit fetch正确的答案。
当看到和(例如) git status之间的差异时会生成该消息。.git/FETCH_HEAD.git/refs/remotes/<repository>/<branch>.git/refs/remotes/origin/master

后一个文件记录了上次获取的 HEAD(用于存储库/分支)。git fetch将两个文件都更新到分支的当前 HEAD 。
当然,如果没有要获取的内容(因为本地存储库已经是最新的),则.git/FETCH_HEAD不会更改。

于 2014-01-22T16:55:27.870 回答
1

我得到以下与实际问题有关的内容Your branch is ahead of 'origin/testing/KB-200' by 17 commits

原因:我上周创建了 PR 以供审核,然后我关闭了该项目。然后今天打开项目在同一个分支上做个小改动(testing/KB-200)就先跑了git pull。这个拉取包含 18 个由其他开发人员在该项目上工作的新提交,这使得我的本地分支通过这些提交领先于我的远程分支,因此我收到了这条消息。所以我只需要运行以下命令:

git push origin testing/KB-200

然后它全部同步并且是最新的。[On branch testing/KB-200 Your branch is up to date with 'origin/testing/KB-200']

于 2021-06-30T11:20:52.220 回答
0

只是分享发生在我身上的事情。

我提交了一堆文件并意识到有些文件我不想提交,所以我使用 VS 代码来undo last commit删除文件并添加到 gitignore,然后再次强制推送我的提交。

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

解决undo last commit并取消暂存 gitignore 中的文件

于 2021-06-16T16:44:58.020 回答
0

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

于 2018-03-26T06:25:07.317 回答