LINUX.ORG.RU

git clone при наличии подпроекта в основном проекте (поддеревья)

 ,


1

4

Есть удалённый репозиторий основного проекта, в котором в каталоге cite лежит содержимое другого подпроекта.

Реализована данная схема была согласно этому руководству.

Добавил удалённый сервер подпроекта:

git remote add cite_serv user@server:/opt/git/cite
Получил информацию по серверу:
git fetch cite_serv
Поместил подпроект в отдельную ветку cite_project
git checkout -b cite_project cite_serv/master
Переключился в ветку master основного проекта
git checkout master
Вытянул подпроект в подкаталог cite, которого изначально в основном проекте не было:
git read-tree --prefix=cite/ -u cite_project

В итоге (практически цитата): после того как вы сделаете коммит, все файлы проекта сite_project будут находиться подкаталоге cite — будто вы скопировали их туда из архива.

Плюсом подхода является то, что можно лего последние изменения подпроекта вытягивать в соответствующую ветку и потом её объединять через

git merge --squash -s subtree --no-commit cite_project

Теперь сложности: Прихожу домой, клонирую основной проект.

git clone user@server:/opt/git/letter
Ни о каком втором удалённом сервере полученный проект не знает, папка cite так же присутствует.

При повторении предыдущей последовательности команда

git read-tree --prefix=cite/ -u cite_project
выдаёт
 error: Entry 'cite/LibraryDB.bib' overlaps with 'cite/LibraryDB.bib'.  Cannot bind.
что логично, файлы же существуют после клонирования.

Вопрос такой: можно ли как-то ветку подпроекта (cite_project), которая создалась после git checkout -b cite_project cite_serv/master объединить с уже существующей папкой cite в основном проекте? И чтобы она смотрела на cite_serv/master?

Сейчас использую такой костыль:

Удаляю в клонированном проекте папку cite

git rm -r cite/
Дальше вытягиваю подпроект в каталог cite вышеописаной командой
git read-tree --prefix=cite/ -u cite_project

При таком подходе теряются изменения, которые были внесены в cite в основном проекте, но ещё не были отправлены в репозиторий подпроекта.

гит не централизованная система - это надо осознавать

Советую подстраховаться и перетащить на домашний комп ветку подпроекта и потренироваться на ней. В случае сложностей ветку подпроекта можно обновить в отдельный домашней репе, а потом синхронизировать с основным проектом. Для подстраховки так и делал, ибо запушить в удаленную ветку мастер рискованно без отлаженного воркфлоу.

Насчет приведенного мануала ничего не скажу: я делал по этому: https://www.kernel.org/pub/software/scm/git/docs/howto/using-merge-subtree.html

рекомендую плагин-хук для гита поставить еще: https://github.com/apenwarr/git-subtree (поискать более свежие)

с ним проще экспериментировать и пушить.

И естественно все эксперименты делать в отдельных ветках и локальных репах - для гита локальная репа такая-же как и удаленная.

swwwfactory ★★ ()
Ответ на: комментарий от swwwfactory

Судя по всему git-subtree должно помочь.

# move yourself to the subtree commit of your choice
git checkout <subtree-hash>

# fetch commits from the subtree repository, to have available the commit you want
# to cherry pick.
git fetch <path-to-remote>

# cherry pick the hash you want
git cherry-pick <cherry-hash>

# move back to your original branch
git checkout <your-branch>

# subtree merge your cherry pick (using the previous HEAD),
# so that it gets moved to the correct location specified by prefix.
git subtree merge --prefix <subtree-prefix> HEAD@{1}

# Since you probably fetched more commits that you needed from
# the remote, you might want to clean those that where not needed
git gc

Но, я так понял, что с подпроектами идеологически правильно работать в режиме read-only, а необходимые изменения сначала вносить в удалённый репозиторий подпроекта, а затем pull'ить и merge'ить их в основной проект.

Опыта мало, остановлюсь на последнем, git-subtree оставлю в закладках.

Jurik_Phys ★★★★★ ()
Последнее исправление: Jurik_Phys (всего исправлений: 1)
Ответ на: комментарий от Jurik_Phys

нет, можно работая в основном дереве менять в подпроекте, который приаттачен в дереве, потом с помощью плагина делаешь пуш в отдельную ветку отдельной репы подпроекта. Там мержишь уже ветку в мастер подпроекта и при необходимости пушишь в другую репу этого репозитария (т.е. подпроекта) в обычном порядке.

Потом, чтобы убедится что все прошло правильно в рабочем проекте - делаешь подлив в поддерево из сторонней репы того подпроекта.

Эта схема работает достаточно хорошо, но нужен навык. Прежде чем делать реальные изменения раз пять минимум потренироваться на «кошках»... т.е. на ветках и локальных репах-клонах.

Для освоения материала погугли видео в тему.

еще ссылки:

http://community.webfaction.com/questions/4442/how-do-i-install-git-subtree

http://www.betaful.com/2011/01/i-love-git-subtree/

http://log.pardus.de/2012/08/modular-git-with-git-subtree.html

swwwfactory ★★ ()
Последнее исправление: swwwfactory (всего исправлений: 1)
Ответ на: комментарий от swwwfactory

Установил subtree, пощупал - работает. Но, моё затруднение всё равно не решает.

Никак не могу понять: пусть есть удалённый сервер, пользователь А, пользователь Б.

Пусть пользователь A подключит в основной проект, в каталог cite подпроект (не важно, через subtree, либо в прямо через read-tree), сделает commit и отправит результат в репозиторий основного проекта. Теперь пользователь Б, склонировав основной проект, не может подключить тот же подпроект в каталог cite т.к., каталог уже будет существовать после клонирования.

Вот и выходит, что Б либо работает с cite в режиме read-only, получая изменения в cite только через удалённый основной репозиторий(изменения поствляет, соответственно, только пользователь А), либо удаляет cite из рабочего каталога (git rm -r cite) и вручную подключает подпроект в cite.

Этот момент, что пользователь Б при клонировании ничего не знает про существование подпроектов и возмжные несоответствия версий файлов подпроекта в основном репозитории и в репозитории подпроекта меня и напрягает.

При таком раскладе, если пользователь A сделает изменения в cite, но не пошлёт их в репозиторий подпроекта, то пользователь Б (после клонирования проекта) при удалении папки cite и подключении подпроекта самостоятельно, рискует потерять изменения, сделанные в основном проекте, но в файлах подпроекта.

Jurik_Phys ★★★★★ ()
Ответ на: комментарий от Jurik_Phys

гит - это тотальная децентрализация и владелец в праве делать со своей репой все, что пожелает. Это так-же означает, что владельцы реп не обязаны вообще задумываться или строить предположения о других репах. Вся информация о поддереве находится в умах и локальных репах, больше нигде. Соответственно, когда ты копируешь плоское дерево, получаешь монолит. Потом делаешь ему https://www.kernel.org/pub/software/scm/git/docs/howto/using-merge-subtree.html и получаешь рабочее поддерево - т.е. каталог остается как и был, но локальная репа уже знает, что это поддерево. Теперь можно делать pull для поддерева и push subtree поддерева в репу поддерева (вот тут советую пушить в отдельную локальную ветку, локальной репы)

Этот момент, что пользователь Б при клонировании ничего не знает про существование подпроектов и возмжные несоответствия версий файлов подпроекта в основном репозитории и в репозитории подпроекта меня и напрягает.

Это централизованное мышление не дает Вам свободно мыслить в данном аспекте - никто и ничто никому и ничему не обязано. Децентрализация, позволяет быть равноправным центром каждому участнику такой системы. Есть команды синхронизации на это: pull|push и ветки - а уж задача владельца разрешить конфликты и слиться в конечном итоге с мастер-веткой, если это необходимо.

swwwfactory ★★ ()
Ответ на: комментарий от swwwfactory

Потом делаешь ему https://www.kernel.org/pub/software/scm/git/docs/howto/using-merge-subtree.html и получаешь рабочее поддерево - т.е. каталог остается как и был, но локальная репа уже знает, что это поддерево.

каталог остается как и был, но локальная репа уже знает, что это поддерево

Это мне и нужно. Но, в том-то и беда, что получив монолит, который включает в себя каталог с подпроектом просто выделить каталог с подпроектом в дерево нельзя (или я не могу понять, как).

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

Jurik_Phys ★★★★★ ()
Ответ на: комментарий от Jurik_Phys

Это мне и нужно. Но, в том-то и беда, что получив монолит, который включает в себя каталог с подпроектом просто выделить каталог с подпроектом в дерево нельзя (или я не могу понять, как).

Как это нельзя??? Наоборот можно! В этом главный смыл поддерева subtree.

Вы что-то недопонимаете и/или неправильно действуете.

УМВР

swwwfactory ★★ ()
Последнее исправление: swwwfactory (всего исправлений: 1)
Ответ на: комментарий от swwwfactory

УМВР

Спасибо добрый человек!!! Похоже, что у меня тоже заработало:

1. Отделяем каталог в отдельную подветку:

git subtree merge --prefix=cite --branch cite_branch
2. Добавляем удалённый репозиторий подпроекта
git remote add cite_serv user@server:/opt/git/cite
3. Получаем информацию с cite_serv
git fetch cite_serv
4. Привязываем уже существующую ветку к удаленной
git branch --set-upstream cite_branch cite_serv/master
5. Profit.

Jurik_Phys ★★★★★ ()
Последнее исправление: Jurik_Phys (всего исправлений: 1)
Ответ на: комментарий от Jurik_Phys

с просветлением :)

только я делал проще из команд плагина использовал только push

Обязательно задокументируй, а то можно забыть легко т.к. нюансов немало.

И помнить всегда, что мастер-ветка особая - лучше ее не трогать а только туда подливать с других веток и то аккуратно.

с удаленными ветками работать чревато - это централизация и глобализм.

swwwfactory ★★ ()
Последнее исправление: swwwfactory (всего исправлений: 3)
Ответ на: комментарий от swwwfactory

Идею и про мастер и про удалённые ветки прочуствовал. Такие наюансы я всегда записываю.

P.S. пункт 1 (опечатка) merge == split

Jurik_Phys ★★★★★ ()
Последнее исправление: Jurik_Phys (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.