我需要重写一个分支,放弃对特定子文件夹(例如,其路径为path/to/folder)所做的所有更改,以及它在一系列修订(从指定的start修订版开始到以HEAD结束)之间的内容。接受start修订之前的更改。
我考虑过使用git-filter-branch来完成这个任务,但是不知道使用什么过滤器。我认为对每个提交的子文件夹使用“git-重置”可能有效,但是这个帖子让我怀疑这种方法是否有效。
问:我如何重写上面第一段所述的分支?
发布于 2015-12-03 15:24:14
最终起作用的是使用git-filter-branch与git rm的组合来删除添加在提交中的新文件,并使用“git签出”恢复状态。
git filter-branch -f --prune-empty --index-filter 'git rm -rfq -- path/to/subdir && git checkout -f <the-good-state-sha1> -- path/to/subdir' -- start..HEAD这里,start是开始提交,<the-good-state-sha1>是start父提交的哈希。注意到:需要按显示的两次指定path/to/subdir,一次在rm命令中,一次在checkout命令中。
发布于 2015-12-02 11:10:16
将git-过滤器-分支与--tree-filter一起使用,可能与--prune-empty一起使用。整个命令序列可以如下所示:
GOOD_STATE=<some-revision>
DIR_TO_PRESERVE="relative/path/to/directory"
BRANCH_TO_REWRITE=<branch-to-rewrite>
export GOOD_STATE DIR_TO_PRESERVE BRANCH_TO_REWRITE
git filter-branch --tree-filter \
'rm -rf "${DIR_TO_PRESERVE}" && git checkout -f ${GOOD_STATE} -- "${DIR_TO_PRESERVE}"' \
--prune-empty ${BRANCH_TO_REWRITE} --not ${GOOD_STATE}作为一种更快的替代方案,可以使用--index-filter。但是作为一个命令,您不应该使用git rm...,因为这将完全删除路径。相反,您应该使用git reset重置给定文件夹的索引。
git filter-branch --index-filter \
'git reset -q ${GOOD_STATE} -- "${DIR_TO_PRESERVE}"'' \
--prune-empty ${BRANCH_TO_REWRITE} --not ${GOOD_STATE}为了加快速度,人们可以暂时将存储库复制到更快的文件系统(我在Linux上使用了tmpfs,9007提交已经用索引过滤器在14分钟37秒内重写)。
https://stackoverflow.com/questions/34039274
复制相似问题