使用Git将特定文件重置或还原到特定版本?

Hates_ 4255 git version-control git-checkout

我已经对作为一组文件的一部分提交了几次的文件进行了一些更改,但现在想要将其上的更改重置/还原到以前的版本.

我已经做了git log一个git diff找到我需要的修订版,但是根本不知道如何将文件恢复到以前的状态.

Greg Hewgill.. 5753

假设您想要的提交哈希是c5f567:

git checkout c5f567 -- file1/to/restore file2/to/restore

git的结帐手册页提供了更多的信息.

如果你想恢复之前的提交c5f567,追加~1(使用任何数字):

git checkout c5f567~1 -- file1/to/restore file2/to/restore

作为旁注,我总是对这个命令感到不舒服,因为它用于普通事物(在分支之间切换)和不寻常的破坏性事物(丢弃工作目录中的变化).

  • 如果你要使用*abcde*的分支名称(例如`develop`),你需要`git checkout develop - file/to/restore`(注意双破折号) (41认同)
  • @aliteralmind:不,不幸的是Git历史快捷方式符号只在历史上倒退了. (15认同)
  • @shadowhand:有没有办法扭转这种局面,所以它就是后来的版本? (11认同)
  • @aliteralmind:实际上,是的,有办法做到这一点:"git log --reverse -1 --ancestry-path yourgitrev..master"然后使用适当的选项来获得git rev.--ancestry-path将在两个提交之间"绘制一条线",-1将显示一个版本, - 反向将确保发出的第一个条目是最旧的一个. (7认同)
  • 就个人而言,我发现HEAD ^比HEAD更容易打字~1 :) (6认同)
  • 如果您要删除对此特定文件的更改,可以使用`git checkout path / to / file`。如果不指定哈希,则使用HEAD。 (2认同)

Chris Lloyd.. 585

您可以使用diff命令快速查看对文件所做的更改:

git diff <commit hash> <filename>

然后,要将特定文件还原到该提交,请使用reset命令:

git reset <commit hash> <filename>

--hard如果您进行了本地修改,则可能需要使用该选项.

管理航点的良好工作流程是使用标签在时间轴中清晰地标记点.我不太明白你的最后一句话,但你可能想要的是从前一个时间点分支出一个分支.为此,请使用方便的checkout命令:

git checkout <commit hash>
git checkout -b <new branch name>

然后,当您准备合并这些更改时,可以针对主线对其进行重新绑定:

git checkout <my branch>
git rebase master
git checkout master
git merge <my branch>

  • 要恢复文件`git checkout <commit hash> <filename>`对我来说比`git reset`更好 (44认同)
  • 不能使用`git reset`来重置单个文件,你会得到一个错误`致命:不能用路径进行硬重置 (20认同)
  • 什么slier说:你不能`git reset --hard <commit hash> <filename>`.这将导致`fatal:无法使用路径进行硬重置.Mitti Strom说:使用`git checkout <commit hash> <filename> (12认同)
  • 'git checkout <commit hash>'命令让我回复了我正在寻找的旧版本的项目,我正在寻找感谢Chris. (6认同)
  • 我想要一个单个文件的早期版本,因为我已经用一个选择错误的复制/粘贴覆盖了150行.`git checkout <commit hash> <filename>`为我工作.这不应该是公认的答案,恕我直言.`git reset`没有. (3认同)
  • 'git reset <commit hash> <filename>'没有更改我想要更改的特定文件.有没有办法检查文件的版本,特别是,不检查整个项目? (2认同)

foxxtrot.. 351

你可以使用任何对git commit的引用,包括SHA-1,如果这是最方便的.关键是命令看起来像这样:

git checkout [commit-ref] -- [filename]

  • 在git中,文件列表前面的' - '告诉git所有下一个参数都应该被解释为文件名,而不是分支名称或其他任何东西.有时它是一个有用的消歧器. (73认同)
  • ' - '不仅是一个git约定,而是你在*nix命令行中的各个地方找到的东西.`rm - -f`(删除一个名为`-f`的文件)似乎是一个典型的例子.[更多细节](http://stackoverflow.com/a/1192194/99717) (48认同)
  • 这个答案有什么区别,哪个有`--`,而被接受的答案有没有? (20认同)
  • 只需添加@HawkeyeParker所说的,`rm`命令使用getopt(3)来解析其参数.`getopt`是解析命令参数的命令.http://www.gnu.org/software/libc/manual/html_node/Getopt.html (7认同)
  • @Honey是的,这就是我的意思,是的,可能根本不常见.我在不同的地方看过这个例子,也许只是让它变得难忘:rm -f众所周知是可怕的/危险的.但是,关键是,在*nix中,文件名_can_以' - '开头,这会混淆各种命令行解释器,当他们看到' - '时,期望跟随一个命令选项.它可以是以' - '开头的任何文件; 例如," - mySpecialFile". (2认同)

Greg Hewgill.. 271

git checkout -- foo

这将重置foo为HEAD.你也可以:

git checkout HEAD^ foo

一次修改,等等

  • 我建议使用语法`git checkout - foo`以避免任何错误,如果`foo`是特殊的(如目录或名为`-f`的文件).使用git,如果您不确定,请始终使用特殊参数` - `作为所有文件和目录的前缀. (11认同)
  • @matthaeus它既不是特定于bash也不是shell特征.它是在许多不同命令中实现的约定(并由getopt支持). (11认同)
  • Mikko评论的另一个注释:` - `不是git命令,对git来说并不特别.它是一个内置的bash,用于表示命令选项的结束.您也可以将它与许多其他bash命令一起使用. (7认同)

CDR.. 121

要恢复到最常需要的最后提交的版本,您可以使用这个更简单的命令.

git checkout HEAD file/to/restore

  • 这个(git checkout HEAD文件/ to/restore)和git reset - 硬件文件/ to/restore之间的区别是什么? (2认同)
  • 1)更容易记住更通用的方式2)输入文件名前无需担心按Enter (2认同)

bbrown.. 104

我刚才遇到了同样的问题,我发现这个答案最容易理解(commit-ref是你想要回到日志中的变化的SHA值):

git checkout [commit-ref] [filename]

这会将旧版本放在您的工作目录中,如果您愿意,可以从那里提交.


Ron DeVera.. 91

如果您知道需要返回的提交数量,则可以使用:

git checkout master~5 image.png

这假设你在master分支机构,你想要的版本是5提交回来.


jdee.. 80

我想我已经找到了....来自http://www-cs-students.stanford.edu/~blynn/gitmagic/ch02.html

有时候你只想回去忘记每一次过去的变化,因为他们都错了.

从...开始:

$ git log

它显示了最近提交的列表及其SHA1哈希值.

接下来,键入:

$ git reset --hard SHA1_HASH

将状态恢复到给定的提交并永久删除记录中的所有新提交.

  • Git从不删除任何东西.你的旧提交仍在那里,但除非有一个分支提示指向它们,否则它们将无法再访问.在您使用git-gc清理存储库之前,git reflog仍会显示它们. (24认同)
  • @Bombe - "Git永远不会删除任何东西.你的旧提交仍然存在,但除非有一个分支尖端指向它们,否则它们不再可用." - 但这样的提交会在一段时间后被修剪,所以"Git永远不会删除任何东西"是不真实的. (5认同)
  • 可能接着是`git push --force` (4认同)
  • 如果您有未提交的更改,**如果执行git reset,则会丢失** (4认同)

v2k.. 61

这对我有用:

git checkout <commit hash> file

然后提交更改:

git commit -a


小智.. 54

当你说"回滚"时你必须要小心.如果您曾经在提交$ A中有一个版本的文件,然后在两个单独的提交中进行了两次更改$ B和$ C(所以你看到的是文件的第三次迭代),如果你说"我想回到第一个",你真的是这个意思吗?

如果你想要摆脱第二次和第三次迭代的变化,那很简单:

$ git checkout $A file

然后你提交结果.该命令询问"我想从提交$ A记录的状态检出文件".

另一方面,你的意思是摆脱引入的第二次迭代(即提交$ B)的变化,同时保持$ C对文件做了什么,你想要还原$ B

$ git revert $B

请注意,创建提交$ B的人可能不是非常自律,并且可能在同一次提交中提交了完全无关的更改,并且此恢复可能会触及您看到有违规更改的文件以外的文件,因此您可能需要在执行后仔细检查结果所以.


Aaron Maenpa.. 36

有趣的是,如果工作副本位于名为foo的目录中,'git checkout foo'将无法工作; 然而,'git checkout HEAD foo'和'git checkout ./foo'都将:

$ pwd
/Users/aaron/Documents/work/foo
$ git checkout foo
D   foo
Already on "foo"
$ git checkout ./foo
$ git checkout HEAD foo

  • 或者`git checkout - foo` (26认同)

cmcginty.. 32

这是如何rebase工作:

git checkout <my branch>
git rebase master
git checkout master
git merge <my branch>

假设你有

---o----o----o----o  master
    \---A----B       <my branch>

前两个命令...提交git checkout git rebase master

...查看要应用于分支的更改master分支.该rebase命令接受来自<my branch>(未找到master)的提交并将它们重新应用到头部master.换句话说,第一次提交的父级<my branch>不再是master历史记录中的先前提交,而是当前的提交master.这两个命令与:

git rebase master <my branch>

记住此命令可能更容易,因为"基本"和"修改"分支都是显式的.

.最终的历史结果是:

---o----o----o----o   master
                   \----A'----B'  <my branch>

最后两个命令......

git checkout master
git merge <my branch>

...执行快进合并以应用所有<my branch>更改master.如果没有此步骤,则不会添加rebase提交master.最终结果是:

---o----o----o----o----A'----B'  master, <my branch>

master并且<my branch>都参考B'.此外,从这一点来看,删除<my branch>引用是安全的.

git branch -d <my branch>


Gulshan Maur.. 23

首先重置目标文件头

git reset HEAD path_to_file

第二个结帐那个文件

git checkout -- path_to_file

  • +1,虽然不确定重置HEAD的意图.它可能需要也可能不需要.在我的情况下,我只想将一个特定的文件恢复到存储库中的版本(这保持了剩余的本地更改.只需运行上面的第二步就足够了 (4认同)

TheCodeArtis.. 22

救援的git-aliases,awk和shell-functions!

git prevision <N> <filename>

其中<N>是要回滚文件的文件的修订数<filename>.
例如,要x/y/z.c运行,请检查单个文件的前一个修订版本

git prevision -1 x/y/z.c

git prevision如何运作?

将以下内容添加到您的 gitconfig

[alias]
        prevision = "!f() { git checkout `git log --oneline $2 |  awk -v commit="$1" 'FNR == -commit+1 {print $1}'` $2;} ;f"

命令基本上

  • git log在指定的文件上 执行a
  • 在文件的历史记录中选择适当的commit-id
  • 执行git checkout指定文件的commit-id.

从本质上讲,所有人都会在这种情况下手动完成,
包含在一个美丽,高效的git-alias中 - git-prevision


Aristotle Pa.. 20

我必须在这里插入EasyGit,这是一个包装器,使新手更容易接近git而不会混淆经验丰富的用户.它所做的一件事就是赋予git revert更多的意义.在这种情况下,您只需说:

eg revert foo/bar foo/baz


小智.. 20

如果您要将文件还原为先前的提交(以及要还原已提交的文件),则可以使用

git checkout HEAD^1 path/to/file

要么

git checkout HEAD~1 path/to/file

然后只是暂存并提交"新"版本.

知道在合并的情况下提交可以有两个父项,你应该知道HEAD ^ 1是第一个父级,HEAD~1是第二个父级.

如果树中只有一个父项,则两者都可以工作.


Damien Diede.. 18

但是请注意,这git checkout ./foogit checkout HEAD ./foo 不能确切同样的事情; 一个很好的例子:

$ 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在执行此操作之前将索引中的路径还原为其 修订版.


Peter V. Mør.. 18

这里有很多建议,大多数都是这样的git checkout $revision -- $file.一些不起眼的替代方案:

git show $revision:$file > $file

而且,我经常使用它来暂时查看特定版本:

git show $revision:$file

要么

git show $revision:$file | vim -R -

(OBS:如果它是工作的相对路径$file,./则需要加上前缀git show $revision:$file)

更奇怪的是:

git archive $revision $file | tar -x0 > $file


kalmanIsAGam.. 14

对我来说,没有一个回复看起来很清楚,因此我想补充我看起来非常容易.

我有一个提交abc1,之后我对文件做了几次(或一次修改)file.txt.

现在说我弄乱了文件中的某些东西file.txt,我想回到之前的提交abc1.

1 git checkout file.txt.:如果您不需要,这将删除本地更改

2 . git checkout abc1 file.txt:这会将您的文件带到您想要的版本

3 . git commit -m "Restored file.txt to version abc1":这将使你的回归.

  1. git push :这将推送远程存储库上的所有内容

当然,在第2步和第3步之间,您可以git status了解正在发生的事情.通常你应该看到file.txt已经添加的,这就是为什么不需要a git add.

  • 好吧,我猜第1步和第2步是相互排斥的:如果abc1是你的最后一次提交,则不需要2.如果在abc1之后还有其他提交,你可以直接执行2. (2认同)
  • 很好的答案.这应该是#1 (2认同)

shah1988.. 11

要转到文件的先前提交版本,请获取提交编号,然后输入eb917a1

git checkout eb917a1 YourFileName

如果您只需要返回上一个提交的版本

git reset HEAD YourFileName
git checkout YourFileName

这将简单地将您带到文件的最后一个提交状态


Amos Folarin.. 10

git checkout ref | commitHash - filePath

例如

git checkout HEAD~5 -- foo.bar
or 
git checkout 048ee28 -- foo.bar


Vince.. 9

这里的许多答案声称使用git reset ... <file>或者git checkout ... <file>通过这样做,你将在<file>你想要恢复的提交之后松掉所有提交的修改.

如果你只想恢复单个文件上的一次提交的更改,就像git revert只做一个文件(或者说是提交文件的一个子集)一样,我建议使用两者git diff并且git apply像那样(使用<sha>=的哈希值)提交你想要还原):

git diff <sha>^ <sha> path/to/file.ext | git apply -R

基本上,它将首先生成与您要还原的更改相对应的修补程序,然后反向应用修补程序以删除这些更改.

当然,如果通过<sha1>HEAD(冲突)之间的任何提交修改了恢复的行,它将不起作用.

  • 就是这个!应该标记为最佳答案 (2认同)

小智.. 9

  1. git将文件还原为特定提交

git checkout Last_Stable_commit_Number-文件名

2. Git将文件还原到特定分支

git checkout branchName_Which_Has_stable_Commit fileName


小智.. 8

使用git log以获得特定版本的哈希键,然后使用git checkout <hashkey>

注意:不要忘记在最后一个之前键入哈希.最后一个哈希点指向您当前的位置(HEAD)并且不做任何更改.


小智.. 7

显然有人需要在git上写一本可理解的书,或者需要在文档中更好地解释git.面对同样的问题,我猜对了

cd <working copy>
git revert master

会撤消似乎做的最后一次提交.

伊恩


mjarosie.. 7

从git v2.23.0开始,有一个新的git restore方法,该方法应该假定是其中的一部分git checkout(即使已接受的答案git checkout也很令人困惑)。在github博客上查看更改的要点。

此命令的默认行为是使用来自source参数的内容(在您的情况下为提交哈希)恢复工作树的状态。

因此,根据Greg Hewgill的答案(假设commit hash为c5f567),该命令将如下所示:

git restore --source=c5f567 file1/to/restore file2/to/restore

或者,如果您想还原到c5f567之前的一次提交的内容,请执行以下操作:

git restore --source=c5f567~1 file1/to/restore file2/to/restore


小智.. 6

您可以通过4个步骤进行操作:

  1. 使用您要专门还原的文件还原整个提交-它将在您的分支上创建一个新的提交
  2. 提交的软复位-删除提交并将更改移动到工作区
  3. 手动选择文件以还原并提交
  4. 将所有其他文件放到工作区中

您需要在终端中输入什么

  1. git revert <commit_hash>
  2. git reset HEAD~1
  3. git add <file_i_want_to_revert> && git commit -m 'reverting file'
  4. git checkout .

祝好运

  • 我建议使用:1.`git revert --no-commit &lt;commit_hash&gt;`2.`git reset HEAD`这样可以节省额外的提交,并且仅在您的工作目录中进行所有更改。 (2认同)

saber tabata.. 5

如果您在上次提交中提交了错误的文件,请遵循以下说明:

  1. 开源树,更改为此提交

开源树

  1. 更改行并找到错误文件作为提交发送的提交

在此输入图像描述

  1. 您可以在该提交中看到更改列表 源树中的文件列表
  2. 选择它,然后单击右侧的...按钮...单击反向文件
  3. 然后你可以在左下角的文件状态选项卡上看到它,然后点击unstage:

文件状态选项卡

  1. 打开您的visual studio代码并通过提交已删除的文件来恢复
  2. 在它们之后,您可以在源树中的最后一次提交中看到结果

在此输入图像描述


Abhishek Dwi.. 5

这是非常简单的步骤。签出文件到我们想要的提交ID,这里是一个提交ID,然后是git commit修改,我们就完成了。

# git checkout <previous commit_id> <file_name>
# git commit --amend

这非常方便。如果我们想将任何文件带到提交顶部的任何先前的提交ID,我们可以轻松做到。


归档时间:

查看次数:

1794799 次

最近记录:

11 月,2 周 前