github - 为什么Git说我的主分支“已经是最新的”,即使它不是?

基本问题

我刚从项目中的文件中删除了所有代码,并将更改提交给我的本地git(故意)。 我做到了

git pull upstream master

从上游获取和合并(因此理论上应该返回已删除的代码)。

Git告诉我一切都是最新的。

一切都绝对不是最新的 - 所有删除的代码仍然被删除。

其他相关信息

我只有一个名为" master"的分支。

我最近成立了#34; master" 像这样跟踪上游:

分支主站设置为从上游跟踪远程分支主站。

命令git branch -vv产生:

* master 7cfcb29 [upstream/master: ahead 9] deletion test

为什么会出现这种情况的原因? 我只是通过电子邮件向我的项目经理发送了我对代码所做的任何更改。

更新

我认为这很明显,但无论如何这是我的目标:

获取我系统上最新的代码。

请原谅我的愤怒,但为什么这么简单的任务必须如此努力?

user1971506 asked 2019-08-12T09:53:04Z
6个解决方案
173 votes

我认为你的基本问题是你误解和/或误解了git的作用以及它为什么会这样做。

当你克隆一些其他的存储库时,git会复制那些"在那里"。 它还需要"他们的" 分支标签,例如HEAD^^,并制作该标签的副本,其全名为#34; 在你的git树是(通常)bunchofhacks(但在你的情况下,reset --hard)。 大多数情况下,您也省略了git fsck部分,因此您可以将该原始副本称为fetch

如果您现在对某些文件进行了一些更改并对其进行了一些更改,那么您就是唯一一个有这些更改的人。 与此同时,其他人可能会使用原始存储库(您从中创建克隆)来创建其他克隆并更改这些克隆。 当然,他们是唯一有变化的人。 但最终,有人可能会将更改发送回原始所有者(通过"推送"或补丁或其他)。

HEAD^^命令主要是bunchofhacks的简写,后跟reset --hard。这很重要,因为这意味着您需要了解这两个操作实际执行的操作。

HEAD^^命令表示返回到您从中克隆的位置(或以其他方式设置为获取的位置)并查找其他人添加或更改或删除的新内容"。 这些更改将复制并应用于您之前从中获取的内容的副本。 它们不适用于您自己的工作,只适用于他们自己的工作。

HEAD^^命令更复杂,是您出错的地方。 它做了什么,过度简化了一下,比较了你在副本中改变了什么" 改变你从别人那里获得的改变,从而被添加到你的另一个人的副作品中#s;#34;。 如果您的更改及其更改似乎没有冲突,则bunchofhacks操作会将它们组合在一起并为您提供"合并提交" 这将你的发展和他们的发展联系在一起(虽然有一个非常普遍的"简单"你没有变化的情况,你得到了一个快进#34;)。

你现在遇到的情况是你已经做出改变并提交了它们的情况 - 实际上是九次,而且他们没有做出任何改变。 因此,HEAD^^尽职尽责,然后bunchofhacks采取了他们没有改变,也没有做任何事情。

你想要的是看,甚至可能"重置" 到,"他们的" 代码的版本。

如果您只想查看它,您可以查看该版本:

git checkout upstream/master

这告诉git你想把当前目录移动到全名实际上是HEAD^^的分支。你上次运行bunchofhacks时会看到他们的代码并获得他们的最新代码。

如果您想放弃所有自己的更改,您需要做的是更改git对您的标签HEAD^^应该命名的修订版的想法。 目前它命名您最近的提交。 如果你回到那个分支:

git checkout master

然后HEAD^^命令将允许您按原样移动标签"。 唯一剩下的问题(假设你真的准备好放弃你所做的一切)就是找到标签所指的位置。

HEAD^^可以让你找到数字名称 - 像bunchofhacks这样的东西 - 它们是永久的(永不改变的)名字,还有一些荒谬的其他方法来命名它们,但在这种情况下你只需要名称reset --hard

要移动标签,擦除你自己的更改(你提交的任何内容实际上可以恢复很长一段时间,但在此之后它会变得更加困难,所以非常肯定):

git reset --hard upstream/master

HEAD^^告诉git消除你一直在做的事情,移动当前的分支标签,然后检查给定的提交。

真正想要HEAD^^并且消除一堆工作并不是超常见的。 一个更安全的方法(如果你决定其中一些是值得的,那么恢复这项工作要容易得多)就是重命名你现有的分支:

git branch -m master bunchofhacks

然后创建一个名为HEAD^^的新本地分支," track" (我不喜欢这个术语,因为我觉得它让人困惑,但这就是git术语:-))起源(或上游)主人:

git branch -t master upstream/master

然后你可以开始使用:

git checkout master

最后三个命令的作用(只有两个命令的快捷方式)是更改现有标签上粘贴的名称,然后创建一个新标签,然后切换到它:

在做任何事之前:

C0 -    "remotes/upstream/master"
    \
     \- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9    "master"

HEAD^^之后:

C0 -    "remotes/upstream/master"
    \
     \- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9    "bunchofhacks"

HEAD^^之后:

C0 -    "remotes/upstream/master", "master"
    \
     \- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9    "bunchofhacks"

HEAD^^是您第一次执行bunchofhacks时获得的最新提交(完整的源代码树).C1到C9是您的提交。

请注意,如果你是HEAD^^,然后是bunchofhacks,这会将最后一张图片更改为:

C0 -    "remotes/upstream/master", "master"
    \
     \- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 -    "bunchofhacks"
                                                      \
                                                       \- C8 --- C9

原因是HEAD^^将当前分支的头部(在重置之前为bunchofhacks)命名为修订版本2,然后reset --hard移动标签。 提交C8和C9现在几乎是不可见的(你可以使用像reflog和git fsck这样的东西找到它们,但它不再是微不足道的)。 无论你喜欢什么,你的标签都可以移动。 fetch命令负责处理以remotes/开头的命令。它可以匹配"你的" 用他们的"他们的" (所以,如果他们有remotes/origin/mauve,你也可以将你的名字命名为mauve),但你可以输入"他们的" 无论何时你想要命名/看到你得到的提交"来自他们"。 (请记住,"一次提交"是一个完整的源代码树。例如,如果需要,可以从一次提交中选择一个特定文件,例如git show。)

torek answered 2019-08-12T09:56:15Z
3 votes

正如其他海报所说,拉动将上游的变化合并到您的存储库中。 如果要将存储库中的内容替换为上游内容,则可以使用多个选项。 脱下袖口,我一起去

git checkout HEAD^1  # Get off your repo's master.. doesn't matter where you go, so just go back one commit
git branch -d master  # Delete your repo's master branch
git checkout -t upstream/master  # Check out upstream's master into a local tracking branch of the same name
Paul answered 2019-08-12T09:56:41Z
2 votes

您提交的任何更改(例如删除所有项目文件)在拉动后仍将保留。 拉动所做的就是将来自其他地方的最新更改合并到您自己的分支中,如果您的分支已经删除了所有内容,那么当上游更改影响您已删除的文件时,您最多会遇到合并冲突。 所以,简而言之,是的,一切都是最新的。

如果你描述了你想要的结果而不是"所有文件被删除",也许有人可以提出适当的行动方案。

更新:

在我的系统中获取最新的代码

您似乎不明白的是,您已经拥有最新的代码,这是您的代码。 如果您真正想要的是看到最新的其他人在主分支上的工作,那么就这样做:

git fetch upstream
git checkout upstream/master

请注意,这不会让您立即(重新)开始自己的工作。 如果您需要知道如何撤消已完成的内容或以其他方式还原您或其他人所做的更改,请提供详细信息。 另外,请考虑阅读版本控制的内容,因为您似乎误解了其基本用途。

Ryan Stewart answered 2019-08-12T09:57:39Z
2 votes

我遇到了和你一样的问题。

我做了git status git fetch git pull,但我的分支仍然落后于原点。 我将文件夹和文件推送到远程,我在网上看到了这些文件,但是在我当地的文件丢失了。

最后,这些命令更新了我本地的所有文件和文件夹:

git fetch --all
git reset --hard origin/master 

或者如果你想要一个分支

git checkout your_branch_name_here
git reset --hard origin/your_branch_name_here
Jozsef Turi answered 2019-08-12T09:58:27Z
1 votes

如果我错了,请有人纠正我,但我相信这是因为你的分支在9次提交之前领先于上游主分支。 当您从遥控器进行拉动时,您已经进行了这些更改,只是因为您提交了9次提交。 对于您在历史记录中已经拥有并且提前9次提交的旧更改来替换您的新更改是没有意义的。

我相信如果遥控器中的提交更新,那么它们将被合并(默认情况下;除非您指定--rebase)到您当前的分支。

像瑞安说的那样,我建议你准确说明你的目标是什么,以便有人可以更直接地帮助你。

Jorge Israel Peña answered 2019-08-12T09:59:09Z
1 votes

在给出的信息的广度和深度方面,最佳答案要好得多,但似乎您希望几乎立即修复问题,并且不要介意对版本控制的一些基本原则进行研究,您可以。..

  1. 切换到主人

    $ git checkout -b <new_branch_name>
    
  2. 删除不需要的分支。 (注意:它必须是-D,而不是普通的-d标志,因为你的分支在主服务器之前有很多提交。)

    $ git checkout -b <new_branch_name>
    
  3. 创建一个新分支

    $ git checkout -b <new_branch_name>
    
BrotherDonkey answered 2019-08-12T10:00:09Z
translate from https://stackoverflow.com:/questions/15376241/why-does-git-say-my-master-branch-is-already-up-to-date-even-though-it-is-not