问题描述:
如何在特定的提交哈希(我通过 git log 和 git diff 确定)处将修改后的文件恢复到其先前的版本?
解决方案1:
一个优秀的自由职业者,应该有对需求敏感和精准需求捕获的能力,而huntsbot.com提供了这个机会
假设您想要的提交的哈希是 c5f567:
git checkout c5f567 -- file1/to/restore file2/to/restore
git checkout 手册页提供了更多信息。
如果您想恢复到 c5f567 之前的提交,请附加 ~1(其中 1 是您要返回的提交数,可以是任何值):
git checkout c5f567~1-- file1/to/restore file2/to/restore
作为旁注,我一直对这个命令感到不舒服,因为它既用于普通事物(在分支之间更改),也用于不寻常的破坏性事物(丢弃工作目录中的更改)。
还有一个新的 git restore 命令专门用于恢复已修改的工作副本文件。如果您的 git 足够新,您可以使用此命令,但文档附带警告:
此命令是实验性的。行为可能会改变。
@shadowhand:有没有办法扭转这种情况,所以它是紧随其后的版本?
@alliteralmind:不,不幸的是,Git 历史快捷方式符号只会在历史上倒退。
如果您要为 abcde 使用分支名称(例如 develop),您将需要 git checkout develop -- file/to/restore(注意双破折号)
@alliteralmind:实际上,是的,有一种方法可以做到:“git log --reverse -1 --ancestry-path yourgitrev..master”,然后使用适当的选项来获取 git rev。 --ancestry-path 将在两个提交之间“画一条线”,-1 将只显示一个版本,而 --reverse 将确保发出的第一个条目是最旧的条目。
就我个人而言,我发现 HEAD^ 比 HEAD~1 更容易输入 :)
解决方案2:
huntsbot.com高效搞钱,一站式跟进超10+任务平台外包需求
您可以使用 diff 命令快速查看对文件所做的更改:
git diff
然后要将特定文件还原为该提交,请使用 reset 命令:
git reset
如果您有本地修改,您可能需要使用 --hard 选项。
管理航点的一个很好的工作流程是使用标签在您的时间线中清晰地标记点。我不太明白你的最后一句话,但你可能想要的是从前一个时间点分出一个分支。为此,请使用方便的 checkout 命令:
git checkout
git checkout -b
然后,当您准备好合并这些更改时,您可以根据您的主线重新设置:
git checkout
git rebase master
git checkout master
git merge
'git checkout ' 命令让我恢复了旧版本的项目,这正是我正在寻找的项目 谢谢克里斯。
恢复文件 git checkout 对我来说比 git reset 效果更好
我想要单个文件的早期版本,因为我用错误选择的复制/粘贴覆盖了 150 行。 git checkout 为我工作。恕我直言,这不应该是公认的答案。 git reset 没有。
无法使用 git reset 重置单个文件,您将收到错误 fatal: Cannot do hard reset with paths
什么 slier 说:你不能git reset --hard 。这将与 fatal: Cannot do hard reset with paths. Motti Strom 所说的错误:使用 git checkout
解决方案3:
huntsbot.com提供全网独家一站式外包任务、远程工作、创意产品分享与订阅服务!
您可以使用对 git 提交的任何引用,如果最方便的话,包括 SHA-1。关键是命令看起来像这样:
git checkout [commit-ref] – [filename]
huntsbot.com – 程序员副业首选,一站式外包任务、远程工作、创意产品分享订阅平台。
这个有 -- 的答案与没有的已接受答案有什么区别?
在 git 中,文件列表前的“--”告诉 git 所有下一个参数都应该被解释为文件名,而不是分支名或其他任何东西。有时它是一个有用的消歧器。
'--' 不仅是一个 git 约定,而且是你在 *nix 命令行的不同位置找到的东西。 rm -- -f(删除一个名为 -f 的文件)似乎是典型的例子。 More detail here
只需添加@HawkeyeParker 所说的, rm 命令使用 getopt(3) 解析其参数。 getopt 是解析命令参数的命令。 gnu.org/software/libc/manual/html_node/Getopt.html
@Honey 是的,这就是我的意思,是的,可能根本不常见。我已经在不同的地方看到过这个例子,也许只是为了让它有点令人难忘: rm -f 众所周知是可怕/危险的。但是,关键是,在 *nix 中,文件名可以以“-”开头,这会使各种命令行解释器感到困惑,当它们看到“-”时,会期望后面跟着一个命令选项。它可以是任何以'-'开头的文件;例如,“-mySpecialFile”。
解决方案4:
huntsbot.com洞察每一个产品背后的需求与收益,从而捕获灵感
git checkout -- foo
这会将 foo 重置为 HEAD。你也可以:
git checkout HEAD^ foo
一次修订,等等。
如果 foo 有任何特殊(例如目录或名为 -f 的文件),我建议使用语法 git checkout -- foo 以避免任何错误。对于 git,如果您不确定,请始终在所有文件和目录前加上特殊参数 --。
Mikko 评论的附加说明:-- 不是 git 命令,对 git 来说并不特殊。它是一个内置的 bash,用于表示命令选项的结束。您也可以将它与许多其他 bash 命令一起使用。
@matthaeus 它也既不是特定于 bash 也不是 shell 功能。这是在许多不同命令中实现的约定(并由 getopt 支持)。
不,-- 不是 bash 中的内置特殊词。但它是许多命令行解析器支持的通用约定,并被许多 CLI 使用,包括 git。
解决方案5:
huntsbot.com精选全球7大洲远程工作机会,涵盖各领域,帮助想要远程工作的数字游民们能更精准、更高效的找到对方。
并且要恢复到最常需要的最后提交的版本,您可以使用这个更简单的命令。
git checkout HEAD file/to/restore
这(git checkout HEAD file/to/restore)和 git reset --hard file/to/restore 有什么区别???
1)更容易记住更通用的方式 2)不用担心在输入文件名之前按 Enter
这是对“真实”问题的更有效答案。
解决方案6:
huntsbot.com精选全球7大洲远程工作机会,涵盖各领域,帮助想要远程工作的数字游民们能更精准、更高效的找到对方。
我刚才遇到了同样的问题,我发现 this answer 最容易理解(commit-ref 是您要返回的日志中更改的 SHA 值):
git checkout [commit-ref][filename]
这会将旧版本放在您的工作目录中,如果需要,您可以从那里提交它。
解决方案7:
huntsbot.com聚合了超过10+全球外包任务平台的外包需求,寻找外包任务与机会变的简单与高效。
从 git v2.23.0 开始,有一个新的 git restore 方法应该假设 git checkout 负责的部分内容(即使接受的答案也提到 git checkout 非常令人困惑)。请参阅 github blog 上的变化亮点。
此命令的默认行为是使用来自 source 参数的内容(在您的情况下将是提交哈希)恢复工作树的状态。
因此,根据 Greg Hewgill 的回答(假设提交哈希为 c5f567),命令将如下所示:
git restore --source=c5f567 file1/to/restore file2/to/restore
或者如果你想恢复到 c5f567 之前的一次提交的内容:
git restore --source=c5f567~1 file1/to/restore file2/to/restore
我想这是一种死线,但这是正确的“现代”答案。
这是截至 2021 年的最佳答案。
解决方案8:
huntsbot.com聚合了超过10+全球外包任务平台的外包需求,寻找外包任务与机会变的简单与高效。
如果您知道需要返回多少次提交,您可以使用:
git checkout master~5 image.png
这假设您在 master 分支上,并且您想要的版本是 5 次提交。
解决方案9:
HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com
我想我找到了…来自 http://www-cs-students.stanford.edu/~blynn/gitmagic/ch02.html
有时你只想回到过去,忘记过去的每一个变化,因为它们都是错误的。
从…开始:
$ git log
它向您显示了最近提交的列表,以及它们的 SHA1 哈希值。
接下来,键入:
$ git reset --hard SHA1_HASH
将状态恢复到给定的提交并从记录中永久删除所有较新的提交。
Git 从不删除任何东西。您的旧提交仍然存在,但除非有指向它们的分支提示,否则它们不再可访问。 git reflog 仍然会显示它们,直到你用 git-gc 清理你的存储库。
@Bombe:感谢您提供的信息。我检查了一个旧版本的文件。阅读您的评论后,我能够使用“gitref”查找部分 SHA1 哈希,并使用“checkout”返回到最新版本。其他 git 用户可能会发现此信息很有帮助。
可能后跟一个 git push --force
如果您有未提交的更改,如果执行 git reset --hard,您将丢失它们
@Bombe - “Git 从不删除任何东西。你的旧提交仍然存在,但除非有指向它们的分支提示,否则它们不再可访问。” - 但是像这样的提交会在一段时间后被修剪,所以“Git 从不删除任何东西”是不真实的。
解决方案10:
huntsbot.com高效搞钱,一站式跟进超10+任务平台外包需求
这对我有用:
git checkout file
然后提交更改:
git commit -a
解决方案11:
打造属于自己的副业,开启自由职业之旅,从huntsbot.com开始!
当你说“回滚”时,你必须小心。如果您曾经在提交 $A 中有一个文件版本,然后在两个单独的提交 $B 和 $C 中进行了两次更改(所以您看到的是文件的第三次迭代),如果您说“我想回滚到第一个”,你真的是这个意思吗?
如果你想摆脱第二次和第三次迭代的变化,这很简单:
$ git checkout $A file
然后你提交结果。该命令询问“我想从提交 $A 记录的状态中签出文件”。
另一方面,您的意思是摆脱第二次迭代(即提交 $B)带来的更改,同时保留提交 $C 对文件所做的更改,您希望恢复 $B
$ git revert $B
请注意,创建提交 $B 的人可能不是很自律,并且可能在同一次提交中提交了完全不相关的更改,并且此还原可能会触及文件以外的文件,而不是您看到有问题的更改,因此您可能需要在执行后仔细检查结果所以。
我这样做了,但随后一个“git 日志文件”会说我在原始提交上,HEAD。似乎“git checkout”失败了。但是,git status 显示该文件实际上已更改,并且“git diff --staged 文件”将显示实际更改。此外,“git status”显示文件也已更改。所以不要在这里使用“git log”来跟踪哪些文件发生了变化。
@FrederickOllinger - 这种行为是有道理的,因为 git log 显示 commits,而您还没有 commit 更改(还原)。如果您在恢复后执行 git commit,则 git log 将显示更改。
原文链接:https://www.huntsbot.com/qa/oD2w/how-do-i-reset-or-revert-a-file-to-a-specific-revision?lang=zh_CN
与HuntsBot一起,探索全球自由职业机会–huntsbot.com
版权归原作者 HuntsBot 所有, 如有侵权,请联系我们删除。