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
Ответы
Ответ 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.
но вам просто нужно разрешить конфликты вручную, и все готово.