【问题标题】:Git revert/checkout for specific files touches them, but leaves contents unchanged特定文件的 Git 还原/签出会触及它们,但保持内容不变
【发布时间】:2025-12-06 10:20:03
【问题描述】:

我的同事前段时间添加了一些 .ps1 文件(此后提交了几次,他可能稍后只修改了其中一个文件等 - 所以我们不能假设这一切都是在一次提交中完成的)。假设它们是在 commit1 中添加的,后来在 commit5 中修改了其中一个文件。

然后,我不小心对那些 .ps1 文件提交了一些本地更改(特定于我的环境),以及我真正想要提交的其他更改。我只是暂存了所有更改并忘记排除我对 .ps1 文件的更改(我想保留在本地,但不提交)。我们可以称之为 commit14。

然后我再次提交(到其他文件,commit15)并推送我的更改。

基本上是这样的:

commit15   me         Foo.cs, Bar.cs
commit14   me         Foo.cs, Bazz.cs, [File1.ps1, File2.ps1, File3.ps1]
commit13   co-worker  SomeCode.cs
...
commit5    co-worker  File2.ps1
...
commit1    co-worker  File1.ps1, File2.ps1, File3.ps1 (added)

我已经尝试通过丢弃 Bitkraken 中的任何本地更改然后 cd'ing 进入包含文件的目录并运行来恢复这三个 .ps1 文件(在上面的方括号中标记):

$ git checkout commit14~1 -f -- File1.ps1 File2.ps1 File3.ps1

没有输出,但文件随后被自动列为在 Bitkraken 中暂存。这让我充满了希望 - 但后来我意识到文件内容是相同的(包括我想要恢复的更改)。

我也试过这样:

$ git reset commit14~1 -- File1.ps1 File2.ps1 File3.ps1

输出如下:

Unstaged changes after reset:
M       My/Path/File1.ps1
M       My/path/File2.ps1
M       My/Path/File3.ps1

结果还是一样,文件内容没有改变。 我什至尝试过明确指定“commit13”而不是“commit14~1”,但这也没有用。

我做错了什么?

所有这一切都发生在一个名为“dev”的分支上,以防万一。

而且我不确定 .ps1 文件的实际历史记录,但如果我不必找出每个文件的最后一次提交,我会非常喜欢。这很容易超过 3 个文件。肯定有办法说“将这些文件改回我不小心提交它们之前的状态,无论它们最后一次更新是什么时候”。

谢谢。

【问题讨论】:

  • 我想你不知道你的 ps1 文件什么时候改变了。只需使用 diff 记录日志即可找出答案。
  • 根据您对所提供答案的评论,我相信这就是您所需要的:*.com/questions/10755655/git-ignore-tracked-files
  • @matt 如果我不必这样做,我会非常喜欢。想象一下,如果它是 30 个文件,而不是 3 个!没有别的办法吗?
  • @joanis 我的问题是关于保留文件的先前版本,而不是忽略/排除它们。我只想恢复我自己对这些文件的更改。所以它不是重复的。
  • @TravelingFox 对我的误解深表歉意,我将撤回我的“重复”投票。幸运的是,没有人同意我的看法。

标签: git revert git-revert


【解决方案1】:

从版本控制中删除文件的最简单方法是

git rm <file name>
git commit

如果您仍然需要这些文件作为本地配置的一部分,只需将它们备份到另一个文件夹,然后在运行这些命令后将它们复制回您的项目文件夹。

您还应该将配置文件添加到.gitignore,以免将来出现此错误。

【讨论】:

  • 对不起,我可能不够清楚。这些文件包含一些配置。我想保留它们。它们是由一位同事在几次提交前添加的。我只是不想保留我自己对这些文件的更改(因为它们特定于我的本地环境,对团队的其他成员来说毫无用处)。
【解决方案2】:

我为您查看了git rebase -i HEAD~2 命令选项,但看起来这只会让您编辑提交消息,并且不允许您删除在该提交期间添加的文件。在这种情况下,您将需要回滚提交并一次重新应用它们。这将通过执行以下操作来完成:

重置您之前的提交并将其隐藏:

git reset --soft HEAD~1
git stash

然后重置之前的提交(带有额外文件的那个):

git reset --soft HEAD~1

重置该提交后,那些错误提交的文件仍将暂存以进行提交。使用以下命令将它们从即将到来的分阶段提交中删除:

git reset My/Path/File1.ps1
git reset My/Path/File2.ps1
git reset My/Path/File3.ps1

现在文件已从分阶段提交中删除,更新(或创建)一个 .gitignore 文件位于您的仓库的根目录中。在.gitignore 文件中添加以下行以忽略所有.ps1 文件:

*.ps1

或者,如果您不想忽略所有 .ps1 文件,您可以通过添加以下三行来明确指定要忽略的文件:

My/Path/File1.ps1
My/Path/File2.ps1
My/Path/File3.ps1

一旦您的 .gitignore 文件更新,请确保将其添加到您即将提交的提交中:

git add .gitignore

然后您可以完成您的提交,这一次无需担心 .ps1 文件会再次被意外提交。

要重新应用您隐藏的其他提交,请使用以下命令弹出您的隐藏并完成该提交:

git stash pop
git commit -m "relevant commit message"

上述步骤应该已经撤消、更正并使用 git 命令重新应用这些提交:git resetgit stashgit commit

如果你怕搞砸了,先创建一个分支来保存你之前的工作,在开始上述步骤之前执行这些命令:

git checkout -b [new branch name]
git checkout [previous branch name]

这应该将所有混乱的提交存储在旧分支中,以防你想回到它们。

【讨论】:

  • 谢谢。我不想删除任何文件。我最初的问题一定是措辞很差,因为你是第二个推荐这个的人。我要编辑我的问题。
  • 我回答的一个关键方面,我不相信它会从源代码控制中删除文件,它只会阻止您的本地更改(或任何其他工程师)提交/推送到您的团队的回购。如果您忽略将其添加到您的 .gitignore 文件的步骤...其余的将起作用,并允许稍后提交对这些文件的更改。
  • 这也不是我想要的(或不一定)。我可以在自己的分支上进行更改。我们可能必须对文件进行其他更改。但这里的重要问题是:如何取回以前版本的文件?我真的很惊讶这在 Git 中似乎非常困难。
  • 您是否已经将更改推送到您的remote?如果是这样.. 恢复更改的唯一方法是在 ps1 文件中检查具有正确值的提交,将这些更改复制到临时文件夹,然后再次检查该分支的 HEAD 并应用更改从该临时文件夹并将更改推送回远程。抱歉,我帮不上忙。
  • @TravelingFox 每个人都很难帮助您的原因是,将文件重置为包含此文件的较早提交您如何恢复它。现在,如果您所做的是第一次更改文件 添加它,则没有可返回的早期版本,因为它以前不受版本控制。但你没有告诉我们你是不是这么做的。
最近更新 更多