git push branch to tag switch



Git: поддерево слиться в глубоко вложенный подкаталог? (2)

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

Я следовал приведенным here инструкциям, чтобы добавить хранилище модулей в качестве удаленного, запустить 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 уровня: сайты / все / модули /. Это тоже отлично работает, вытягивая изменения и обновляя файлы.

$ 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

https://ffff65535.com


Разъяснение для будущих читателей, решение в комментариях Криса Джонсена. Если вы видите ошибку «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.

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


Стратегия слияния 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




git-merge