2010-07-11 5 views
4

Я использовал фильтр-ветвь в fix an incorrect email address в моем репозитории, но все ветви теперь MIA (кроме мастера).как удалить старые коммиты после фильтрации-ветви?

Это то, что 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.
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 

EDIT: делать то, что было предложено 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.
Итак, что вы видите, это нормально, по дизайну.


ОП сообщает, что после того, как делает git filter-branch ... -- --all, rm -r .git/refs/original заботится о старых фиксаций.

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

+0

спасибо, это решается одна из проблем, увидеть мой выбор. –

+0

Фактически 'rm -r .git/refs/original' сделал трюк на этот раз, странно ... спасибо! –

+0

@ Идан: Благодарим вас за отзыв. Я выполнил свой ответ. – VonC

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 

Но потому, что я толкнул его к репо до исправления, а затем толкнул его после того, как у меня было странное строение две головки в истории моего мерзавца кода, в дополнение к не совсем -orphaned рефов ветви:

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

а был репо, прежде чем я добрался до него, Е мои локально совершенные изменения, которые я пытался объединить в и нажать на репо.

Оба B и C имеют A и E в качестве родителей, а D - это новая голова. B - это первый толчок моей работы из E с неправильным именем/адресом, C - результат фильтрации, фиксирующий все мои изменения в E, чтобы быть правильным именем.

Я использовал git reflog, чтобы показать последовательность в моем локальном клоне, затем git reset --hard A, чтобы все вернуть в A, отбросив все изменения и файлы в B/C/D. Это было хорошо, это были те же файлы, как раз с разными авторами.

Тогда я переделал слияние с Е и выше git filter-branch, на этот раз включая -- --all, который изменил мой местный репо быть

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

Так что теперь git shortlog -se показывает только автор из А и Е (исправленный), а не «неизвестный» автор из B.

Затем я использовал rm -r .git/refs/original для обрезки осиротевшей ветви. git branch теперь показывает правильную вещь.

Когда я сделал git push, он пожаловался на потерю коммитов и отказался. Это верно, потому что commit B выше - именно то, что я хотел избавиться.

git push -f сделал трюк. Но будьте уверены, что у вас есть все, что вы хотите в репо, потому что оно разрушительно. Но, в конце концов, удаленное github-репо соответствует моей локальной структуре, а не мутанту.

О, и для бонусной забавы, если вы делаете это с помощью msys Git для Windows, вам, возможно, придется обновлять, я не мог использовать ветвь фильтра с 1,52, но после обновления до 1,74 он работал нормально.

+0

Lifesaver, отлично работает – Sam

0

Если вы хотите изменить все ветви не забудьте использовать --all

git filter-branch $options -- --all 

И удалить старые ссылки:

rm -rf .git/refs/original 
Смежные вопросы