Подтвердить что ты не робот

Git: Subtree Merge в глубоко вложенную подкаталоги?

Я пытаюсь использовать git поддерево слияния stategy, где подкаталог, в который я хочу объединиться, достаточно глубоко вложен - в настоящее время четыре уровня глубоки.

Я следил за указаниями здесь, чтобы добавить репозиторий модулей в качестве удаленного, запустите git read-tree, чтобы получить удаленный код в подкаталог в моем локальном репо и зафиксировать эти изменения.

Моя проблема возникает, когда я пытаюсь вытащить и слить изменения с пульта в главную ветку моего основного проекта. Шаг 5 на вышеприведенной странице предлагает git pull с ключом -s поддерева. Это работает правильно для меня, когда мой подкаталог один, два или три уровня в глубину, но не четыре.

Вот результат слияния в подкаталог 2 уровня глубоко. Вы можете увидеть, что файл README на сайтах/все/был правильно обновлен. В моем удаленном репо README находится в корне.

$ git pull -s subtree REMOTE_REPO master
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /path/to/my/REMOTE_REPO
 * branch            master     -> FETCH_HEAD
Merge made by subtree.
 sites/all/README |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

Здесь подкаталог имеет 3 уровня глубины: sites/all/modules/. Это тоже отлично работает, вытягивая изменения и обновляя файлы.

$ git pull -s subtree REMOTE_REPO master
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /path/to/my/REMOTE_REPO
 * branch            master     -> FETCH_HEAD
Merge made by subtree.
 sites/all/modules/README |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

Но теперь мой код находится в подкаталоге 4 уровня в глубину: sites/all/modules/my_module/. git похоже, вытаскивает изменения из REMOTE_REPO, но он не обновляет файлы, а говорит мне, что он уже обновлен.

$ git pull -s subtree REMOTE_REPO master
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /path/to/my/REMOTE_REPO
 * branch            master     -> FETCH_HEAD
Already up-to-date!
Merge made by subtree.

И если я запустил его сразу, он не вытащил изменения или не обновил файлы.

$ git pull -s subtree REMOTE_REPO master
From /path/to/my/REMOTE_REPO
 * branch            master     -> FETCH_HEAD
Already up-to-date.

Просмотр журнала git в этот момент покажет мне изменения из удаленного репо и слияния, но файлы в моем контроле не были обновлены.

Является ли это ошибкой, или я делаю что-то неправильно?

Обновление: Крис Джонсен предложил следующий вариант, который вызывает ошибку:

$ git pull -X subtree=sites/all/modules/my_module/ REMOTE_REPO master
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /Users/jeff/work/checkouts/compass_suite
 * branch            master     -> FETCH_HEAD
fatal: entry  not found in tree 173d4f16af4d2d61ae5c4b3446c392e8b49cc57d
4b9b3361

Ответ 1

Стратегия слияния subtree искусственно ограничивает глубину поиска, где поддерево "вписывается" в общее дерево. К сожалению, этот предел жестко закодирован (см. match-trees.c:267).

К счастью, Git 1.7.0 добавила опцию subtree=… в стратегию слияния (по умолчанию) recursive. Этот параметр позволяет точно указать префикс так, чтобы Git не нужно было гадать (столько же).

С Git 1.7.0 или новее попробуйте следующее:

git pull -X subtree=sites/all/modules/my_module REMOTE_REPO master

Ответ 2

Уточнение для будущих читателей, решение находится в комментариях Криса Джонсена. Если вы видите ошибку "fatal: entry not found in tree", избавитесь от конечной косой черты в конце вашего префикса поддерева.

Например, если вы пытаетесь вытащить поддеревье GitHub Pages с помощью команды типа

git subtree --prefix gh-pages/ pull origin gh-pages

и есть конфликты, вы получите ошибку, например

 * branch            gh-pages   -> FETCH_HEAD
fatal: entry  not found in tree 6e69aa201cad3e5888f1d12af0d910f8a10a8ec3

Просто удалите конечную косую черту из каталога gh-pages

git subtree --prefix gh-pages pull origin gh-pages

Это будет работать и будет пытаться объединиться. Худший сценарий, который вы можете получить, - это когда сбой автоматического слияния и вы получите ошибку, например

Automatic merge failed; fix conflicts and then commit the result.

но вам просто нужно разрешить конфликты вручную, и все готово.