Git - установка родителя фиксации без переустановки

Я использовал git-svn для создания зеркала git репозитория SVN. Структура внутри SVN была немного нестандартной, поэтому git создала ветвь, которая не имеет общей фиксации с ветвью master.

      A---B---C topic

D---E---F---G master

Я знаю, что commit A основан на commit E, и я довольно уверен, что исправил проблемы, вызывающие git, чтобы не распознавать этот факт (используя filter-branch). То, что я хочу сделать, это повторно присоединить topic к ветке master, установив E в качестве родителя A:

      A---B---C topic
     /
D---E---F---G master

git-rebase, похоже, не работает для меня, потому что diff для commit A перечисляет создание большого количества файлов, которые уже существуют в master, что приводит к огромному количеству конфликтов.
Из моего понимания git просто установка E, поскольку родительский элемент A должен быть достаточным для решения всех проблем.
Это возможно? Если да, то как я могу это сделать?

Ответ 1

Посмотрите на трансплантаты (файл трансплантата можно найти в .git/info/grafts). Формат довольно прост:

<commit sha1> <parent1 sha1> <parent2 sha1> … <parentN sha1>

Это означает, что git считает, что у фиксации есть разные родители, чем есть на самом деле. Используйте фильтр-ветвь, чтобы сделать трансплантаты постоянными (так что файл графтов можно удалить):

git filter-branch --tag-name-filter cat -- --all

Обратите внимание, что эта перезаписывает историю в репозитории, поэтому ее нельзя использовать в общих репозиториях!


Если вы хотите только переписать историю коммитов, которые были перенесены на главную ветвь, например, используйте следующую команду:

git filter-branch --tag-name-filter cat -- master..

Ответ 2

Основываясь на ваших диаграммах (хотя меня беспокоит то, что вы подразумеваете под "Я довольно уверен, что исправил проблемы, вызывающие git, чтобы не распознавать этот факт (используя filter-branch)." ) вы должны сделать что-то вроде следующего.

# checkout A
git checkout A

# Reset the branch pointer to E so that E is the parent of the next commit
# --soft ensures that the index stays the same
git reset --soft E

# Remake the commit with the E as the parent, re-using the old commit metadata
git commit -C [email protected]{1}

# Rebase the topic branch onto the modified A commit (current HEAD)
git rebase --onto HEAD A topic

Ответ 3

Все, что вам нужно, это:

git rebase --root --onto master^^ topic^^ topic

параметр root позволяет включать A.

UPDATE:

Добавьте параметр --preserve-merges, если вы хотите сохранить разветвление и слияние части, которую вы перегружаете.