git - 为什么 Git 说我的主分支是 "already up to date"即使它不是?

标签 git github merge

基本问题

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

git pull upstream master

从上游获取和 merge (所以理论上删除的代码应该回来)。

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

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

其他相关信息

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

我最近设置了“master”来跟踪上游,如下所示:

Branch master set up to track remote branch master from upstream.



命令 git branch -vv产量:
* master 7cfcb29 [upstream/master: ahead 9] deletion test

为什么为什么会发生这种情况?我即将通过电子邮件向我的项目经理发送我对代码所做的任何更改。

更新

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

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

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

最佳答案

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

当您克隆某个其他存储库时,git 会复制“那边”的任何内容。它还需要“他们的”分支标签,例如 master ,并复制该标签的副本,该标签在您的 git 树中的“全名”是(通常)remotes/origin/master (但在你的情况下, remotes/upstream/master )。大多数情况下,您可以省略 remotes/部分也是如此,因此您可以将该原始副本称为 upstream/master .

如果您现在对某些文件进行并提交一些更改,则您是唯一进行这些更改的人。与此同时,其他人可能会使用原始存储库(您从中制作克隆)来制作其他克隆并更改这些克隆。当然,他们是唯一有变化的人。但最终,有人可能会将更改发送回原始所有者(通过“推送”或补丁或其他方式)。
git pull命令主要是 git fetch 的简写其次是 git merge .这很重要,因为这意味着您需要了解这两个操作的实际作用。
git fetch命令说返回到你克隆的任何地方(或以其他方式设置为从中获取的地方)并找到“其他人添加、更改或删除的新内容”。这些更改被复制并应用到您之前从它们那里获得的副本。它们不适用于您自己的工作,仅适用于他们的工作。
git merge命令更复杂,这就是你出错的地方。它所做的稍微简单化了一点,就是将“您在副本中更改的内容”与“您从其他人那里获取的更改内容添加到您的其他人的工作副本中”进行比较。如果您的更改和它们的更改似乎没有冲突,merge操作将它们混合在一起并为您提供“merge 提交”,将您的开发和它们的开发联系在一起(尽管有一种非常常见的“简单”情况,您没有更改并且您会得到“快进”)。

您现在遇到的情况是您进行了更改并进行了更改——实际上是 9 次,因此是“前进 9”——而他们没有进行任何更改。所以,fetch尽职尽责地什么也不取,然后 merge接受他们缺乏变化,也不做任何事情。

您想要的是查看或什至“重置”到“他们的”代码版本。

如果你只是想看看它,你可以简单地查看那个版本:

git checkout upstream/master

这告诉 git 你想把当前目录移动到全名实际上是 remotes/upstream/master 的分支。 .您将看到上次运行时的代码 git fetch并得到了他们的最新代码。

如果你想放弃你自己的所有改动,你需要做的是改变git对你的标签是哪个版本的想法,master ,应命名。目前它命名你最近的提交。如果你回到那个分支:
git checkout master

然后是 git reset命令将允许您“移动标签”,就像它一样。唯一剩下的问题(假设你真的准备放弃你所做的一切)是找到标签应该指向的地方。
git log会让你找到数字名称——比如 7cfcb29 之类的东西——它们是永久的(永远不会改变的)名字,还有很多其他的方法来命名它们,但在这种情况下,你只想要名字 upstream/master .

要移动标签,清除您自己的更改(您提交的任何更改实际上都可以在很长一段时间内恢复,但在此之后要困难得多,因此请务必确保):
git reset --hard upstream/master
--hard告诉 git 清除你一直在做的事情,移动当前的分支标签,然后检查给定的提交。

真正想要的不是 super 常见的 git reset --hard并抹去一堆工作。一种更安全的方法(如果您认为其中的一些工作是值得的,那么恢复工作会更容易)是重命名现有分支:
git branch -m master bunchofhacks

然后创建一个名为 master 的新本地分支那个“跟踪”(我真的不喜欢这个词,因为我认为它让人们感到困惑,但那是 git 术语 :-) )起源(或上游)大师:
git branch -t master upstream/master

然后你可以开始:
git checkout master

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

在做任何事情之前:
C0 -    "remotes/upstream/master"
    \
     \- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9    "master"

之后 git branch -m :
C0 -    "remotes/upstream/master"
    \
     \- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9    "bunchofhacks"

之后 git branch -t master upstream/master :
C0 -    "remotes/upstream/master", "master"
    \
     \- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9    "bunchofhacks"

这里C0是您第一次做 git clone 时得到的最新提交(完整的源代码树)。 . C1 到 C9 是你的提交。

请注意,如果您要 git checkout bunchofhacks然后 git reset --hard HEAD^^ ,这会将最后一张图片更改为:
C0 -    "remotes/upstream/master", "master"
    \
     \- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 -    "bunchofhacks"
                                                      \
                                                       \- C8 --- C9

原因是HEAD^^将修订版命名为从当前分支的头部开始(在重置之前是 bunchofhacks )和 reset --hard然后移动标签。提交 C8 和 C9 现在大部分是不可见的(你可以使用诸如 reflog 和 git fsck 之类的东西来找到它们,但这不再是微不足道的了)。您的标签可以随心所欲地移动。 fetch命令处理以 remotes/ 开头的那些.通常将“你的”与“他们的”匹配(所以如果他们有 remotes/origin/mauve,你也可以命名你的 mauve),但你可以在任何时候输入“他们的”,只要你想命名/查看你得到的提交“从他们”。 (请记住,“一次提交”是一整个源代码树。您可以从一次提交中挑选出一个特定的文件,例如 git show,如果需要的话。)

关于git - 为什么 Git 说我的主分支是 "already up to date"即使它不是?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15376241/

相关文章:

使用动态主机的 Node.js GitHub oAuth 回调?

sorting - Lua中的合并函数

python - pandas 中的高效链合并

Git:如何将两个标签之间所做的更改 merge 到另一个分支?

来自 IDEA 的 github 提交未显示在贡献事件中

git push 在 MacOS Sierra 10.12.5 中失败

excel - Excel 中的自动分组/合并

git - `git push` 到底做了什么?

linux - 在后续 git 命令中使用 git 命令的输出路径的最简单方法是什么?

git - 我可以使用自定义标志扩展 git 命令吗?