2012-03-21 4 views
32

Я немного очистил наш репозиторий Git, нам нужно удалить большие части из истории. Я делаю это с помощью:Сокращение пустого слияния происходит из истории в репозитории Git

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

Флага --prune-empty удалит фиксации, которые остались пустыми после процесса, за исключением того, совершает с несколькими родителями (слияние фиксаций). Даже если ветвь, объединенная в, не содержит абсолютно ничего, и слияние ничего не добавляет к дереву.

Как я также обрезаю эти пустые слияния из истории?

ответ

0

Я нашел очень милый маленький обертку сценарий вокруг фильтра-ветви здесь:

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

Preconds и фон здесь:

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

+0

Это не работает. Из 'man git filter-branch':« Вы также можете использовать git_commit_non_empty_tree «$ @» вместо git commit-tree «$ @», если вы не хотите продолжать коммиты с одним родителем и не вносите изменений в дерево «. Но у коммитов слияния есть несколько родителей. Таким образом, он делает то же самое, что и флаг '--prune-empty'. Я попробовал это, и он не обрезает пустые слияния. :/ –

+0

Aah ok, damn. Тогда понадобилось больше исследований. Brb. – ralphtheninja

+0

Проверьте этот сценарий оболочки. – ralphtheninja

0

Так что мое решение движется все, чтобы суб- dir (исторически), а затем --subdirectory-filter

Первый шаг error combining git repositories into subdirs

Я изменил чуток файл Sh:

#!/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 

запустить

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

второй этап

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

и толкать его.

10

Мне нужно было сделать это после запуска filter-branch на копии ssokolow/profile, чтобы разделить ssokolow/lap.

Это сделал приличную работу в автоматическом «коллапсу прочь что-нибудь оставил рудиментарным по --prune-empty» Команда:

git rebase --root HEAD 

(я нуждался в --root поэтому было бы заменить ныне пустой первоначальное обязательство с самой старой, что еще содержание)

+0

Полезно, хотя в некоторых ситуациях переполняется. Стоит отметить, что этот подход сглаживает * все *, а не только пустые. –

+1

Обратите внимание также, что это сбрасывает GIT_COMMITTER_DATE, что и делает rebate по умолчанию. –

+0

@ ElanRuusamäe: Вы знаете способ избежать этого (т. Е. Сохранить исходную информацию комминера)? – Thilo

3

Это выглядит, как он работал для меня. http://git.661346.n2.nabble.com/Removing-useless-merge-commit-with-quot-filter-branch-quot-td7356544.html

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

rewrite_parent.rb:

#!/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(' ') 
20

Это превосходит Rebase решения, поскольку он сохраняет зафиксировавшие данные, даты коммиттера и непустые слияния оригинальной истории.

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

Это навеян же thread on the kernel mailing list чем решение Лукаса. Однако он не требует Ruby и является однострочным.Это делает, однако требуется версия GNU xargs и sed.

+1

Простое решение для меня, потому что не нужны внешние скрипты. – krlmlr

+1

В OSX 'sed 's/-p // g" | xargs git show-branch - независимый | sed "s/^/- p/g" | tr "\ n" "" 'работает для меня –

+1

Не удаляет транзакции слияния из нижнего дерева, т.е. слияние двух пустых коммитов (каждый без предка) – Tomas