2010-07-11 63 views
4

我在我的仓库中使用了过滤分支到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"' 

,并得到这样的:

​​

几件事情,打扰我:

1)f1分支未移至0f58ab5。
2)在fb012a9之前的所有提交与我无关,我可以摆脱它们吗?

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

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,现在我只需要找到一种方法来摆脱第旧的提交,我该怎么做?

回答

6

难道你再试试你的git的过滤分支与“-- --all”末,如:

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

注:

  • ,从修订选项分离过滤器分支选项--
  • --all重写所有分支和标签

这就是说,在当前形势下,没有git gc ... prune ...量将删除提交仍由一个分支标记引用,如f1仍然指向08e7463
所以你看到的是正常的,通过设计。


的OP报告说,一旦做git filter-branch ... -- --all,一个rm -r .git/refs/original取旧提交的照顾。

再一次,这并不奇怪:没有标签或分支引用它们,这次意味着这次它们是永久从Git仓库中删除的候选项。

+0

感谢,它解决的问题之一,看到我的编辑。 – 2010-07-11 13:26:19

+0

实际上'rm -r .git/refs/original'这次做的诡计,很奇怪......谢谢! – 2010-07-11 15:05:28

+0

@Idan:感谢您的反馈。我已经完成了我的答案。 – VonC 2010-07-11 16:07:00

4

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

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

但我另外它推到一个远程GitHub库..

您可能需要修复的GIT_COMMITTER_NAME和GIT_COMMITTER_EMAIL相同的方式..一旦回购包括多个作者,你会需要过滤名称。我的未配置名称是“未知”。

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代码历史上的一个奇怪的双头结构,除了没有,相当-orphaned裁判分支:

--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把所有的东西都放回到A处,扔掉B/C/D中的所有变化和文件。这很好,这是相同的文件,只是与不同的作者。

然后我重做了合并从E,和上面的git filter-branch,这次包括-- --all它改变了我的本地回购是

--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 push的时候,它抱怨失去了提交并被拒绝了。这是真的,因为上面的提交B正是我想要摆脱的。

git push -f诀窍。但确保你在回购中拥有你想要的一切,因为它具有破坏性。但最终,远程github回购与我的本地结构相匹配,而不是突变。

哦,为了获得额外的乐趣,如果你使用的是msys Git for windows,那么你可能需要更新,我无法使用1.52的filter-branch,但在更新到1.74后仍然可以正常工作。

+0

生命力,完美工作 – Sam 2013-06-17 13:01:38

0

如果要修改所有的树枝记得使用--all

git filter-branch $options -- --all 

,并删除旧的引用:

rm -rf .git/refs/original