Страницы

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

суббота, 16 марта 2019 г.

git subtree внутри одного репозитория

Как слить содержимое папки ветки 1 в ветку 2 и поддерживать синхронность папки в ветке 1 и ветки 2?
Контекст:
Делаю библиотеку, в т.ч. для выкладывания на github.com, на github принято выкладывать master-ветки без файлов проекта и окружения (файл настроек ide, подтянутые зависимости и т.п.), я же привык всё таскать с собой, чтобы легко было восстановить окружение.
Нужно сделать так:
ветка env: моё рабочее окружение, вместе с подтянутыми зависимостями. Чтобы можно было просто сделать checkout и скомпилировать проект.
ветка master - только непосредственно мои исходники.
Речь идет о репизитории https://github.com/rekby/mbr, сейчас туда загружен вариант с веткой env. Ветка master пуста. В master должно быть содержимое https://github.com/rekby/mbr/tree/env/src/github.com/rekby/mbr
По документации я понял что мне хорошо должен подойти вариант поддеревьев (subtree) - я работаю в своей env-ветке и периодически сливаю изменения в мастер. При необходимости из master подтягиваю их обратно через git diff-tree
В этом месте возникла проблема - git diff-tree работает не так как я этого ожидаю.
Например:
git checkout env git diff-tree -R -r -p master src/github.com/rekby/mbr
Как я понимаю должен мне выдать отличия в src/github.com/rekby/mbr ветки env (текущей) и корнем ветки master (в которой и должен оказаться мой код). Вывод команды пуст.
Попробовал с --relative и еще несколько вариантов - результат тот же.


Ответ

посмотреть отличия в файлах, находящихся в разных каталогах в двух разных ветках можно так:
$ git diff branch1:path/num/1 branch2:path/num/2
в вашем конкретном случае примерно так:
$ git diff master: env:src/github.com/rekby/mbr
если достаточно просто перенести изменения в ветку master, то можно, переключившись в эту ветку, выполнить примерно такую команду:
$ git checkout master $ git diff master: env:src/github.com/rekby/mbr | git apply
если же требуется перенести коммиты (т.е., коммит-сообщения, дату, авторство), то тогда следует ориентироваться не на различия в файлах (получаемые с помощью diff-а), а на различия в списке коммитов. придётся как-то самостоятельно отслеживать — какие коммиты уже перенесены, а какие ещё нет (я, к сожалению, не знаю средств git-а, позволяющих автоматизировать такой процесс — с изменением путей).
получить набор patch-файлов, содержащих коммиты, начиная с заданного, в вашем случае можно примерно так:
$ git checkout env $ git format-patch хэш-последнего-уже-перенесённого-коммита $ git checkout master $ git am -p5 *.patch
обратите внимание на параметр -p5 для команды git am. он указывает отбросить 5 элементов в пути файлов, перечисленных в патче, т.е. вместо a/src/github.com/rekby/mbr/mbr.go получится просто mbr.go
не забудьте после этого удалить сформированные файлы *.patch, чтобы не возникло проблем при следующих переносах.
чтобы сформировать patch-файл для одного коммита, можно передать команде git format-patch параметр -1
$ git format-patch -1 хэш-переносимого-коммита

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

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