Git rebase и сохранить все дочерние ветки

Я пытаюсь импортировать репозиторий CVS в git. К сожалению, мы использовали действительно старый метод создания релизов из нашего репозитория CVS, который не включает никаких реальных ветвей CVS или тегов, но сохраняйте эту информацию в отдельной системе. Следовательно, почти вся разработка происходит на стволе CVS. Таким образом, один файл может быть добавлен очень рано в истории, но не станет частью выпуска в течение 6 месяцев.

Я бы хотел импортировать этот CVS-репозиторий в git и использовать rebasing для перемещения этих коммитов в ветки разработки. У меня есть несколько ветвей из CVS, хотя я действительно хочу переместить все ветки.

Скажем, у меня есть это:

                  F---G---H topic
                 /
A---B---C---D---E---I---J master

B - это фиксация, которую я хочу переместить в свою ветвь. Я хочу, чтобы результат выглядел так:

                F`---G`---H` topic
               /
A---C`---D`---E`---I`---J` master
 \
  B some_unfinished_feature

Но только переполнение master приводит к:

git checkout -b some_unfinished_feature B
git rebase --onto A B master

A---C`---D`---E`---I`---J` master
 \
  \               F---G---H topic
   \             /
    B---C---D---E
     \-some_unfinished_feature

Могу ли я получить git для rebase topic на E' в одной команде rebase? Я могу потенциально иметь множество ветвей, которые я хочу переместить на их новую новую фиксацию. Или есть способ, которым я могу получить сопоставление между E и E'?

Ответ 1

               F---G---H topic
              /
 A---B---C---D---E---I---J master

 git checkout B
 git branch BRANCH-B
 git checkout master
 git rebase -i  HEAD~6

(удалить commit B)

 git rebase --onto D' D topic

Это должно сделать это, не допуская конфликта;)

Ответ 2

Командой перемещения topic будет:

git rebase --onto E' E topic

К сожалению, нет никакого способа сделать это автоматически для кучи разных ветвей, и это по дизайну. Каждая перебаза потенциально представляет конфликты, которые необходимо разрешить вручную.

В качестве альтернативы вы можете использовать git filter-branch с помощью программного обеспечения для управления конфигурацией до script необходимых изменений, но это потенциально много работы. Возможно, имеет смысл сохранить master как ветку развития и использовать filter-branch для создания ветки релиза, а не наоборот.

Ответ 3

Во-первых, слово совета: при повторном использовании работайте с временной ветвью:

git branch wip_topic
git checkout wip_topic

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

git checkout topic
git reset --hard wip_topic
git branch -d wip_topic

(если вы этого не сделали, и что-то плохое, git reflog может сохранить ваш бекон...)


При выполнении переадресации git пропускает коммиты, где текстовый diff commit фиксирует существующую фиксацию на целевой ветке.

Если ваша перестановка master не вводила слишком много конфликтов, применяя:

git rebase --onto A B wip_topic

должен дать вам желаемый результат.

Как правило, большинство конфликтов будет появляться вблизи "начала" списка переустановленных фиксаций (< - щепотка соли).
Предположим, что у вас возникли конфликты при создании commit C', но после этого вы можете перегрузить часть C..topic:

git rebase --onto C' C wip_topic

Во всяком случае: попробуйте и посмотрите, что делает git черная магия.