Страницы

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

четверг, 23 января 2020 г.

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

#git


Как слить содержимое папки ветки 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 и еще несколько вариантов - результат тот же.
    


Ответы

Ответ 1



посмотреть отличия в файлах, находящихся в разных каталогах в двух разных ветках можно так: $ 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 хэш-переносимого-коммита

Ответ 2



возможно, лучшим решением (с сохранением предпочитаемого порядка работы) будет создание двух репозиториев: одного с кодом проекта и ещё одного с «дополнительной обвеской», в котором репозиторий с кодом будет подключен как подмодуль (submodule). примерно так: $ git checkout env $ git submodule add url-репозитория-с-кодом путь/где/будет/находиться/подмодуль $ git commit -m 'add submodule url-репозитория-с-кодом' подробнее можно узнать в документации и примерах использования. например, отсюда.

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

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