Страницы

Поиск по вопросам

четверг, 28 ноября 2019 г.

Как сделать другой репозиторий ответвлением в текущем?

#git




Как сделать другой репозиторий ответвлением в текущем?
    


Ответы

Ответ 1



Для начала, надо куда-то стащить коммиты из двух репозиториев сразу, ведь вы хотите получить комбинацию двух историй. Следуя вашим рисункам, работать будем в репозитории с коммитами-цифрами, а второй подключим к нему: Добавить в него репозиторий с коммитами-буквами как "удалённый источник" (remote) под названием letters (сами можете выбрать и другое, не принципиально): git remote add letters путь/к/другому/репозиторию Стащить оттуда коммиты/ветки/теги/всёподряд: git fetch letters Сделать и перейти в новую ветку base, начинающуюся с master ветки второго репозитория: git checkout -b base letters/master # Ветки ж master в обеих? Откройте журнал ветки master текущего репозитория и найдите коммит, от которого планируете ответвиться: git log master Скажем, пусть его хэш будет начинаться на abcdef. Это всё были приготовления. А теперь заклинание: git rebase --root --onto abcdef Перевесить цепочку коммитов (rebase)... ...от текущего до основания (--root)... ...на коммит с хэшем abcdef (--onto abcdef). В итоге имеем: [1 ]---[2 ]---[3 ]---[4 ]---[5 ] (master) \ \ \[А']---[Б']---[В']---[Г'] (base) Всё как на рисунке. Кроме... хэшей буквенных коммитов. Изменение того, от чего они ответвлены, меняет и их хэши. Поэтому они и отмечены штрихами, т. к. это не на все 100% исходные коммиты. В них будет всё то же самое, кроме предков (если вы с конфликтами не столкнётесь). PS: мне решительно непонятно, для чего эти две истории нужно сцеплять у основания, хотя вам виднее, наверное. Git нормально обращается с несвязанными между собой ветками в одном репозитории. Когда на гитхабе был биллинг по количеству закрытых репозиториев, некоторые экономили, собирая в одном репозитории ветки нескольких проектов. И это работало. Причём для тех, кому нужно было несколько проектов сразу, с помощью свежего Git (2.5+?) можно было держать несколько рабочих копий, относящихся к разным веткам одного репозитория, с помощью git worktree add. Такие дела.

Ответ 2



(Выношу из комментариев) В вашем варианте, как правильно заметил Nick Volynkin, решения быть не может. Надо выбрать либо а) общую базу, тогда изменения А-Г перейдут соответственно в А'-Г', либо б) сохранение изменений, тогда ветка будет соединена как вы сами заметили "сверху". Я выбрал приоритетом вариант б) и вот почему: изменения остаются неизменными; вы можете продолжать развитие старого проекта и "подливать", если нужно, в новый; rebase, так для краткости назовём вариант а), вообще плохая практика для опубликованных репозиториев (тут уж от вас зависит строгость этого термина). Теперь к сути. Вариант б) или merge делается в три команды: git checkout -b <имя новой ветки> <хеш комита №2> git fetch <имя ветки в репозитории №2> git merge --allow-unrelated-histories FETCH_HEAD Перед выполнением необходимо убедиться, что вы находитесь в нужной ветке репозитория №1. В третьей строке специальная опция, чтобы избежать ошибки: fatal: refusing to merge unrelated histories, о которой подробнее описано тут. При наличии конфликтов на третьем этапе их надо разрешить самому так, как вы считаете нужным. Результатом будет ветка <имя новой ветки> в репозитории №1.

Ответ 3



решений, конечно, много. например, можно воспользоваться командой format-patch и парной для неё am. пример. в каталоге 0 у нас хранилище с такой историей: $ git log --one-line a3d5387 5 2b7f19f 4 e1d8018 3 3e1fa25 2 7e8bd8d 1 а в каталоге 1 — с такой: $ git log --one-line 5ea5e2c d d42991a c f980223 b cff9df9 a и хотим мы, чтобы коммиты a b c d из второго хранилища «приложились» к коммиту 2 из первого хранилища. во-первых, надо получить все коммиты в виде patch-файла: $ cd /путь/к/хранилищу/1 $ git format-patch --stdout --root cff9df9 > patch $ git format-patch --stdout cff9df9..HEAD >> patch две команды требуются для того, чтобы в файл patch попал и «корневой» коммит a во-вторых, применить их с помощью команды am в хранилище 0, предварительно создав там новую ветку, ответвлённую от коммита 2: $ cd /путь/к/хранилищу/0 $ git checkout -b new 3e1fa25 $ git am /путь/к/хранилищу/1/patch Applying: a Applying: b Applying: c Applying: d если конфликтов не возникло, в хранилище 0 будет такая картина: $ git log --oneline --all --decorate --graph * 20b6b2f (HEAD -> new) d * 8dedddf c * 6ddec5e b * cb7a798 a | * a3d5387 (master) 5 | * 2b7f19f 4 | * e1d8018 3 |/ * 3e1fa25 2 * 7e8bd8d 1 хэш-суммы, понятно, стали у «приложенных» коммитов другие, но всё остальное — содержимое, дата, автор — на месте.

Комментариев нет:

Отправить комментарий