git - 特定文件的 Git 还原/签出会触及它们,但保持内容不变
问题描述
我的同事前段时间添加了一些 .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 个文件。当然,必须有一种方法可以说“将这些文件改回我不小心提交它们之前的状态,无论它们最后一次更新是什么时候”。
谢谢。
解决方案
我为您查看了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 reset
、git stash
和git commit
如果您害怕搞砸,请先创建一个分支以保存您之前的工作,方法是在开始上述步骤之前执行这些命令:
git checkout -b [new branch name]
git checkout [previous branch name]
这应该将所有混乱的提交存储在旧分支中,以防你想回到它们。