git 如何把单个文件回退到某一版本

git 如何把单个文件回退到某一版本

概要

应用场景:在进行一次完整的提交后,你可能有有这样的需求:需要将某个单文件A的内容回退或者替换为某个历史版本。
或者将某个提交C1记录下文件A替换成提交C3下记录下的文件A内容。

四条命令

下面涉及到的四条命令:

git restore #恢复命令
git reset #回退重置命令
git checkout #签出命令
git cherry-pick #单特色功能应用,挑拣樱桃~

这四条命令均可以实现文章开头提到的应用需求。下面详述具体操作和他们之间的区别。

git restore

下面以t1.txt为例,进行说明:

$cat t1.txt
Home Hello world
1
2
3
4
5
6
7
4-1
4-3

$git restore --source 88018 --worktree -- t1.txt
$ cat t1.txt
Home Hello world
1
2
3
4-1
4-2
$git status
On branch br-0
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   t1.txt

上面的脚本说明:
首先查看t1.txt里面的内容: cat t1.txt
然后通过restore命令恢复:
git restore --source 88018 --worktree – t1.txt
souce 指定要恢复的历史提交SHA256前5位,如本例的88018
worktree选项指定为工作目录恢复,亦即将本地工作目录内的t1.txt
内容全部替换。
如果只想替换暂存区的t1.txt,而不想替换工作目录的t1.txt的内容,可以使用–stage命令;或者可同时使用–stage --worktree选项对暂存区和工作目录进行恢复。

再通过cat t1.txt命令可以看到t1.txt里面的内容已经替换完成;
最后通过 git status查看现在工作区状态,t1.txt文件的状态为“未暂存、未提交”。

git reset

$ git reset 88018 -- t1.txt
Unstaged changes after reset:
M       t1.txt

$ cat t1.txt
Home Hello world
1
2
3
4
5
6
7
4-1
4-3

$ git restore -- t1.txt
$ cat t1.txt
Home Hello world
1
2
3
4-1
4-2
$ git status
On branch br-0
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   t1.txt

一般git reset命令本身并不能起到恢复单个某版本文件的作用,它需要配合git restore – filepath。
在git 官方说明文档中,点明如果使用git reset 命令回退某个文件,那么它只能暂存区被恢复。工作区的t1.txt不会被回退。

…These forms reset the index entries for all paths that match the <pathspec> to their state at <tree-ish>. (It does not affect the working tree or the current branch.)…

一种特殊情况下可以只通过git reset本身回退某个文件至某个版本。那就是某个历史版本(提交记录)下提交的变更只有t1.txt这个文件。
如下

git reset --hard 88018

git reset命令共有5种回退模式:

  • - -soft
  • - -mixed
  • - -hard
  • - -keep
  • - -merge

前面三种是常见的模式,下面着重说一下keep和merge;

  • - - keep 指在回退文件版本时,保留当前工作目录中t1.txt的状态,只将暂存区和仓库重置到所需的某个历史版本(即历史提交);但不是所有时候都可以这么做,当如下情况出现时,禁止使用该选项(使用该选项会失败报错):
    在当前目录下文件t1.txt有未提交的变更并且当前提交和所需重置的历史提交中t1.txt状态不一
  • - -merge 和keep类似,指在回退文件版本时,保留当前工作目录中t1.txt的状态,只将暂存区和仓库重置到所需的某个历史版本(即历史提交);但不是所有时候都可以这么做,当如下情况出现时,禁止使用该选项(使用该选项会失败报错):
    在当前目录下文件t1.txt有未提交的变更并且当前暂存区和所需重置的历史提交中t1.txt状态不一

在这里需要注意:一个文件,如t1.txt,的状态在重置前可能有三种状态,亦即它在工作目录、暂存区、仓库这三个地方的状态均不相同,在重置发生时,同样需要注意该文件在三个地方的状态变化。
其实上面5个重置选项一直在围绕着文件t1.txt在重置前后三个地方的状态。哪些需要重置,哪些需要保留。下面是Git官方给出的某文件在重置前后使用各选项策略的状态变化:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在使用这些选项时,请注意和checkout选项的区别

git checkout

git checkout --theirs 88018 -- t1.txt

使用theirs选项从88018签出文件t1.txt的内容到工作目录以及暂存区。
这里改变的是暂存区和工作区,当前提交不变(仓库中t1.txt内容保持原样)

git cherry-pick

git cherry-pick 88018

这里将提交88018中所有和当前提交的不同的变化重新应用于当前目录,并自动暂存和提交形成一个新的提交记录。
如果历史提交88018中只有t1.txt和当前提交不同,那么同样可以起到恢复t1.txt到历史版本的作用,只是在当前HEAD上又重新形成了一个新提交。
如果提交88018中不止t1.txt文件发生变化,那所有和当前目录下不同的提交都将发生变化。
注意:在应用该命令时,要求工作目录必须干净,否则禁止使用该命令

  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值