Нужна помощь с толкнулся с такой вещью и уже второй раз теряю свои результаты работы с кодом. Вернее результаты ни куда не делись, комит был, только его теперь фиг достанешь в том виде что он был. Короче меня пока не интересуют субмодули и какая от них польза, мне нужно всего лишь их как-то нейтрализовать, что бы они не мешали работать с репозиторием как с единым целым. Так что если кому не лень объясните на пальцах пожалуйста. Вот я склонировал в vs репо, создал новую ветвь от ветки разработки типа task-10, но субмодули при этом остаются в detach состоянии. Что нужно с ними сделать, что бы можно было все закомитить, сделать пуш, а результаты ни куда не делить?
Здравствуйте, Qulac, Вы писали:
Q>Нужна помощь с толкнулся с такой вещью и уже второй раз теряю свои результаты работы с кодом. Вернее результаты ни куда не делись, комит был, только его теперь фиг достанешь в том виде что он был. Короче меня пока не интересуют субмодули и какая от них польза, мне нужно всего лишь их как-то нейтрализовать, что бы они не мешали работать с репозиторием как с единым целым. Так что если кому не лень объясните на пальцах пожалуйста. Вот я склонировал в vs репо, создал новую ветвь от ветки разработки типа task-10, но субмодули при этом остаются в detach состоянии. Что нужно с ними сделать, что бы можно было все закомитить, сделать пуш, а результаты ни куда не делить?
сабмодули — это отдельные репозитории, которые вычекиваются в определенном фиксированном коммите, который фиксируется в коммите главного репа. Надо зайти в каждый, который меняешь, сделать там ветку (возможно от мастера, а не от detached commit), на ней менять, ее коммитить и ее пушить. В главном репе тоже ветка, на ней меняешь код главного репа, а новую ревизию сабмодуля фиксируешь просто добавляя папку сабмодуля (git add). Измненеия в сабмодуле от git add не добавляются. Надо иммено что внутри сделать git add, commit, push. А потом в главном git add submodule-dir.
Есть команды-сокращения для работы с сабами, но сначала надо познать принцип.
У меня похожая ситуация. Каким-то образом сабмодули (но не все, а два из четырех, хз, почему) застряли в состоянии detached, хотя по факту этот коммит и есть последний коммит в мастере. Visual Studio со своим multi-repo support отказывается даже делать Pull. Я просто хочу вернуться в главном репо на мастер, и в сабах тоже на мастер, локальных изменений у меня нет, че делать-то?
Ок, зашел в саб репо, сделал git checkout master, потом git pull, git status показывает, что изменений в сабмодуле НЕТ (nothing to commit, etc). Но теперь в главном репо я вижу: modified: my-sub-repo (new commits). Студия показывает это:
Что это значит, черт побери? Изменений у меня нет, я просто запуллил всё что мог со всех реп. Что он понимает под изменениями и что мне с этим делать? Коммитить? Так зачем, я не собираюсь портить основной мастер ничем. Реверт? Так потом опять выползет.
Пробовал git submodule update --init --recursive, так оно мне потом опять повергает сабрепо в detached.
Наверно, остается один проверенный путь — нахрен удалить весь каталог и выкачать всё заново. Но лень, потом специфические конфиги по папкам раскладывать.
----
И вопрос, скорее, в КСВ — почему так? зачем мне эти сложности? Я не хотел ничего другого, кроме как выкачать репо с сабрепами, создать ветки для фичи, сделать фичу, закоммитить и вернуться на мастер. Почему для этого необходимо изучать всю подноготную гита, всякие рефы, детачед коммиты? Ну я могу понять, возможно, для разработки ядра линукс такой трэш, где есть сеть независимых репозиториев, где разработка ведется peer-to-peer, а потом еще патчи друг другу шлют — это то что доктор прописал. Но зачем это всё обычным разрабам, кто их всех подсадил на это чудовище?
Здравствуйте, dmitry_npi, Вы писали:
— _>Но зачем это всё обычным разрабам, кто их всех подсадил на это чудовище?
Я тоже замучался выкачивать qt с подмодулями с помощью git. Потом плюнул и создал один собственный коммит в стиле монорепозитория.
Есть альтернативные способы работы, вроде использования веток. Только вот стиль работы с git выбирают сами разработчики. Если они выбрали подмодули, то для нормальных людей всё становится крайне неудобным.
Проблема не только в выкачивании, какой-нибудь gitweb потом плохо это интерпретирует.
Здравствуйте, andrey.desman, Вы писали:
AD>сабмодули — это отдельные репозитории, которые вычекиваются в определенном фиксированном коммите, который фиксируется в коммите главного репа. Надо зайти в каждый, который меняешь, сделать там ветку (возможно от мастера, а не от detached commit), на ней менять, ее коммитить и ее пушить. В главном репе тоже ветка, на ней меняешь код главного репа, а новую ревизию сабмодуля фиксируешь просто добавляя папку сабмодуля (git add). Измненеия в сабмодуле от git add не добавляются. Надо иммено что внутри сделать git add, commit, push. А потом в главном git add submodule-dir. AD>Есть команды-сокращения для работы с сабами, но сначала надо познать принцип.
А можно как-то сделать, чтобы сабмодуль сам устанавливался например в мастер (или на другую какую-то ветку) и при всех обновлениях не менял состояния? А то задолбало, постоянно на оторванную башку натыкаюсь
П>А можно как-то сделать, чтобы сабмодуль сам устанавливался например в мастер (или на другую какую-то ветку) и при всех обновлениях не менял состояния? А то задолбало, постоянно на оторванную башку натыкаюсь
Взаимоисключающие параграфы. Как это стоять на мастере и не менять состояния?
Ну ладно, не важно. Сабмодули всегда ставятся на конкретный коммит, как раз чтобы не менять состояния, поэтому они всегда вычекиваются в detached head.
Здравствуйте, dmitry_npi, Вы писали:
_>У меня похожая ситуация. Каким-то образом сабмодули (но не все, а два из четырех, хз, почему) застряли в состоянии detached, хотя по факту этот коммит и есть последний коммит в мастере. Visual Studio со своим multi-repo support отказывается даже делать Pull. Я просто хочу вернуться в главном репо на мастер, и в сабах тоже на мастер, локальных изменений у меня нет, че делать-то?
Ну смотри, каждый коммит в главном репе ссылается на какой-то конкретный коммит в сабмодуле.
Нет такого, что ссылка идет на ветку мастер сабмодуля, чтобы каждый конкретный коммит главного репа ссылался на определенную версию, а не как повезет.
_>Ок, зашел в саб репо, сделал git checkout master, потом git pull, git status показывает, что изменений в сабмодуле НЕТ (nothing to commit, etc). Но теперь в главном репо я вижу: modified: my-sub-repo (new commits). Студия показывает это:
Да, теперь у тебя сабмодуль в твоей ветке все еще ссылается на старый коммит, а вычекнут другой коммит. Очевидно, ты поменял ссылку. (Есть изменения в главном репе, а не в сабмодуле).
_>Что это значит, черт побери? Изменений у меня нет, я просто запуллил всё что мог со всех реп. Что он понимает под изменениями и что мне с этим делать? Коммитить? Так зачем, я не собираюсь портить основной мастер ничем. Реверт? Так потом опять выползет.
Если хочешь зафиксировать в своей ветке новую версию сабмодуля, то git add submodule-path / git commit. Иначе ну просто игнорь. Ну а что. Если файл меняешь, тебе же тоже изменения покажет.
_>Пробовал git submodule update --init --recursive, так оно мне потом опять повергает сабрепо в detached.
Конечно, он вычекивает конкретный коммит, на который ссылается твоя ветка. И оно оказывается в detached.
_>Наверно, остается один проверенный путь — нахрен удалить весь каталог и выкачать всё заново. Но лень, потом специфические конфиги по папкам раскладывать.
Ничего не поменяется.
_>
_>---- _>И вопрос, скорее, в КСВ — почему так? зачем мне эти сложности? Я не хотел ничего другого, кроме как выкачать репо с сабрепами, создать ветки для фичи, сделать фичу, закоммитить и вернуться на мастер. Почему для этого необходимо изучать всю подноготную гита, всякие рефы, детачед коммиты? Ну я могу понять, возможно, для разработки ядра линукс такой трэш, где есть сеть независимых репозиториев, где разработка ведется peer-to-peer, а потом еще патчи друг другу шлют — это то что доктор прописал. Но зачем это всё обычным разрабам, кто их всех подсадил на это чудовище?
Здравствуйте, andrey.desman, Вы писали:
П>>А можно как-то сделать, чтобы сабмодуль сам устанавливался например в мастер (или на другую какую-то ветку) и при всех обновлениях не менял состояния? А то задолбало, постоянно на оторванную башку натыкаюсь
AD>Взаимоисключающие параграфы. Как это стоять на мастере и не менять состояния?
Да я наверное не очень что-то понимаю. Решил я попробовать с ними пожить. Есть у меня либа, я её в проект присунул как сабмодуль. Либа активно развивается вместе с проектом, я особо не заморачиваюсь с ветками мержреквестами и пр, тупо в мастер добавляю изменения, и пушу в ремоут. Да, при обновлении текущая ветка не меняется, если я уже сделал чекаут, тут я соврал, но в новое место когда клонируешь, надо чекаут на ветку сделать, я пару раз накололся.
Состояние не менять — в том плане, что у меня выбрана ветка мастер, и я хочу иметь там самые последние изменения. Ну то есть да, HEAD будет двигаться.
AD>Ну ладно, не важно. Сабмодули всегда ставятся на конкретный коммит, как раз чтобы не менять состояния, поэтому они всегда вычекиваются в detached head.
Вот тут не очень понятно, а на какой коммит они ставятся? В .gitmodules вроде нет по дефолту информации о коммите, значит, гит сам выбирает какой коммит мне подсунуть? Самый последний?
А если я в подмодуле завёл ветки, сделал ветку develop, куда коммичу даже не собирающиеся сорцы, чтобы потом доделать, оттестить, и смержить в мастер? Получится, что сабмодуль будет указывать на нерабочий коммит? Но когда я использую либу, я вообще-то хочу чтобы у меня собиралось с ней. Вот тут как-то не очень понятно
Здравствуйте, пффф, Вы писали:
П>Да я наверное не очень что-то понимаю. Решил я попробовать с ними пожить. Есть у меня либа, я её в проект присунул как сабмодуль. Либа активно развивается вместе с проектом, я особо не заморачиваюсь с ветками мержреквестами и пр, тупо в мастер добавляю изменения, и пушу в ремоут. Да, при обновлении текущая ветка не меняется, если я уже сделал чекаут, тут я соврал, но в новое место когда клонируешь, надо чекаут на ветку сделать, я пару раз накололся.
Не понял...
П>Состояние не менять — в том плане, что у меня выбрана ветка мастер, и я хочу иметь там самые последние изменения. Ну то есть да, HEAD будет двигаться.
Так не получится, двигать надо вручную. А что если захочешь собрать старую версию, а она тебе вычекнет несовместимый новый сабмодуль?
AD>>Ну ладно, не важно. Сабмодули всегда ставятся на конкретный коммит, как раз чтобы не менять состояния, поэтому они всегда вычекиваются в detached head.
П>Вот тут не очень понятно, а на какой коммит они ставятся? В .gitmodules вроде нет по дефолту информации о коммите, значит, гит сам выбирает какой коммит мне подсунуть? Самый последний?
Нет, который был последним закомичен в этой ветке.
А хранит внутри дерева https://stackoverflow.com/questions/5033441/where-does-git-store-the-sha1-of-the-commit-for-a-submodule
Представь, что сабмодуль — это софтлинк, который ссылается на конкретное имя mysuperlib-0.0.3. В разных ветках, в разных коммитах эта ссылка может быть разной. Она автомагически не будет меняться на другие имена.
Чтобы обновить версию сабмодуля в ветке, ты идешь в сабмодуль, вычекиваешь нужную версию (можно и мастер, не важно, азпоминаться бущет именно коммит). Потом идешь обратно в главный реп, делаешь git add submodule-path, git commit. Всё, теперь в твоей ветке новая версия. Мержишь свою ветку в мастер главного репа, и оппа, теперь в мастере новая версия.
П>А если я в подмодуле завёл ветки, сделал ветку develop, куда коммичу даже не собирающиеся сорцы, чтобы потом доделать, оттестить, и смержить в мастер? Получится, что сабмодуль будет указывать на нерабочий коммит? Но когда я использую либу, я вообще-то хочу чтобы у меня собиралось с ней. Вот тут как-то не очень понятно
Делаешь ветку в главном репе, делаешь ветку в сабмодуле (можешь их даже одинаково назвать). В ветку главного репа вычекиваешь в сабмодуле свою ветку сабмодуля, делаешь git add submodule-path, git commit. Можно пушить и делать автобилд. Другие ветки и мастер это не затронет.
Здравствуйте, andrey.desman, Вы писали:
П>>Да я наверное не очень что-то понимаю. Решил я попробовать с ними пожить. Есть у меня либа, я её в проект присунул как сабмодуль. Либа активно развивается вместе с проектом, я особо не заморачиваюсь с ветками мержреквестами и пр, тупо в мастер добавляю изменения, и пушу в ремоут. Да, при обновлении текущая ветка не меняется, если я уже сделал чекаут, тут я соврал, но в новое место когда клонируешь, надо чекаут на ветку сделать, я пару раз накололся.
AD>Не понял...
Хм, а что именно я непонятно изложил? Попробую попонятнее, только я пока не пойму, что тебе не понятно
П>>Состояние не менять — в том плане, что у меня выбрана ветка мастер, и я хочу иметь там самые последние изменения. Ну то есть да, HEAD будет двигаться.
AD>Так не получится, двигать надо вручную. А что если захочешь собрать старую версию, а она тебе вычекнет несовместимый новый сабмодуль?
AD>>>Ну ладно, не важно. Сабмодули всегда ставятся на конкретный коммит, как раз чтобы не менять состояния, поэтому они всегда вычекиваются в detached head.
П>>Вот тут не очень понятно, а на какой коммит они ставятся? В .gitmodules вроде нет по дефолту информации о коммите, значит, гит сам выбирает какой коммит мне подсунуть? Самый последний? AD>Нет, который был последним закомичен в этой ветке.
В какой ветке?
AD>Представь, что сабмодуль — это софтлинк, который ссылается на конкретное имя mysuperlib-0.0.3. В разных ветках, в разных коммитах эта ссылка может быть разной. Она автомагически не будет меняться на другие имена. AD>Чтобы обновить версию сабмодуля в ветке, ты идешь в сабмодуль, вычекиваешь нужную версию (можно и мастер, не важно, азпоминаться бущет именно коммит). Потом идешь обратно в главный реп, делаешь git add submodule-path, git commit. Всё, теперь в твоей ветке новая версия. Мержишь свою ветку в мастер главного репа, и оппа, теперь в мастере новая версия.
П>>Вот тут не очень понятно, а на какой коммит они ставятся? В .gitmodules вроде нет по дефолту информации о коммите, значит, гит сам выбирает какой коммит мне подсунуть? Самый последний? AD>Нет, который был последним закомичен в этой ветке.
Как модифицируется это поведение в зависимости от того, указана ли опция submodule.<name>.branch ?
* "git submodule" started learning a new mode to integrate with the
tip of the remote branch (as opposed to integrating with the commit
recorded in the superproject's gitlink).
Здравствуйте, m2user, Вы писали:
П>>>Вот тут не очень понятно, а на какой коммит они ставятся? В .gitmodules вроде нет по дефолту информации о коммите, значит, гит сам выбирает какой коммит мне подсунуть? Самый последний? AD>>Нет, который был последним закомичен в этой ветке.
M>Как модифицируется это поведение в зависимости от того, указана ли опция submodule.<name>.branch ?
Да никак. Она позволяет тебе сделать git submodule update --remote, которая тянет и вычекивает с ремоута ветку submodule.<name>.branch. Это просто для удобства, сути дела не меняет.
То есть, это облегчает обновление на последний master/develop/trunk сабмодуля. Но потом тебе все равно надо сделать git add и git commit в главном репе, чтобы актуализировать новый коммит сабмодуля. И в следующий раз, когда сделаешь git submodule update, всё равно получишь detached head.
M>Из https://github.com/git/git/blob/master/Documentation/RelNotes/1.8.2.txt M>
M> * "git submodule" started learning a new mode to integrate with the
M> tip of the remote branch (as opposed to integrating with the commit
M> recorded in the superproject's gitlink).
Здравствуйте, пффф, Вы писали:
П>>>Да я наверное не очень что-то понимаю. Решил я попробовать с ними пожить. Есть у меня либа, я её в проект присунул как сабмодуль. Либа активно развивается вместе с проектом, я особо не заморачиваюсь с ветками мержреквестами и пр, тупо в мастер добавляю изменения, и пушу в ремоут. Да, при обновлении текущая ветка не меняется, если я уже сделал чекаут, тут я соврал, но в новое место когда клонируешь, надо чекаут на ветку сделать, я пару раз накололся. AD>>Не понял... П>Хм, а что именно я непонятно изложил? Попробую попонятнее, только я пока не пойму, что тебе не понятно
Да не понятно, кто на ком стоял. В чей мастер пушатся изменения и чья текущая ветка не меняется.
П>А, кажись я понял. Я после git pull репы делаю П>
Ага, это тебе вычекнет последний "мастер" твоего сабмодуля (merge тут лишний). Но это будет локально у тебя, мастере твоего главного проекта хер знает что вычекнется если ты периодически не обновляешь ссылку на сабмодуль.
То есть, нормальные люди для нормального чекаута будут делать git submodule update --init и получат фигу.
По сути у тебя нет нормальной истории, потому как нет связей между главным репом и сабмодулем.
П>>>Вот тут не очень понятно, а на какой коммит они ставятся? В .gitmodules вроде нет по дефолту информации о коммите, значит, гит сам выбирает какой коммит мне подсунуть? Самый последний? AD>>Нет, который был последним закомичен в этой ветке. П>В какой ветке?
В ветке главного проекта, в любой (мастер — это тоже ветка).
Здравствуйте, andrey.desman, Вы писали:
П>>>>Да я наверное не очень что-то понимаю. Решил я попробовать с ними пожить. Есть у меня либа, я её в проект присунул как сабмодуль. Либа активно развивается вместе с проектом, я особо не заморачиваюсь с ветками мержреквестами и пр, тупо в мастер добавляю изменения, и пушу в ремоут. Да, при обновлении текущая ветка не меняется, если я уже сделал чекаут, тут я соврал, но в новое место когда клонируешь, надо чекаут на ветку сделать, я пару раз накололся. AD>>>Не понял... П>>Хм, а что именно я непонятно изложил? Попробую попонятнее, только я пока не пойму, что тебе не понятно
AD>Да не понятно, кто на ком стоял. В чей мастер пушатся изменения и чья текущая ветка не меняется.
В мастер сабмодуля добавляю изменения, коммичу, и пушу
П>>А, кажись я понял. Я после git pull репы делаю П>>
AD>Ага, это тебе вычекнет последний "мастер" твоего сабмодуля (merge тут лишний). Но это будет локально у тебя, мастере твоего главного проекта хер знает что вычекнется если ты периодически не обновляешь ссылку на сабмодуль. AD>То есть, нормальные люди для нормального чекаута будут делать git submodule update --init и получат фигу. AD>По сути у тебя нет нормальной истории, потому как нет связей между главным репом и сабмодулем.
Похоже ссылка обновляется, потому что я когда коммичу изменения в сабмодуле, то в основном проекте он становится модифицированным и фиксируется при следующем коммите
AD>В ветке главного проекта, в любой (мастер — это тоже ветка).
Ясно. А что выбирается, когда я только добавил сабмодуль? master/main?
Здравствуйте, пффф, Вы писали:
AD>>По сути у тебя нет нормальной истории, потому как нет связей между главным репом и сабмодулем.
П>Похоже ссылка обновляется, потому что я когда коммичу изменения в сабмодуле, то в основном проекте он становится модифицированным и фиксируется при следующем коммите
А, ну да. Если в основном ты делаешь git add -u или явно git add submodule-path, то коммит зафиксируется.
AD>>В ветке главного проекта, в любой (мастер — это тоже ветка). П>Ясно. А что выбирается, когда я только добавил сабмодуль? master/main?
В смысле совсем новый? Не каждый день я сабмодули добавляю... Что вычекнуто, то и добавляется. По идее ремотный HEAD
Здравствуйте, andrey.desman, Вы писали:
AD>>>По сути у тебя нет нормальной истории, потому как нет связей между главным репом и сабмодулем.
П>>Похоже ссылка обновляется, потому что я когда коммичу изменения в сабмодуле, то в основном проекте он становится модифицированным и фиксируется при следующем коммите
AD>А, ну да. Если в основном ты делаешь git add -u или явно git add submodule-path, то коммит зафиксируется.
Так я так не делаю. Может, конечно, за меня это делает тортилка, посмотрю внимательнее при случае, что она делает
AD>>>В ветке главного проекта, в любой (мастер — это тоже ветка). П>>Ясно. А что выбирается, когда я только добавил сабмодуль? master/main?
AD>В смысле совсем новый? Не каждый день я сабмодули добавляю... Что вычекнуто, то и добавляется. По идее ремотный HEAD
Ну, хоть раз в год. В смысле, что вычекнуто? HEAD — он один на всех, или у веток свои?
AD>>>>В ветке главного проекта, в любой (мастер — это тоже ветка). П>>>Ясно. А что выбирается, когда я только добавил сабмодуль? master/main? AD>>В смысле совсем новый? Не каждый день я сабмодули добавляю... Что вычекнуто, то и добавляется. По идее ремотный HEAD П>Ну, хоть раз в год. В смысле, что вычекнуто? HEAD — он один на всех, или у веток свои?
origin/HEAD — самый свежий коммит на главной ветке репозитория, название ветки может быть всякое. Это то же, что ты получишь, когда сделаешь git clone.
Выглядит так, что поведение несколько переусложнено.
Т.е. то, что конкрентная ревизия проекта связана с конкрентной ревизией зависимости, это конечно правильно.
Но зачастую избыточно.
Если все эти проекты разрабатываются внутри одной организации (т.е. зависимости не внешняя), то обычно достаточно связи на уровне веток (stable — stable, dev — dev)/
Т.е. если я хочу на билд-сервере (или на машине разработчика) собирать dev-ветку проекта всегда с последней версией dev-ветки субмодуля, то как это организовать?
Здравствуйте, m2user, Вы писали:
M>Выглядит так, что поведение несколько переусложнено. M>Т.е. то, что конкрентная ревизия проекта связана с конкрентной ревизией зависимости, это конечно правильно. M>Но зачастую избыточно. M>Если все эти проекты разрабатываются внутри одной организации (т.е. зависимости не внешняя), то обычно достаточно связи на уровне веток (stable — stable, dev — dev)/
Даже так не очень. Это вот пффф выше, который сам сабмодуль пилит, и тут же в мастер подливает, ему ок.
А возьми более-менее корпорат, когда какой-то модуль разрабатывает другая команда, периодически вносит туда баги и/или ломающие изменения и/или добавляют зависимости, которые у тебя не настроены, то....
M>Т.е. если я хочу на билд-сервере (или на машине разработчика) собирать dev-ветку проекта всегда с последней версией dev-ветки субмодуля, то как это организовать?
Это зависит от CI системы. Обычно есть возможность управлять процессом вычекивания и задавать свои команды для этого.
На машине локально git clone --recurse-submodules --remote-submodules, на апдейт git pull && git submodule update --remote