git - установка родителя коммита без перебазирования - PullRequest
23 голосов
/ 12 ноября 2010

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

      A---B---C topic

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

Я знаю, что фиксация A основана на фиксации 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, чтобы решить все проблемы.
Это возможно? Если это так, как я могу это сделать?

Ответы [ 3 ]

29 голосов
/ 12 ноября 2010

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

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

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

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

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


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

git filter-branch --tag-name-filter cat -- master..
8 голосов
/ 12 ноября 2010

Исходя из ваших диаграмм (хотя я обеспокоен тем, что вы подразумеваете под "Я довольно уверен, что я исправил проблемы, заставляющие 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 HEAD@{1}

# Rebase the topic branch onto the modified A commit (current HEAD)
git rebase --onto HEAD A topic
6 голосов
/ 24 ноября 2010

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

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

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

UPDATE:

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

...