代码之家  ›  专栏  ›  技术社区  ›  Idan K

如何删除过滤分支后的旧提交?

git
  •  4
  • Idan K  · 技术社区  · 14 年前

    我用过滤嘴 fix an incorrect email address 但现在所有的分支都是MIA(除了master)。

    git graph 在之前显示 filter-branch :

    *   d93c7ee (HEAD, master) Merge branch 'f1'
    |\  
    | * 08e7463 (f1) adding b
    |/  
    * 7c7bd91 adding a
    

    我发出了这个过滤器分支命令:

    git filter-branch --env-filter 'export GIT_AUTHOR_EMAIL="fixed-email";
                                    GIT_AUTHOR_NAME="fixed-author"'
    

    得到这个:

    *   770262a (HEAD, master) Merge branch 'f1'
    |\  
    | * 0f58ab5 adding b
    |/  
    * fb012a9 adding a
    *   d93c7ee (refs/original/refs/heads/master) Merge branch 'f1'
    |\  
    | * 08e7463 (f1) adding b
    |/  
    * 7c7bd91 adding a
    

    1) f1 分支未移动到0f58ab5。

    我在另一个问题上看到有人建议:

    rm -rf .git/refs/original/
    git reflog expire --expire=now --all
    git gc --aggressive --prune=now
    

    但没什么帮助,我后来得到的是:

    *   770262a (HEAD, master) Merge branch 'f1'
    |\  
    | * 0f58ab5 adding b
    |/  
    * fb012a9 adding a
    * 08e7463 (f1) adding b
    * 7c7bd91 adding a
    

    编辑:按照VonC的建议生成以下图表:

    *   211632d (HEAD, master) Merge branch 'f1'
    |\  
    | * bda7577 (f1) adding b
    |/  
    * 70c7b34 adding a
    *   3182b33 (refs/original/refs/heads/master) Merge branch 'f1'
    |\  
    | * 8b81c21 (refs/original/refs/heads/f1) adding b
    |/  
    * 4c07dc9 adding a
    

    这解决了问题1,现在我只需要找到一个方法来摆脱旧的承诺,我该如何做到这一点?

    3 回复  |  直到 7 年前
        1
  •  6
  •   tgf    8 年前

    你能用' -- --all “最后,比如:

    git filter-branch --env-filter 'export GIT_AUTHOR_EMAIL="fixed-email";
                                           GIT_AUTHOR_NAME="fixed-author"' -- --all
    

    注:

    • 这个 -- 将过滤器分支选项与修订选项分开,
    • 以及 --all 重写所有分支和标记 .

    也就是说,在你目前的情况下 git gc ... prune ... 将删除仍由分支标记引用的提交,如 f1 这仍然指向 08e7463 .
    所以你看到的是正常的设计。


    行动组报告说 git filter-branch ... -- --all ,一个 rm -r .git/refs/original 照顾老朋友。

        2
  •  4
  •   davenpcj    13 年前

    我也有同样的问题,我忘了做 -- --all 在我的过滤器分支上,正如VonC所建议的。

    git filter-branch --env-filter 'export GIT_AUTHOR_EMAIL="fixed-email";
                                           GIT_AUTHOR_NAME="fixed-author"' -- --all
    

    但我还把它推到了一个远程github回购。。

    您可能需要以相同的方式修复GIT\u提交者\u名称和GIT\u提交者\u电子邮件。。一旦repo包含了多个作者,你就需要对名字进行过滤。我未配置的名字是“未知”。

    git filter-branch -f --env-filter '
    if [ "$GIT_COMMITTER_NAME" = "unknown" ]
    then
     export GIT_COMMITTER_EMAIL="fixed-email"
     export GIT_COMMITTER_NAME="fixed-author"
     export GIT_AUTHOR_EMAIL="fixed-email"
     export GIT_AUTHOR_NAME="fixed-author"
    fi
    ' -- --all
    

    但是因为我在修复之前把它推到了回购,然后又推到了回购之后,所以在我的git代码的历史中,除了没有完全孤立的refs分支之外,我还有一个奇怪的双头结构:

    --E--\                   --E--\
    ---A--B----\             ---A--B----\
        \----C--D--- master      \----C--D--- refs/original/refs/heads/master
    --E-----/                --E-----/
    

    A是我之前的回购,E是我在本地提交的变更,我正试图合并并推进回购。

    B和C都有A和E作为父母,D是新的负责人。B是我的工作第一次从E推到坏名字/地址,C是过滤分支将我在E中的所有更改修复为正确名字的结果。

    我曾经 git reflog 在本地克隆中显示序列,然后 git reset --hard A 把所有的东西放回原处,扔掉所有的更改和B/C/D中的文件。很好,是相同的文件,只是作者不同。

    然后我从E重新定义合并,然后 git filter-branch ----全部

    --E--\
    ---A--C-- master    (plus the refs branch is still there)
    

    那么现在呢 git shortlog -se 仅显示来自A和E的作者(已更正),而不显示来自B的“未知”作者。

    rm -r .git/refs/original 修剪那枝孤枝。 git branch 现在展示正确的东西。

    当我推git的时候,它抱怨失败了,并拒绝了。这是真的,因为上面的commit B正是我想要摆脱的。

    git push -f 我成功了。但要确保你在回购中拥有你想要的一切,因为这是破坏性的。但最终,远程github repo匹配的是我的本地结构,而不是变种。

    哦,还有额外的乐趣,如果你用msysgitforwindows做这个,你可能需要更新,我不能用1.52的filter branch,但是在更新到1.74后它工作正常。

        3
  •  0
  •   FelipeC    12 年前

    如果要修改所有分支,请记住使用 --all

    git filter-branch $options -- --all
    

    要删除旧的引用:

    rm -rf .git/refs/original