关于git filter分支:从Git存储库中的历史记录中修剪空合并提交

Prune empty merge commits from history in Git repository

我已经清理了不少Git存储库,我们需要从历史中删除大部分内容。我这样做是使用:

1
git filter-branch --prune-empty --tree-filter 'rm -rf some_stuff'

--prune-empty标志将删除进程后保留为空的提交,但与多个父级的提交除外(合并提交)。即使被合并的分支绝对不包含任何内容,合并也不会向树中添加任何内容。

如何从历史中删除这些空合并提交?


这优于Rebase解决方案,因为它保留了原始历史记录的提交者信息、提交者日期和非空合并。

1
2
git filter-branch --prune-empty --parent-filter \
    'sed"s/-p //g" | xargs -r git show-branch --independent | sed"s/\</-p /g"'

这是受到内核邮件列表中与Lucas解决方案相同的线程的启发。但是它不需要Ruby,而且是一个单行程序。不过,它确实需要xargssed的GNU版本。


我需要在运行了一份ssokolow/profile上的filter-branch之后这样做,以分离ssokolow/lap。

这是一个很好的工作,作为一个自动"瓦解任何由--prune-empty命令遗留下来的东西:

1
git rebase --root HEAD

(我需要--root,所以它将用最旧的仍然有内容的初始提交替换现在空的初始提交。)


这看起来对我很有用:http://git.661346.n2.nabble.com/removing-unused-merge-commit-with-quot-filter-branch-quot-td7356544.html

1
git filter-branch -f --prune-empty --parent-filter FULL_PATH_TO/rewrite_parent.rb master

rewrite_parent.rb号:

1
2
3
4
5
6
7
8
9
10
#!/usr/bin/ruby
old_parents = gets.chomp.gsub('-p ', ' ')

if old_parents.empty? then
  new_parents = []
else
  new_parents = `git show-branch --independent #{old_parents}`.split
end

puts new_parents.map{|p| '-p ' + p}.join(' ')


因此,我的解决方案是将所有内容都转移到子目录(历史上),然后转移到--subdirectory-filter

将Git存储库合并为子目录时的第一步错误

我修改了一点sh文件:

1
2
3
4
5
#!/bin/bash

git ls-files -s | sed"s-\t-&temp_dir/-" | GIT_INDEX_FILE="$GIT_INDEX_FILE.new" git update-index --index-info

mv"$GIT_INDEX_FILE.new""$GIT_INDEX_FILE" || true

运行

1
git filter-branch --index-filter '~/doit.sh' HEAD

第二步

1
git filter-branch --subdirectory-filter temp_dir --prune-empty

然后推动它。


我在这里的filter分支找到了一个非常可爱的包装脚本:

https://github.com/pflanze/chj-bin/blob/master/cj-git-filter-branch

这里是预编码和背景:

http://lists.q42.co.uk/pipermail/git-announce/2011-九月/000486.html