【问题标题】:How to rewrite a branch, discarding changes to a subfolder如何重写分支,丢弃对子文件夹的更改
【发布时间】:2015-12-02 09:35:43
【问题描述】:

我需要重写一个分支,丢弃对特定子文件夹(例如,其路径为 path/to/folder)及其在从指定 start 修订开始到 HEAD 结束的修订范围之间的所有更改。接受start 修订版之前的更改。

我考虑过使用git-filter-branch 来执行此操作,但不知道要使用什么过滤器。我认为在每次提交的子文件夹中使用 'git-reset' 可能会起作用,但是这个 post 让我质疑这种方法是否有效。

问题:如何重写上面第一段中指定的分支?

【问题讨论】:

  • 请举个例子好吗?
  • 据我了解docs 你应该对git filter-branch --index-filter 'git rm --cached --ignore-unmatch path/to/folder' commit..HEAD 很好
  • 这将完全删除路径/到/文件夹

标签: git git-filter-branch git-reset


【解决方案1】:

git-filter-branch--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,并且已使用 --index-filter 在 14 分 37 秒内重写了 9007 个提交)。

【讨论】:

  • 嗯 - 我尝试在一个简单的测试 repo 上使用 --index-filter 和相同的命令,它似乎工作。然而,在具有数千次提交的实际回购中,它没有。您能否提供一个完整的命令行以与 --index-filter 一起使用?此外,对正在发生的事情进行一些解释会很棒。我不太明白它是怎么做的。
【解决方案2】:

最终奏效的是使用git-filter-branchgit rm 的组合来删除提交中添加的新文件,并使用“git checkout”来恢复状态。

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 是起始提交,&lt;the-good-state-sha1&gt;start 父提交的哈希值。 注意path/to/subdir 需要指定两次,如图所示,一次在rm 命令中,一次在checkout 命令中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-07
    • 2011-06-17
    • 2021-09-20
    • 2012-10-27
    • 2014-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多