吉特如何在提交链中回滚某些文件中的更改?

时间:2019-05-28 10:05:44

标签: git

我有一个包含三个文件的仓库:1.txt,2.txt和3.txt。我创建了一个分支“ new_branch”并进行了提交(我们将其称为A,B和C),这些提交中的每一个都包含来自我的仓库中几个文件的更改。然后我知道1.txt被错误地更新了。是否可以从提交A,B和C中删除在1.txt中所做的更改,但将更改保留在2.txt和3.txt中?

UPD。。我还想从提交历史记录中删除将其更改为1.txt的更改。结果是'git log -p'应该显示,在提交A,B和C中仅修改了2.txt和3.txt。

非常感谢。

4 个答案:

答案 0 :(得分:2)

假设您的修订树如下所示:

-- S <s.sha> -- A -- B -- C (HEAD)

您可以使用git filter-branch从对单个文件的提交A..C中删除更改。

git filter-branch --tree-filter 'git checkout <s.sha> -- 1.txt' HEAD~3..

这将:

  • 检出最后三个提交中的每一个,
  • 1.txt文件运行'git checkout',将其转到您想要的版本,
  • 将修改后的提交放回到树上。

这显然是在重写历史记录,因此,与推动重新设置基准点相同。

答案 1 :(得分:1)

您可以尝试在提交{em>之前提交1.txt时签出A,这是您开始进行不需要的更改的第一个提交:

git checkout abc123 -- 1.txt

这假定您的分支结构如下所示(提交S具有SHA-1哈希abc123):

S -- A -- B -- C

然后,只需添加更改并提交即可。

答案 2 :(得分:0)

git checkout <commit reference> <file>是您要寻找的。

> git init
Initialized empty Git repository in /Users/ody/temp/git-co/.git/
> touch 1 2 3
> echo foo > 1 > 2 > 3
> git add 1 2 3
> git commit -m "foo"
[master (root-commit) 470f4e8] foo
 3 files changed, 3 insertions(+)
 create mode 100644 1
 create mode 100644 2
 create mode 100644 3
> echo bar > 1 > 2 > 3
> git add 1 2 3
> git commit -m "bar"  
[master 916819d] bar
 3 files changed, 3 insertions(+), 3 deletions(-)
> git checkout :/foo 1
> cat 1
foo

注意:通过:/标记,您可以按提交名称的一部分而不是提交哈希值引用提交。

答案 3 :(得分:0)

这是另一种不太整洁的方法[尽管蒂姆提供的解决方案最适合这种情况]-

假设您的前三项提交分别是A,B,C,则可以执行git reset --soft HEAD~3。您所有已落实的更改都将出现在您的暂存区中。您可以取消暂存1.txt并提交其余文件。

这将导致历史更改,将提交A,B和C替换为新的提交D,该提交将具有A,B和C中的所有更改,但文件1.txt除外。