$ git submodule update fataclass="underline" reference isn’t a tree: 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 Unable to checkout '6c5e70b984a60b3cecd395edd5ba7575bf58e0' in submodule path 'rack'
Вам надо посмотреть, кто последним менял подмодуль:
$ git log -1 rack commit 85a3eee996800fcfa91e2119372dd4172bf76678 Author: Scott Chacon <schacon@gmail.com> Date: Thu Apr 9 09:19:14 2009 -0700 added a submodule reference I will never make public. hahahahaha!
А затем отправить этому человеку письмо со своими возмущениями.
Суперпроекты
Иногда, разработчики хотят объединить подкаталоги крупного проекта в нечто связанное, в зависимости от того, в какой они команде. Это типично для людей перешедших с CVS или Subversion, где они определяли модуль или набор подкаталогов, и они хотят сохранить данный тип рабочего процесса.
Хороший способ сделать такое в Git — это сделать каждый из подкаталогов отдельным Git-репозиторием, и создать Git-репозиторий для суперпроекта, который будет содержать несколько подмодулей. Преимущество такого подхода в том, что вы можете более гибко определять отношения между проектами при помощи меток и ветвей в суперпроектах.
Проблемы с подмодулями
Однако, использование подмодулей не обходится без загвоздок. Во-первых, вы должны быть относительно осторожны работая в каталоге подмодуля. Когда вы выполняете команду git submodule update, она возвращает определённую версию проекта, но не внутри ветви. Это называется состоянием с отделённым HEAD (detached HEAD) — это означает, что файл HEAD указывает на конкретный коммит, а не на символическую ссылку. Проблема в том, что вы, скорее всего, не хотите работать в окружении с отделённым HEAD, потому что так легко потерять изменения. Если вы сделаете первоначальный submodule update, сделаете коммит в каталоге подмодуля не создавая ветки для работы в ней, и затем вновь выполните git submodule update из основного проекта, без создания коммита в суперпроекте, Git затрёт ваши изменения без предупреждения. Технически вы не потеряете проделанную работу, но у вас не будет ветки указывающей на неё, так что будет несколько сложновато её восстановить.
Для предотвращения этой проблемы, создавайте ветвь, когда работаете в каталоге подмодуля с использованием команды git checkout -b work или какой-нибудь аналогичной. Когда вы сделаете обновление подмодуля командой submodule update в следующий раз, она все же откатит вашу работу, но, по крайней мере, у вас будет указатель для возврата назад.
Переключение веток с подмодулями в них также может быть мудрёным. Если вы создадите новую ветку, добавите туда подмодуль и затем переключитесь обратно, туда где не было этого подмодуля, вы все ещё будете иметь каталог подмодуля в виде неотслеживаемого каталога:
$ git checkout -b rack Switched to a new branch "rack" $ git submodule add git@github.com:schacon/rack.git rack Initialized empty Git repository in /opt/myproj/rack/.git/ ... Receiving objects: 100% (3184/3184), 677.42 KiB | 34 KiB/s, done. Resolving deltas: 100% (1952/1952), done. $ git commit -am 'added rack submodule' [rack cc49a69] added rack submodule 2 files changed, 4 insertions(+), 0 deletions(-) create mode 100644 .gitmodules create mode 160000 rack $ git checkout master Switched to branch "master" $ git status # On branch master # Untracked files: # (use "git add <file>..." to include in what will be committed) # # rack/
Вы будете вынуждены либо переместить каталог подмодуля в другое место, либо удалить его. В случае удаления вам потребуется клонировать его снова при переключении обратно, и тогда вы можете потерять локальные изменения или ветки, которые не были отправлены в основной репозиторий.
Последняя проблема, которая возникает у многих, и о которой стоит предостеречь, возникает при переходе от подкаталогов к подмодулям. Если вы держали некоторые файлы под версионным контролем в своём проекте, а сейчас хотите перенести их в подмодуль, вам надо быть осторожным, иначе Git разозлится на вас. Допустим, вы держите файлы rack в подкаталоге проекта, и вы хотите вынести его в подмодуль. Если вы просто удалите подкаталог и затем выполните submodule add, Git наорёт на вас:
$ rm -Rf rack/ $ git submodule add git@github.com:schacon/rack.git rack 'rack' already exists in the index
Вначале вам следует убрать каталог rack из индекса (убрать из под версионного контроля). Потом можете добавить подмодуль:
$ git rm -r rack $ git submodule add git@github.com:schacon/rack.git rack Initialized empty Git repository in /opt/testsub/rack/.git/ remote: Counting objects: 3184, done. remote: Compressing objects: 100% (1465/1465), done. remote: Total 3184 (delta 1952), reused 2770 (delta 1675) Receiving objects: 100% (3184/3184), 677.42 KiB | 88 KiB/s, done. Resolving deltas: 100% (1952/1952), done.
Теперь, предположим, вы сделали это в ветке. Если вы попытаетесь переключиться обратно на ту ветку, где эти файлы всё еще в актуальном дереве, а не в подмодуле, то вы получите такую ошибку:
$ git checkout master error: Untracked working tree file 'rack/AUTHORS' would be overwritten by merge.
Вам следует переместить каталог подмодуля rack, перед тем, как вы сможете переключиться на ветку, которая не содержит его: