我对作为一组文件的一部分提交了几次的文件进行了一些更改,但现在希望将其更改重置/还原回以前的版本。
我已经做了一个git log和一个git diff来查找我需要的修订,但不知道如何将文件恢复到以前的状态。
- 恢复后,检查EDOCX1[1]时不要忘记EDOCX1[0]。链接
- 我在谷歌上搜索时发现了你的问题。但是在我阅读了解决方案之后,我检查了我的日志,发现我做了一些改动作为一个独立的提交,所以我为那个提交做了Git还原,其他的一切都保持在我想要的状态。不是一个解决方案,有时只是另一种方法。
假设您想要的提交的散列值是c5f567:
1
| git checkout c5f567 -- file1/to/restore file2/to/restore |
git checkout手册页提供了更多信息。
如果要在c5f567之前恢复提交,请附加~1(使用任何数字):
1
| git checkout c5f567~1 -- file1/to/restore file2/to/restore |
作为旁注,我一直对这个命令感到不舒服,因为它既用于普通的事情(在分支之间更改),也用于不寻常的、破坏性的事情(丢弃工作目录中的更改)。
- @暗影之手:有没有一种方法可以逆转这种情况,所以这就是后面的版本?
- @aliteralmind:不,不幸的是git历史快捷符号只能在历史上倒退。
- 如果要为abcde使用分支名称(例如develop),则需要git checkout develop -- file/to/restore(注意双破折号)
- @aliteralmind:事实上,是的,有一种方法可以做到这一点:"git log--reverse-1--eargtrev..master"然后使用适当的选项来获取git rev。--祖先路径将在两个提交之间"划一条线",-1将只显示一个版本,而--reverse将确保发出的第一个条目是最早的。
- 请确保签出仍然具有要查找的文件的修订哈希。如果它在修订版中被删除,请至少在该修订版之前转到哈希。
- 要自动化搜索文件历史记录和在一个git命令中签出适当的提交ID的整个过程,请使用git prevision。
- 如果要删除对此特定文件所做的更改,可以使用git checkout path/to/file。如果不指定哈希,则使用head。
- 我个人觉得打字比打字容易。
- 我们可以在提交ID之后传递以空格分隔的文件列表吗?
- @或者用@^代替HEAD^。
- 我认为这是目前最干净的解决方案:)
- 我也意识到你必须站在你推到的分支上,而不是从那里。
- 上面的命令对我有用。但是,auto-complete建议使用文件的大写版本,并且生成的"file1/to/restore与Git已知的任何文件都不匹配。"案例需要与Git在存储库中的内容匹配。
- 如何检查2个或更多文件?
- 我本来打算+1你,但很明显我至少在这里呆过一次:D一个非常有用的答案,也许我应该记住!
- 这个人从这个答案中获得的声誉!Git令人敬畏
- Windows用户注意:相对路径不够,我必须包括完整路径,例如/d/Repos/MyRepo/Folder1/Folder2/FileIWantToCheckout.json。
- 回答不正确,无法恢复。这只会更改文件,使其内容与您提供的提交内容完全相同,您必须再次提交才能实际实现此内容。
- 好的一个……完全按照说明工作
- 使用git checkout 5364aee~1 path/to/dir/*将文件的整个目录恢复到5364aee之前的版本。
- 有人能解释一下旁注吗?为什么在分支之间切换和丢弃工作目录中的更改之间存在差异?如果文件名匹配,切换分支是否放弃更改?
- @markboom:答案中显示的命令形式使用git checkout --来恢复特定的文件内容。当然,git checkout的另一个完全不同的用途是用于交换分支。我不清楚为什么有人选择对两个完全不同的东西使用相同的命令名。(不,切换分支永远不会丢弃更改,如果您尝试这样做,Git会抱怨并询问您希望如何处理将被覆盖的更改。)
可以使用diff命令快速查看对文件所做的更改:
1
| git diff <commit hash> <filename> |
然后,要将特定文件还原为该提交,请使用reset命令:
1
| git reset <commit hash> <filename> |
如果您有局部修改,可能需要使用--hard选项。
管理航点的一个好工作流程是使用标记在时间线上清晰地标记点。我不太明白你的最后一句话,但你可能想要的是把一个分支从前一个时间点分开。要执行此操作,请使用便捷的签出命令:
1 2
| git checkout <commit hash>
git checkout -b <new branch name> |
然后,当您准备合并这些更改时,可以将其重新设置为与主线相对应:
1 2 3 4
| git checkout <my branch>
git rebase master
git checkout master
git merge <my branch> |
- "‘出去checkout <承诺>散列有给定的命令,我们回到我的older版本的项目exactly这个方法有哪些搜索确定我是克里斯。
- "‘出去复位<承诺> <哈希filename >不改变RA的特异性的文件,我想变革。是,有一种方式来checkout的版本的文件,具体来说,不checkout对整个项目???????
- 对恢复的文件git checkout 挤压比我们更好的方法git reset
- 我想在早期版本的一个单一的文件,因为我有overwritten 150株与A点badly拷贝/粘贴。我们git checkout 挤压的方法。这不应该是公认的答案,恕我直言。git reset是诺特。
- ‘出去不硬重置期权并不修改工作拷贝的,这就是为什么它不有任何的影响。硬复位的原因的查找文件exactly AS在版本库中specified承诺,将必须与你的局部变化,如果任何国家。
- 不能使用git reset复位的单文件,你将得到的是错误fatal: Cannot do hard reset with paths
- 什么是条说:你不能git reset --hard 。。。。。。。这会有什么错误fatal: Cannot do hard reset with paths.莫提Strom说:使用git checkout
- "hawkeyeparker哦是的,我们看到的是。。。。。。。谢谢,summarizing方法。
您可以使用对git提交的任何引用,包括sha-1(如果这是最方便的话)。关键是命令看起来如下:
git checkout [commit-ref] -- [filename]
- 这个答案与接受的答案有什么区别?接受的答案与不接受的答案有什么区别?
- 在git中,文件列表前面的"--"告诉git接下来的所有参数都应解释为文件名,而不是分支名或其他任何参数。有时这是一个有用的消歧方法。
- "--"不仅是一个git约定,而且在*nix命令行的各个地方都可以找到它。rm -- -f(删除名为-f的文件)似乎是典型的例子。此处提供更多详细信息
- 正如@hawkeyeparker所说,rm命令使用getopt(3)解析其参数。getopt是解析命令参数的命令。gnu.org/software/libc/manual/html_节点/getopt.html
- @Hawkeyeparker你是说文件名是-f?!我想这是非常罕见的情况,对吧?
- @foxxtrot你说--应该被解释为文件,但是在看到下面的greg hewgill第二个答案后,我很困惑。他建议git checkout -- foo<-在他的例子中,foo是文件名吗?或者只是一些树状的东西?我是说你不能签出文件名!这毫无意义
- @亲爱的,是的,这就是我的意思,是的,可能一点也不常见。我在不同的地方看到过这个例子,也许只是为了让它有点难忘:众所周知,rm-f是可怕/危险的。但是,关键是,在*nix中,文件名可以以"-"开头,这会混淆各种命令行解释程序,当它们看到"-"时,这些解释程序会希望后面跟着一个命令选项。它可以是以"-"开头的任何文件;例如"-myspecialfile"。
- @霍克耶帕克谢谢尼克斯,你是说Unix,对吧?
- @亲爱的stackoverflow.com/questions/4715374/&hellip;
这将使foo重置为head。你也可以:
一次修订等。
- 我建议使用语法git checkout -- foo以避免任何错误,如果foo有任何特殊之处(如目录或名为-f的文件)。对于git,如果您不确定,请始终在所有文件和目录前面加上特殊参数--。
- Mikko评论的另一个注释是:--不是git命令,也不是git的特殊命令。它是一个内置的bash,表示命令选项的结束。您也可以将它与许多其他bash命令一起使用。
- @Matthaeus它也不特定于bash,也不特定于shell特性。它是在许多不同的命令中实现的约定(由getopt支持)。
为了恢复到最常需要的最后一个提交的版本,您可以使用这个更简单的命令。
1
| git checkout HEAD file/to/restore |
- 这个(git checkout head file/to/restore)和git reset——硬文件/to/restore有什么区别????
- 1)更容易记住更一般的方法2)输入文件名前无需按Enter键。
刚才我也有同样的问题,我发现这个答案很容易理解(commit-ref是您要返回日志中更改的sha值):
1
| git checkout [commit-ref] [filename] |
这将把旧版本放在您的工作目录中,您可以在那里提交它(如果需要)。
如果您知道需要返回多少提交,可以使用:
1
| git checkout master~5 image.png |
这假设您在master分支上,您想要的版本是5提交回。
我想我找到了……从http://www cs students.stanford.edu/~blynn/gitmagic/ch02.html
有时候,你只是想回到过去,忘记过去某个时刻的每一个变化,因为它们都是错误的。
开始:
$ git log
它向您显示最近提交的列表以及它们的sha1散列。
下一步,类型:
$ git reset --hard SHA1_HASH
将状态恢复到给定的提交,并永久地从记录中删除所有更新的提交。
- ‘出去不removes什么的。你的老commits仍然是有,但除非有一个分支尖端指指点点.他们,他们是不reachable anymore。。。。。。。NEA引用日志会杀了他们的表演,直到你清洁你的版本库与NEA的气相色谱测定法。
- "bombe:谢谢你的信息。我有检查出安老版本的文件。在阅读你的评论,我是能使用"gitref"的SHA1哈希查找的部分,和使用"checkout"to get back的最最近的版本。NEA其他用户可能发现这信息helpful。。。。。。。
- followed可能通过一个git push --force
- 如果在以上"NEA的复位,硬_ SHA1散列"的,你做一个"‘出去的状态",看见未被追踪的档案,你想摆脱它们的束缚。运行"‘出去清洁力."
- 如果你有uncommitted变化,你将松散的,如果他们做一个‘出去硬复位
- 我发现这条,这帮助我们得到通过这样的问题:blogs.gnome.org diegoe / / / / 2009年03 18 / & hellip;它seemed伟大的工作是非常相似到这个独特的答案。
- T这复位不全的档案吗?不是任何一个特定的文件?
- "bombe"‘出去不removes什么的。你的老commits仍然是有,但除非有一个分支尖端指指点点.他们,他们是不reachable anymore。"但是,commits状,这是pruned后几集时,即"没有什么‘出去removes"是untrue。。。。。。。
- "bombe:git reflog will still show them until you clean your repository with git-gc-错误的。引用日志是一个参考和引用的太commits将永远是removed用NEA的气相色谱测定法。如果你需要清洁他们的权利,现在,你要做的git reflog expire --expire-unreachable=now --all
- "nickvolynkin你的信息是错误的;git gc有时会commits remove,从引用日志。为人git-gc页说,"配置变量的gc.reflogExpire和gc.reflogExpireUnreachable集时代thresholds方法deletion从引用日志。older比定值的条目将被删除,当git gc是运行的。默认的值到90天和30天的方法reachable和unreachable commits。。。。。。。
这对我很有用:
1
| git checkout <commit hash> file |
然后提交更改:
当你说"回滚"时必须小心。如果您以前在commit$a中有一个文件版本,然后在两个单独的commit$b和$c中进行了两次更改(那么您看到的是文件的第三次迭代),如果您说"我想回滚到第一次",您真的是这么想的吗?
如果您想消除第二次和第三次迭代中的更改,那么非常简单:
然后提交结果。命令询问"我想从提交$A记录的状态中签出文件"。
另一方面,您的意思是消除第二次迭代(即commit$b)带来的更改,同时保留commit$c对文件所做的操作,您希望恢复$b
请注意,创建commit$b的人可能没有受到严格的约束,并且可能在同一个commit中进行了完全不相关的更改,并且此还原可能接触到文件以外的其他文件,因此您可能希望在执行此操作后仔细检查结果。
- 我这样做了,但是一个"git日志文件"会说我是在原始提交上的,head。似乎"Git结账"失败了。但是,git状态显示文件实际上已经更改,而"git diff--分阶段文件"将显示实际更改。此外,"git状态"也显示文件已更改。所以不要在这里使用"Git日志"来跟踪哪些文件发生了更改。
有趣的是,如果工作副本位于名为foo的目录中,"git checkout foo"将不起作用;但是,"git checkout head foo"和"git checkout./foo"都将:
1 2 3 4 5 6 7
| $ pwd
/Users/aaron/Documents/work/foo
$ git checkout foo
D foo
Already on"foo"
$ git checkout ./foo
$ git checkout HEAD foo |
以下是rebase的工作原理:
1 2 3 4
| git checkout <my branch>
git rebase master
git checkout master
git merge <my branch> |
假设你有
1 2
| ---o----o----o----o master
\---A----B <my branch> |
前两个命令…犯罪GIT校验Git钢筋主控形状
…查看要应用于master分支的更改分支。rebase命令接受的承诺(在master中没有发现),并将其重新应用到master的头上。换言之,中第一个提交的父级不再是master历史中的前一个提交,而是master的当前负责人。这两个命令相同:
1
| git rebase master <my branch> |
因为"base"和"modify"分支都是显式的,所以记住这个命令可能更容易。
. 最后的历史结果是:
1 2
| ---o----o----o----o master
\----A'----B' <my branch> |
最后两个命令…
1 2
| git checkout master
git merge <my branch> |
…进行快进合并,将所有更改应用到master上。如果不执行此步骤,则不会将rebase commit添加到master中。最终结果是:
1
| ---o----o----o----o----A'----B' master, <my branch> |
master和都参考B'。此外,从这一点上删除参考是安全的。
1
| git branch -d <my branch> |
目标文件的第一个重置头
1
| git reset HEAD path_to_file |
第二次签出该文件
1
| git checkout -- path_to_file |
- +1,虽然不确定复位头的意图。可能需要,也可能不需要。在我的情况下,我只想将一个特定的文件恢复到存储库中的版本(这样可以保持其余的本地更改不变)。只跑上面第二步就够了
git-aliases, awk and shell-functions to the rescue!
1
| git prevision <N> <filename> |
其中,是文件要回滚的文件修订数。例如,要签出单个文件x/y/z.c的前一个立即修订版,请运行
1
| git prevision -1 x/y/z.c |
Git预防如何工作?
将以下内容添加到您的EDOCX1[24]
1 2
| [alias]
prevision ="!f() { git checkout `git log --oneline $2 | awk -v commit="$1" 'FNR == -commit+1 {print $1}'` $2;} ;f" |
The command basically
-
performs a git log on the specified file and
-
picks the appropriate commit-id in the history of the file and
-
executes a git checkout to the commit-id for the specified file.
基本上,在这种情况下,所有的手动操作,包裹在一个美丽、高效的Git别名中-Git prevision
我必须在这里插入EasyGit,它是一个包装器,可以使Git对新手更容易接近,而不会混淆经验丰富的用户。它所做的一件事就是赋予git revert更多的含义。在这种情况下,您只需说:
eg revert foo/bar foo/baz
- 它应该是eg revert --in REVISON -- FILENAME。。。。。。。在--in是重要的。对Windows用户的选择有:开放式NEA猛击。echo %PATHexecute。第一路径应该是在你的用户目录的结局与bin。。。。。。。这是创建路径。这个商店有。它egname。不eg.txt。。。。。。。
如果要将文件还原为以前的提交(并且要还原的文件已提交),可以使用
1
| git checkout HEAD^1 path/to/file |
或
1
| git checkout HEAD~1 path/to/file |
然后准备好并提交"新"版本。
如果知道在合并的情况下提交可以有两个父级,则应该知道头^1是第一个父级,头~1是第二个父级。
如果树中只有一个父级,这两种方法都可以。
但是,请注意,git checkout ./foo和git checkout HEAD ./foo不是完全相同的事情;举例来说:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| $ echo A > foo
$ git add foo
$ git commit -m 'A' foo
Created commit a1f085f: A
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 foo
$ echo B >> foo
$ git add foo
$ echo C >> foo
$ cat foo
A
B
C
$ git checkout ./foo
$ cat foo
A
B
$ git checkout HEAD ./foo
$ cat foo
A |
(第二个add将文件放在索引中,但没有承诺的。)
git checkout ./foo是指从索引中恢复路径./foo;添加HEAD指示git将索引中的路径还原为HEAD修订。
这里有很多建议,大部分是沿着git checkout $revision -- $file的路线。一些模糊的选择:
1
| git show $revision:$file > $file |
而且,我经常使用这个来临时查看特定的版本:
1
| git show $revision:$file |
或
1
| git show $revision:$file | vim -R - |
(obs:$file如果是git show $revision:$file工作的相对路径,需要加上./前缀)
更奇怪的是:
1
| git archive $revision $file | tar -x0 > $file |
- 如果您不确定需要哪个提交版本,并且需要在不覆盖工作目录的情况下"浏览"一下,这是一个不错的选择。
对我来说,没有一个答复是非常清楚的,因此我想加上我的,这似乎是非常容易的。
我有一个承诺abc1,在它之后,我对一个文件file.txt做了几个(或一个修改)。
现在假设我在文件file.txt中弄错了什么,我想回到以前的承诺abc1。
1.git checkout file.txt:如果您不需要,这将删除本地更改。
2.git checkout abc1 file.txt这会把你的文件带到你想要的版本。
3.江户十一〔16〕号:这将使你复归。
git push:这将推动远程存储库上的所有内容
在第2步和第3步之间,您当然可以执行git status来了解发生了什么。通常你应该看到file.txt已经添加,这就是为什么不需要git add的原因。
- 好吧,我猜第一步。2。是互斥的:如果abc1是您最后一次提交,则不需要2。如果ABC1之后还有其他提交,您可以直接执行2。
- 很好的回答。这个应该是1
要转到文件的前一个提交版本,请获取提交编号,例如eb917a1然后
1
| git checkout eb917a1 YourFileName |
如果您只需要返回到上一个提交的版本
1 2
| git reset HEAD YourFileName
git checkout YourFileName |
这只会将您带到文件的最后一个提交状态
git checkout ref_commithash--文件路径
例如
1 2 3
| git checkout HEAD~5 -- foo.bar
or
git checkout 048ee28 -- foo.bar |
使用git log获取特定版本的散列密钥,然后使用git checkout 。
注意:不要忘记在最后一个哈希之前键入哈希。最后一个散列点指向您当前的位置(头),不更改任何内容。
这里的许多答案都声称使用了git reset ... 或git checkout ... ,但是这样做会使您在想要恢复的提交之后对所做的所有修改都变松。
如果您只想在单个文件上从一个提交中恢复更改,就像git revert只对一个文件(或者说提交文件的一个子集)那样,我建议使用git diff和git apply两种方法(表示您要恢复的提交的散列值):
1
| git diff <sha>^ <sha> path/to/file.ext | git apply -R |
基本上,它将首先生成与要还原的更改相对应的修补程序,然后反向应用修补程序以除去这些更改。
当然,如果恢复的行被和HEAD之间的任何承诺所修改(冲突),则不起作用。
显然,有人要么需要写一本关于git的易懂书,要么需要在文档中更好地解释git。面对同样的问题,我猜
1 2
| cd <working copy>
git revert master |
将撤消上一次似乎已完成的提交。
伊恩
如果在上一次提交中提交了错误的文件,请按照以下说明操作:
打开源代码树,更改为此提交
更改行,并发现提交错误的文件作为提交发送
您可以在提交中看到更改的列表。
选择它,然后单击…按钮右侧…单击"反向文件"
然后您可以在左下角的"文件状态"选项卡上看到它。然后单击取消页面:
打开Visual Studio代码并通过提交删除的文件还原
毕竟,您可以在源代码树中看到上次提交的结果。
将还原给定的提交。听起来你好像认为git revert只影响最近的承诺。
这并不能解决您的问题,如果您希望恢复特定文件中的更改,并且提交的更改超过了该文件。
您可以通过4个步骤完成:
用您要特别还原的文件还原整个提交-它将在您的分支上创建一个新的提交
软重置提交-删除提交并将更改移动到工作区
手动选取要还原的文件并提交它们
删除工作区中的所有其他文件
您需要在终端中键入的内容:
git revert
git reset HEAD~1
git add 和git commit -m 'reverting file'。
git checkout .
祝你好运
- 这不是还原所有更改吗?
- @arcee123是的,但随后的重置将撤消所有更改的恢复。问题是,git-revert只对整个回购进行操作,因此为了补偿,我们必须撤销所有其他操作。
- 我建议使用:1。git revert --no-commit 2号。git reset HEAD这节省了一个额外的浮动提交,并且只在工作目录中进行所有更改。
- @格雷格·休吉尔的回答更好,而且很准确。这个很烂,不应该用。
- 这正是真正还原特定文件所需要的。我需要撤消先前提交的几个文件的更改,这些文件已经被推送到远程存储库中。我还原、重置并提交结果:git revert _oldcommit_ --no-commitgit reset -- _unchanged1_ _unchanged2_ ...git commit -m"branch without changes to specific files"。新的分支提示反映了除还原文件之外的所有更改。
- @Danieltraca Greg Hewgill的回答并不好,如果你想恢复变化。可能存在更改文件其他部分的中间提交。NIR M的应答地址只恢复在一次提交中更改为特定文件的内容;HIS是恢复的更好的答案,我通过自己达到等效步骤来确认。
Git将文件还原为特定的提交
git checkout Last_Stable_commit_Number -- fileName
2.git将文件还原到特定分支
1
| git checkout branchName_Which_Has_stable_Commit fileName |
这是一个非常简单的步骤。将文件签出到我们想要的提交ID,这里有一个提交ID,然后只需git commit-amend,我们就完成了。
1 2
| # git checkout [cc] <file_name>
# git commit --amend |
这很方便。如果我们想在提交顶部将任何文件带到任何先前的提交ID,我们可以很容易地做到。
这是我的路。
a)在Android Studio中,打开文件。
b)git->show history,查找要恢复到的上一次提交。获取提交ID(即提交哈希)。
c)git checkout commit_id file_path。
如果您使用的是git扩展名,并且只希望还原为文件的父提交,则可以选择包含要还原的更改的提交,然后在"详细信息"窗格中选择"diff"选项卡,右键单击要还原的文件,然后将文件重置为"…",然后选择"a"(父文件)。