我有一个包含三个文件的仓库: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。
非常感谢。
答案 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>
是您要寻找的。 p>
> 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除外。