将提交更改为 GitHub... 删除文件

Change a commit pushed to GitHub... removing files

Git 绞尽脑汁。但我想我已经解决了这个问题。

我提交(两次)并推送到 GitHub,但第一次提交包含两个不应该包含的文件。所以我做了以下...

git reset --hard HEAD~2

这使 HEAD 返回到带有额外文件的第一次提交。

HEAD is now at 1979096c2

现在,如果我仅使用需要的两个文件进行修改、提交(并强制推送),这是否更正了 GitHub 上的提交?

更清楚...初始(错误)提交包含 4 个文件。我想将其修改为只有 2 个文件。我在正确的轨道上吗?

你是对的,这会解决问题。小心用力推动,因为你基本上是在重写历史。拉取了您要删除的那些提交的任何人都将从远程分支。如果你是唯一一个在回购或分支上工作的人,那没关系。

除了进行硬重置,您还可以进行 git 还原。

git revert <commit_id>

使用 git log 来引用您要还原的提交 ID。

没有。

首先,当你说"amend, commit (and force push)"时,你指的是git commit --amend命令吗? amend 选项的命名可能有点混乱。虽然它确实反映了命令的目的,但它表明它编辑了现有的提交——它没有这样做,因为那是不可能的。

重置后是这样的

O <--(master)
 \
  A -- B <--(origin/master)

因此您提交了两次(AB),但是 A 包含您不需要的文件,因此您重置回 2 次提交(到 之前 A)。那么首先要了解的是,如果您从这里执行 commit --amend 它将修改提交 O - 而不是提交 A.

而且,"amend" 提交意味着什么——正如我上面所说的——你不能更改现有的提交?好吧,这意味着你创建了一个新的提交——它有一个新的 ID——和 "replace" 旧的提交。这听起来像头发分裂,但这很重要,因为 "replacing" 提交并没有完成您可能认为它会做的所有事情。

假设您重置为提交 A。在您描述的示例中,这将是 git reset --hard master^(在分支提示之前有 1 个提交 - 所以您已经检查了 "wrong" 的提交)。现在你有

O -- A <--(master)
      \
       B <--(origin/master)

现在您可以编辑工作树(即删除不需要的文件),然后您可以告诉 git "amend" 提交 A。但你得到的是

O -- A -- B <--(origin/master)
 \
  C <--(master)

C 是具有新 ID 的新提交。如果您只在 commit --amend 之前进行了小的更改,那么它会应用 大部分 相对于 OA 相同的更改 - 但它是仍然是一个完全不同的承诺。在您本地分支的历史记录中,C 替换了 A - 但 仅在您的本地分支中 - 而不是整个存储库。 B 仍将 A 视为其父级,并且 origin/master 仍指向 B.

如果您随后强制推送,您将 origin/master 移动到 C。这是历史编辑,如果存储库与其他人共享,则会产生影响。请参阅 "recovering from upstream rebase" 下的 git rebase 文档;本节适用于任何重写,无论是否涉及 rebase 命令。另请注意,如果您没有与存储库的其他用户正确协调强制推送,则他们中的任何一个都可能在恢复和撤消您所做的更改时做错事。

因此,除了用 C 替换 A 之外,此过程还从分支历史记录中删除了 B,因为“用 C 替换了 A”不是整个存储库的就地替换。

您可以通过将 BA 变基到 C 来解决这个问题。有几种方法可以解决这个问题,例如

git checkout origin/master
git rebase --onto master HEAD^

这给你

O -- A -- B <--(origin/master)
 \
  C -- B' <--(master)

这里我使用了一个表示法,表示新提交 (B') 应用了与旧提交 (B) 相对于新基础相同的更改 - 但它仍然是一个全新的提交。同样,这是历史重写,您必须与任何其他用户协调并强制推送。

根据应将这些文件从存储库中排除的原因,知道这(还)不会物理删除原始历史记录(包括您已删除的文件)也很重要。只要旧历史保留在 reflog 中,您的本地存储库就会保留它们。您可以采取一些步骤在本地执行早期清理;但是远程(取决于它的托管方式)可能有也可能没有从那里删除文件的方便程序。您无法保证从可能存在的任何其他克隆中删除这些文件。

因此,如果文件包含敏感信息(并且如果其他人可以访问远程文件),您将需要将该信息视为已泄露。如果文件非常大,您可以搜索现有的问题和答案,详细说明如何从历史记录中清除它们以恢复 space