【问题标题】:git no longer able to rewrite historygit不再能够重写历史
【发布时间】:2018-03-20 23:28:11
【问题描述】:

我一直在使用如下命令:

git filter-branch --index-filter \
           'git ls-files -s | sed "s_subdir/__" |
                   GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
                           git update-index --index-info &&
            mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD

将目录树从子目录“subdir”移动到顶层。 为了在不同且成功的过滤树之后清理回购,我尝试使用:

git filter-branch --tag-name-filter cat -- --all
git filter-branch --commit-filter 'git_commit_non_empty_tree "$@"' HEAD
git reflog expire --all --expire=now
git gc --prune=now --aggressive      

这混合了来自附近的一些建议。 但是,执行此过滤器分支后不再起作用:

Rewrite 07436df7a2795910fb0b718d1a1b84e195cfabea (1/113) (0 seconds passed, remaining 0 predicted)    mv: cannot stat ‘somepathhere/.git-rewrite/t/../index.new’: No such file or directory
index filter failed: git ls-files -s | sed "_subdir/__" |
GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
git update-index --index-info &&
 mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"

我完全不清楚为什么会这样,或者我使用的哪个“巫毒”清理命令负责。显然,我的 git-fu 中缺少一些知识。有人可以建议那可能是什么吗?

【问题讨论】:

  • commit 07436df7a2795910fb0b718d1a1b84e195cfabea里面有write子目录吗?
  • 命令是将repo的内容从“subdir”移动到目录的根目录。如果这就是“写”子目录的意思,那么每次提交都必须存在根目录。我相信所有提交都存在子目录,并且我使用--prune-empty 重写了。但是 .git-rewrite 不存在,当然也不应该用于任何提交。
  • 其实我用了一个同音字;我的意思是“正确的”子目录。 subdir/ 是否存在于它提到的提交树中?如果你git checkout 07436df; ls,你会得到什么? (有一些方法可以查看提交的树,但我不记得它是什么,并且目前没有可用的 git
  • 我想你可能正在做一些事情。毕竟第一次提交不存在 subdir 。提交根本没有文件。我以为我已经删除了所有使用 git filter-branch --commit-filter 'git_commit_non_empty_tree "$@"' HEAD 的空提交,但该命令似乎没有触及它们。

标签: git


【解决方案1】:

重写失败,因为至少有一个提交,其中 'subdir' 不存在。 对我有用的修复方法是通过添加“; /bin/true

来更改过滤器以忽略错误
git filter-branch --index-filter \
           'git ls-files -s | sed "s_subdir/__" |
                   GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
                           git update-index --index-info &&
            mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"; /bin/true' HEAD

这似乎相当于 --index-filter--ignore-unmatch

我仍然不确定为什么之前没有删除空提交:

git filter-branch --prune-empty --tag-name-filter cat -- --all
git filter-branch --commit-filter 'git_commit_non_empty_tree "$@"' HEAD

但是有一个解决方案(来自question):

git filter-branch --parent-filter "sed 's/-p <the_commit>//'" HEAD

这会剪掉最初的提交,它只是一个没有文件的评论(作为早期重写的结果)。完成此操作后,可能不再需要“;/bin/true”技巧。

【讨论】:

    猜你喜欢
    • 2021-12-09
    • 1970-01-01
    • 2014-11-01
    • 2014-09-25
    • 1970-01-01
    • 2020-05-30
    • 2013-04-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多