Самый простой способ повторного воспроизведения фиксируется в новом репозитории git

Я использовал git -svn, и недавно я получал ошибки при попытке совершить (я думаю, что это связано с ошибкой в ​​libneon, но это выходит за рамки этого вопроса). Решением было повторное клонирование моего репозитория git с помощью git svn clone. Тем не менее, у меня есть изменения на главной ветке в моем старом репозитории git, который я не смог передать svn, используя git svn dcommit. Я хотел бы воспроизвести эти изменения в новом репозитории, клонированном с помощью git svn. Я думаю, что я мог бы, вероятно, экспортировать патч-набор с помощью git format-patch, а затем воспроизвести эти изменения в новом репозитории, но я не совсем уверен, как это сделать, и я задаюсь вопросом, есть ли еще более простой или элегантный способ выполнения это.

Ответы

Ответ 1

Из вашего нового репозитория добавьте удаленную ссылку в ваш старый репозиторий:

git remote add temp file:///path/to/old/repo/on/your/machine

Извлечение из старого репо:

git fetch temp

Проверьте свою основную ветку из старого репо:

git checkout temp/master -b wip

(wip обозначает незавершенное производство)

Восстановите изменения поверх материала в вашем существующем репозитории:

git rebase master

Обновить мастер, чтобы указать на новый HEAD:

git checkout master
git merge wip

Удалите удаленную ссылку на свое прежнее репо и используемую ветку wip:

git branch -d wip
git remote rm temp

Что вы на самом деле делаете:

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

Итак, когда вы создали новый репозиторий Git, основанный на том же репозитории SVN, все коммиты имели те же суммы SHA1. В результате новые коммиты, которые вы загрузили в свой текущий репозиторий, продолжали указывать на правильные вещи. Это очень здорово и важно запомнить.

Затем вы переключились на кончик ветки мастера темпа и сказали ему переустановить ваш текущий мастер. Возможно, перебаза была ненужной, поскольку мастер из SVN, возможно, не отошел от мастера в вашем старом репо, но лучше всего быть в безопасности.

Бабаза находит ближайшую точку общности между двумя коммитами, работая назад через их истории, пока они оба не укажут на одно и то же сообщение родителя. Затем он переключается на имя ветки, которое вы ему дали (в данном случае master), и вишня выбирает каждый из коммитов, отсутствовавших в своей истории из исходной ветки. После завершения он указывает на ветку, в которой вы были, когда вы начали с последней фиксации, которую она применяла.

Наконец, слияние мастера с wip состояло в том, чтобы просто переместить мастер в конец. Поскольку это была прямая линия, на самом деле это была просто перемотка вперед. Вы могли бы так же легко выполнить rebase или reset - hard; любой из них изменил бы главную ветвь, чтобы указать на правильное местоположение. Слияние было только самым безопасным из них, потому что, если бы что-то странное произошло, это дало бы вам понять, что это не простая перемотка вперед.

Ответ 2

Вы можете:

  • добавьте свое старое репо в качестве удаленного вашего нового репо (git remote)
  • выберите ветку
  • переформатируйте часть старой ветки, в которой вы заинтересованы, поверх текущего master.

См. Как вишня выбрать диапазон коммитов и слить в другую ветку:

# go to your current but incomplete new master branch
git checkout master

# mark your current master HEAD as branch 'tmp'
git checkout -b tmp

# reset your master to the old one
git branch -f master oldrepo/master

# replay the right commits on top of 'tmp' (which was your master HEAD)
git rebase --onto tmp first_SHA-1_of_old_master_to_replay~1 master

# remove tmp branch, 
# your master HEAD is now on top of tmp, with the right commits replayed
git branch -d tmp

Это решение будет работать, даже если SHA1 отличается от старой истории master и вашего нового мастера с вашего второго git-svn clone.
Вот почему я рекомендую rebase --onto: история обоих master может иметь ничего общего, если по какой-либо причине вторая git-svn clone не генерирует точно такой же SHA1.