Невозможно добавить папку в git repo - PullRequest
0 голосов
/ 27 февраля 2019

Я думаю, что эта проблема уже обсуждалась в рамках этого вопроса:

Рекурсивно добавить всю папку в хранилище

Однако я все еще не могу добавить некоторые папки вхранилище git и мне нужна помощь.

$ git status
...
# modified:   folder_to_add1 (modified content, untracked content)
# modified:   folder_to_add2 (modified content, untracked content)

Эти папки изначально принадлежали другому хранилищу git, поэтому я вошел в папки и удалил папку .git внутри.

Затем я запустил:

$ git add folder_to_add1
$ git add folder_to_add2
$ git status 
# On branch master
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#   (commit or discard the untracked or modified content in submodules)
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       ../filestore/
#       ../../stdout
no changes added to commit (use "git add" and/or "git commit -a")

Ни одна из folder_to_add1 и folder_to_add2 не может быть зафиксирована.

В моем репозитории нет файла .gitignore.

Что еще можно попробовать?Спасибо.


Я постараюсь добавить дополнительную информацию относительно моего исходного поста, который закончился прямо перед предыдущей строкой.Я буду признателен за ваши комментарии по поводу того, что «это» считается верной войной для дальнейшего уточнения моего первоначального вопроса. Я полностью новичок здесь.

Уважаемый Торек, спасибо за ваш очень подробный ответ.Думаю, мне придется очень внимательно прочитать его, чтобы понять тонкости, связанные с концепцией субмодулей.Я полагаю, что подмодули очень похожи на «svn externals», с которыми я более знаком.

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

Я уверен, что ваш ответ где-то говорит мне, почему это происходит, но факт в том, что мне нужно скопировать мой проект с одного ПК на другой, и с помощью git сделать это, эти папки на самом деле невключается в индекс с помощью "git add" независимо от того, есть ли в них подпапка .git или нет.

Файл ".gitmodules", по-видимому, не существует.После запуска:

$ find . -name .gitmodules -print 

в основной папке проекта я не получаю результатов.

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

$ cp -r myproject /home/myusername/newproject
$ cd /home/myusername/newproject/folder_to_add1
$ rm -r .git
$ cd ../folder_to_add2
$ rm -r .git
$ cd /home/myusername/newproject
$ git init
$ git add .
$ git commit -m "Adding all existing files to the new repository"

Но я думаю, что теряю всю историю изменений файлов, делая это таким образом.

1 Ответ

0 голосов
/ 27 февраля 2019

Всякий раз, когда вы видите:

modified: some-name (modified content)

в git status выводе, это означает, что ваш Git-репозиторий считает, что каталог с именем some-name является частью некоторого другого Git репозиторий.(Обратите внимание, что здесь имя подкаталога / папки, some-name в этом примере, не заканчивается косой чертой.)

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

Это повторяется: этот подкаталог / папка действительно был каким-то другимGit репозиторий раньше.Это может или не может все еще быть вторым хранилищем.Более того, ваш собственный Git-репозиторий каким-то образом уже записал присутствие другого Git. Если бы ваш Git-репозиторий не записал это, вы бы увидели:

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        subgit/

Вместо этого,тем не менее, вы видите:

Changes not staged for commit:
...
        modified:   subgit (modified content)

Итак, тот факт, что ваш вывод Git репозитория git status говорит о modified content или untracked content означает ваш репозиторий вполне уверен , что этот подкаталог является некоторым другим хранилищем.Ваш репозиторий сообщает об относительном состоянии другого репозитория.

Вы можете получить другую подсказку по этому поводу, если используете git status -uall или git status --untracked-files=all (это означает то же самое, -u - это сокращение от --untracked-files=): если ваш Git не считает, что подкаталог содержит другое хранилище Git, он заглянет внутрь подкаталога и сообщит вам о каждом файле в каталоге.Если ваш Git убежден, что подкаталог является собственным Git-репозиторием, он не будет заглядывать в него и сообщать о каждом файле, но ваш Git также не скажет «измененный контент» или ««неотслеживаемый контент» вот так.

Что с этим делать, зависит от того, что вы хотите, чтобы произошло в конце

Во-первых, нам нужно поговорить о подмодулях.

Подмодули

Git имеет концепцию под названием submodules .Некоторые люди называют их sob-modules , потому что они заставляют программистов плакать.Essentially Подмодуль по существу означает: Я говорю моему Git записывать информацию о другом хранилище Git.

Теперь подумайте о том, как вы клонируете хранилище Git.Это с одной простой командой: git clone <em>url name</em>, или, может быть, даже просто git clone <em>url</em> с результирующим клоном, идущим в имя каталога / папки на основе URL.(При указании аргумента name выбирается имя каталога / папки вместо того, чтобы указывать URL-адрес.)

Итак, если ваш репозиторий - который мы назовем суперпроектом , поскольку он контролирует некоторые суб-Gits - будет ссылаться на какой-то другой репозиторий, то, что нужно вашему Git:

  • URL, который он должен клонировать
  • имя каталога / папки, которое следует использовать при клонировании

Эти два фрагмента информации в собственном подмодуле хранятся в файле с именем .gitmodulesв верхнем уровне суперпроекта.

Этот .gitmodules файл необходим для создания нового клона суперпроекта.Это нужно только в новом клоне!Если у вас уже есть клон, который работает и управляет своими вложенными репозиториями, содержимое .gitmodules файла больше не имеет значения.

С .gitmodules или без негоВаш Git также записывает больше о подмодуле

Каждый репозиторий Git состоит из трех частей:

  1. Git хранит сам репозиторий .git.Он содержит несколько баз данных, которые вам не нужно искать в себе.
  2. Git also хранит то, что называется, по-разному, index , staging area или cache .То, как он называется, зависит от того, кто или какая часть Git выполняет вызов, но все три являются именами для одной и той же вещи.
  3. Git предоставляет вам рабочее дерево .Файлы внутри вашего Git-репозитория хранятся в специальном, замороженном, сжатом формате Git-only.Они не могут быть изменены .Они могут быть добавлены к , как при добавлении большего количества версий файлов, но все они являются просто историческими записями.Поэтому вам нужно место, где вы можете получить в этих файлах, в обычном не-Git формате, и работать с ними и вместе с ними.Это ваше рабочее дерево .

Рабочее дерево часто является частью Git, с которой вы работаете больше всего - ну, естественно, оно прямо в названии, не так ли?не так ли?И все же Git на самом деле не использует рабочее дерево, в некотором смысле.Он помещает в него файлы, которые вы можете использовать;и когда вы запускаете git add, ваш Git копирует файлы из рабочего дерева в эту вещь в # 2 выше: они входят в index .

Когда Git делает новый коммит, Git использует файлы, которые есть в index .Именно наличие файла в индексе делает файл отслеживаемым в первую очередь.Когда Git заполнит ваше рабочее дерево, используя git checkout для извлечения коммита, Git сначала заполняет ваш index .В этом индексе происходит все реальное действие Git: в него включаются существующие коммиты, и из него создаются новые коммиты.Так что на самом деле важен индекс, а не рабочее дерево, по крайней мере, насколько новые коммиты идут.Независимо от того, что вы делаете в рабочем дереве, Git действительно обращает внимание только на индекс. Вот почему вы должны постоянно использовать git add: это копия каждого файла в индекса, который имеет значение для Git.

Короче говоря,ваш индекс содержит то, что войдет в следующий коммит, который вы сделаете .Внутри него есть копия всех ваших файлов в формате «pre-Git-ified», готовом к заморозке навсегда.Вот что делает ваш индекс таким важным.Если вы изменяете файл рабочего дерева, вы должны использовать git add, чтобы скопировать (и Git-ify) файл, чтобы быть готовым к следующему коммиту.

Итак, для Git важны коммиты, идентифицируемый по их большим уродливым хеш-идентификаторам, которые уникальны: никогда не бывает двух разных коммитов с одинаковым хеш-идентификатором, и индекс , который используется для создания новых коммитов.Вы используете рабочее дерево для выполнения своей работы, но затем вы обновляете индекс вашего Git и заставляете свой Git делать новый коммит из него.

Здесь также снова появляются субмодули.Если ваш Git действует как суперпроект, например, наблюдая за каким-то вложенным Git в некоторой папке с именем subgit/, тогда ваш Git запишет их идентификатор хита коммитов Git в вашем индексе!

Подумайте об этом немного.Ваш Git не сохраняет файлы своего Git.Ваш Git знает, что если его Git - Git в вашей папке subgit/ - сохранил некоторые файлы в коммите, то идентификатор хэша коммита хорош forever .Этот простой хэш-идентификатор, каким бы большим и уродливым он ни был, уникальным образом идентифицирует всех этих файлов в их сохраненном навсегда виде .Так что вашему Git не нужно для сохранения файлов.Все, что нужно сделать, это сохранить хеш-код их коммита.

это именно то, что делает ваш суперпроект Git.Вместо сохранения файлов - их файлов - ваш Git просто сохранил свой хэш-идентификатор commit в своем индексе.И затем, поскольку он находится в вашем индексе, он также входит в ваши коммиты. С этого момента каждый новый коммит содержит свой хэш-идентификатор. Если вы хотите записать другой хеш-идентификатор, вы говорите им - другой Git, тот, кто контролируетпапка subgit/ - для переключения на другой хэш-идентификатор коммита или для создания нового коммита;и тогда у вас есть ваша запись Git с хеш-идентификатором в вашем индексе, так что ваш следующий коммит имеет правильный хеш-код подпроекта.

Обратите внимание, что всеэто работает даже без файла .gitmodules. Но если у вас нет файла .gitmodules, этот суперпроект, который контролирует некоторые другие репозитории Git, работает здесь, но вы не сможете легко его клонировать позже.

Теперь вы должны решить: вам нужен субмодуль или нет?

Если вы хотите субмодулей, ну, вы уже там - или хотя бы на полпутитам.Если у вас есть файл .gitmodules, в котором содержится хранилище подпроектов, ваш суперпроект уже записывает правильный URL-адрес и имя для будущих клонов.Если нет, то вам, вероятно, следует создать файл .gitmodules, используя git submodule add.См. Также Как `git submodule add` Существующий подпозиторий? (Это ответ на вопрос о том, как исправить подпроектный репозиторий, который изначально не был правильно добавлен, но вы делаете хотите использовать в качестве правильного подмодуля.)

Итак, вам нужен подмодуль, и он уже есть в .gitmodules

Учитывая, что вы решили, что do хотитечтобы использовать подмодуль и чтобы все было правильно записано, вам нужно сделать , а не git add subgit.Как вы уже видели, это ничего не делает!

Вместо этого вам нужно начать новый сеанс, введя cd в подмодуль, или открыть новое окно, в котором выначать работать в субмодуле, или как угодно.Теперь вы в новом и другом хранилище!Но, о-о, вы, вероятно, находитесь в режиме detached HEAD .

Все нормально: вы можете выбрать работу в этом режиме.Или вы можете запустить git checkout <em>somebranch</em>, чтобы войти в какую-то ветку, или git checkout -b <em>newbranch</em>, чтобы создать новую ветку при текущем коммите.Вы должны делать все, что имеет смысл для этого Git-репозитория.

Теперь, когда вы находитесь в этом новом и другом репозитории, вы можете работать как обычно с вашим рабочим деревом.Как только все файлы будут расположены так, как вы хотите, в ветке, которую вы хотите, вы git add изменили файлы и / или git add не отслеживали файлы, чтобы скопировать их в индекс.Вы тогда git commit результат.И теперь у вас есть новый коммит, и вы можете git push это или что-то еще, что вы делаете с этими коммитами в этом хранилище.

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

Теперь все, что вам нужно сделать в суперпроекте, - запустить git add <em>subproject</em>.Если подпроект называется 1267, просто 1268.Это копирует идентификатор хеша под-репозитория в ваш индекс , так что теперь он готов к фиксации.Добавьте все, что вам нравится, и запустите git commit, чтобы создать новый коммит, который навсегда заморозит все содержимое вашего индекса.Это сохранит ваши файлы и хеш-идентификатор коммита вашего подпроекта , все из которых были готовы войти в ваш индекс.

Так что вам не нужен субмодуль илиСубгит вообще

Это оЭто немного сложнее, особенно в очень старых версиях Git.Современный Git делает это намного проще.Итак, здесь я собираюсь передать весь ответ на Как мне удалить подмодуль? Обратите внимание, что большинство ответов, включая этот короткий для современного Git , имеют идею, чтовы также собираетесь удалить все рабочее дерево из под-репозитория.Если вы хотите сохранить рабочее дерево, самый простой способ - просто переместить или скопировать его в другое место. Обязательно сохраните файлы, которые были изменены и / или не отслежены , поскольку они, вероятно, не в не фиксируют в под-хранилище!

...