我有一个脚本,其中使用
git rebase
从当前分支中删除特定提交。
在一种情况下,它会删除看似随机的文件。 经过长时间的调试会话后,我成功地在
git rebase
执行合并期间追踪到重命名检测机制。
我所有禁用此机制的尝试都失败了。 我能做什么?
这是一个重现问题的 shell 脚本:
#!/bin/sh
mkdir test-repo
cd test-repo
git init
git config --local user.name nobody # just in case
git config --local user.email [email protected] # just in case
printf 'x\nx\n' >foo
git add .
git commit -m 'Added some files'
rm foo
printf 'y\nx\n' >bar # the contents of bar are slightly similar to foo
git add .
git commit -m 'The comit to discard'
printf 'z\nx\n' >bar
git add .
git commit -m 'The commit to keep'
git rebase --strategy-option=theirs --onto HEAD~2 HEAD~1
if [ ! -f bar ]
then
echo 'WHY!?'
fi
问题是 git 提交不是差异。它们是工作树中所有文件的完整规范。您的第二次提交和第三次提交都不包含
foo
。所以任何简单的变基都不会恢复foo
。当您压缩第二次提交(引入 bar 的提交)时,您所要做的就是从该分支上的提交历史记录中删除该提交。您的第三次提交仍将仅包含一个名为 bar
的文件,因此与第一次提交相比将隐式删除 foo
。
如果您想保留这两个文件,那么您将需要进行第一次变基,然后修改您的 HEAD 提交以使其包含 foo。您可以使用
git checkout
来简化此操作。例如:
git checkout HEAD~1 -- foo # ie. from the commit with message "Added some files"
git add foo
git commit --amend
如果您打算保留较大的提交历史记录而不是压缩所有内容,您可能希望在交互式变基中执行此操作。这样你就可以在第一次提交时恢复删除它的
foo
。然后,变基会将这一更改扩散到变基中的所有后续提交。