Как добавить пустой каталог в репозиторий Git? - программирование

Как добавить пустой каталог в репозиторий Git?

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

4b9b3361

Ответ 1

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

# Ignore everything in this directory
*
# Except this file
!.gitignore

Тогда вам не нужно правильно оформлять заказ, как в решении m104.

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

Сделать комментарий @GreenAsJade постоянным:

Я думаю, что стоит отметить, что это решение делает именно то, о чем просил вопрос, но, возможно, не то, что искали многие люди, смотрящие на этот вопрос. Это решение гарантирует, что каталог остается пустым. Там написано: "Я действительно никогда не хочу, чтобы файлы проверялись здесь" В отличие от "У меня пока нет файлов для проверки, но мне нужен каталог здесь, файлы могут появиться позже".

Ответ 2

Вы не можете. См. Git FAQ.

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

Каталоги добавляются автоматически при добавлении в них файлов. Что, каталоги никогда не должны быть добавлены к репозиторию и не отслеживаются самостоятельно.

Вы можете сказать "git add <dir>", и это добавит туда файлы.

Если вам действительно нужен каталог для в выписках вы должны создать файл в нем. .gitignore хорошо работает для эта цель; вы можете оставить его пустым, или введите имена файлов, которые вы Ожидается, что они появятся в каталоге.

Ответ 3

Создайте пустой файл с именем .gitkeep в каталоге и добавьте его.

Ответ 4

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

Ответ 5

touch .keep

В Linux это создает пустой файл с именем .keep. Это имя предпочтительнее, чем .gitkeep, поскольку первое агностическое значение Git, тогда как последнее относится к Git. Во-вторых, как отметил другой пользователь, соглашение о префиксе .git должно быть зарезервировано для файлов и каталогов, которые сам использует Git.

В качестве альтернативы, как указано в другом , каталог может содержать описательный README или README.md файл.

Конечно, это требует, чтобы присутствие файла не вызывало нарушения вашего приложения.

Ответ 6

Зачем нам нужны пустые версионные папки

Перво-наперво:

Пустой каталог не может быть частью дерева в системе управления версиями Git.

Это просто не будет отслеживаться. Но есть сценарии, в которых "управление версиями" пустых каталогов может иметь смысл, например:

  • создание предопределенной структуры папок, делая ее доступной для каждого пользователя/участника репозитория; или, в качестве особого случая, описанного выше, создание папки для временных файлов, таких как каталоги cache/ или logs/, где мы хотим предоставить папку, но .gitignore ее содержимое
  • В связи с вышеизложенным некоторые проекты не будут работать без каких-либо папок (что часто является намеком на плохо спроектированный проект, но это частый сценарий реального мира и, возможно, могут быть, скажем, проблемы с разрешениями, которые необходимо решить).

Некоторые предлагаемые обходные пути

Многие пользователи предлагают:

  1. Поместите файл README или другой файл с некоторым содержимым, чтобы сделать каталог не пустым, или
  2. Создание файла .gitignore с некой "обратной логикой" (т.е. для включения всех файлов), которая, в конце концов, служит той же цели, что и в подходе №1.

Хотя оба решения, безусловно, работают, я считаю их несовместимыми с осмысленным подходом к управлению версиями Git.

  • Почему вы должны поместить поддельные файлы или файлы README, которые, возможно, вам не нужны в вашем проекте?
  • Зачем использовать .gitignore, чтобы делать что-то (хранение файлов), прямо противоположное тому, для чего оно предназначалось (исключая файлы), даже если это возможно?

.gitkeep подход

Используйте пустой файл с именем .gitkeep для принудительного присутствия папки в системе управления версиями.

Хотя это может показаться не такой большой разницей:

  • Вы используете файл, цель которого - сохранить папку. Вы не помещаете туда информацию, которую не хотите помещать.

    Например, вы должны использовать README в качестве README с полезной информацией, а не в качестве предлога для сохранения папки.

    Разделение проблем - это всегда хорошо, и вы все равно можете добавить .gitignore, чтобы игнорировать нежелательные файлы.

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

    • Файл, не связанный с кодом (из-за начальной точки и имени)
    • Файл, явно связанный с Git
    • Его цель (keep) четко сформулирована, последовательна и семантически противоположна по своему значению игнорированию

Принятие

Я видел подход .gitkeep, принятый очень важными средами, такими как Laravel, Angular-CLI.

Ответ 7

Как описано в других ответах, Git не может представлять пустые каталоги в своей промежуточной области. (См. Git FAQ.) Однако, если для ваших целей каталог достаточно пуст, если он содержит только файл .gitignore, то вы можете создавать файлы .gitignore в пустых каталогах только через:

find . -type d -empty -exec touch {}/.gitignore \;

Ответ 8

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

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

Ответ 9

Способ создания папки журнала Ruby on Rails:

mkdir log && touch log/.gitkeep && git add log/.gitkeep

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

Логфайлы могут быть сохранены путем выпуска,

echo log/dev.log >> .gitignore

но вы, наверное, это знали.

Ответ 10

Git не отслеживает пустые каталоги. Дополнительную информацию см. В Git FAQ. Предлагаемое обходное решение - поместить файл .gitignore в пустой каталог. Мне не нравится это решение, потому что .gitignore "скрыт" по соглашению Unix. Также нет объяснений, почему каталоги пусты.

Я предлагаю поместить файл README в пустой каталог, объясняя, почему каталог пуст и почему его нужно отслеживать в Git. С файлом README на месте, насколько это касается Git, каталог больше не пуст.

Реальный вопрос, почему вам нужен пустой каталог в git? Обычно у вас есть сценарий сборки, который может создать пустой каталог перед компиляцией/запуском. Если нет, то сделайте это. Это гораздо лучшее решение, чем размещение пустых каталогов в git.

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


Чтобы перечислить каждый пустой каталог, используйте следующую команду:

find -name .git -prune -o -type d -empty -print

Чтобы создать README заполнителя в каждом пустом каталоге:

find -name .git -prune -o -type d -empty -exec sh -c \
  "echo this directory needs to be empty because reasons > {}/README.emptydir" \;

Чтобы игнорировать все в каталоге, кроме файла README, поместите следующие строки в ваш .gitignore:

path/to/emptydir/*
!path/to/emptydir/README.emptydir
path/to/otheremptydir/*
!path/to/otheremptydir/README.emptydir

Кроме того, вы можете просто исключить каждый файл README из игнорирования:

path/to/emptydir/*
path/to/otheremptydir/*
!README.emptydir

Чтобы перечислить каждый README после того, как они уже созданы:

find -name README.emptydir

Ответ 11

ПРЕДУПРЕЖДЕНИЕ: эта настройка не работает, как оказалось. Извините за неудобства.

Оригинальное сообщение ниже:

Я нашел решение, играя с Git внутренними элементами!

  • Предположим, что вы находитесь в своем репозитории.
  • Создайте свой пустой каталог:

    $ mkdir path/to/empty-folder
    
  • Добавьте его в индекс, используя команду сантехника и пустое дерево SHA-1:

    $ git update-index --index-info
    040000 tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904    path/to/empty-folder
    

    Введите команду и введите вторую строку. Нажмите Enter, а затем Ctrl + D, чтобы завершить ввод. Примечание: формат является типом режима [ПРОБЕЛ] [ПРОБЕЛ] SHA-1hash [TAB] (вкладка важна, форматирование ответа не сохраняет ее).

  • Что это! Ваша пустая папка указана в вашем индексе. Все, что вам нужно сделать, это зафиксировать.

Это решение короткое и, по-видимому, прекрасно работает (см. EDIT!), но его не так просто запомнить...

Пустое дерево SHA-1 можно найти, создав в него новый пустой репозиторий Git, cd и выпустив git write-tree, который выводит пустое дерево SHA-1.

EDIT:

Я использую это решение, так как нашел его. Кажется, он работает точно так же, как создание подмодуля, за исключением того, что ни один модуль не определен нигде. Это приводит к ошибкам при выпуске git submodule init|update. Проблема в том, что git update-index перезаписывает часть 040000 tree в 160000 commit.

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

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

Ответ 12

Скажем, вам нужен пустой каталог с именем tmp:

$ mkdir tmp
$ touch tmp/.gitignore
$ git add tmp
$ echo '*' > tmp/.gitignore
$ git commit -m 'Empty directory' tmp

Другими словами, вам нужно добавить файл .gitignore в индекс, прежде чем вы сможете сказать Git игнорировать его (и все остальное в пустом каталоге).

Ответ 13

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

mkdir --parents .generated/bin ## create a folder for storing generated binaries
mv myprogram1 myprogram2 .generated/bin ## populate the directory as needed

В этом примере вы можете проверить (сломанную) символическую ссылку на каталог, чтобы вы могли получить к ней доступ без префикса ".generated" (но это необязательно).

ln -sf .generated/bin bin
git add bin

Если вы хотите очистить исходное дерево, вы можете просто:

rm -rf .generated ## this should be in a "clean" script or in a makefile

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

Вы можете игнорировать все созданные вами файлы, добавив в корневой каталог .gitignore следующее:

.generated

Ответ 14

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

Вот почему я решил написать инструмент с открытым исходным кодом, который может автоматически управлять созданием/удалением таких файлов-заполнителей. Он написан для платформы .NET и работает под Mono (.NET для Linux) и Windows.

Просто взгляните на: http://code.google.com/p/markemptydirs

Ответ 15

Мне нравятся ответы @Artur79 и @mjs, поэтому я использовал комбинацию обоих и сделал их стандартом для наших проектов.

find . -type d -empty -exec touch {}/.gitkeep \;

Однако только несколько наших разработчиков работают на Mac или Linux. На Windows много работы, и я не смог найти эквивалентную простую однострочную версию для того же. Некоторым посчастливилось установить Cygwin по другим причинам, но назначение Cygwin только для этого казалось излишним.

Изменить для лучшего решения

Итак, поскольку у большинства наших разработчиков уже установлен Ant, первое, о чем я подумал, - собрать файл сборки Ant, чтобы выполнить это независимо от платформы. Это все еще можно найти здесь

Однако, позже я подумал, было бы лучше сделать это в небольшую команду утилиты, так что я воссоздал его с помощью Python и опубликовал его в PyPI здесь. Вы можете установить его, просто запустив:

pip3 install gitkeep2

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

$ gitkeep --help
Usage: gitkeep [OPTIONS] PATH

  Add a .gitkeep file to a directory in order to push them into a Git repo
  even if they're empty.

  Read more about why this is necessary at: https://git.wiki.kernel.org/inde
  x.php/Git_FAQ#Can_I_add_empty_directories.3F

Options:
  -r, --recursive     Add or remove the .gitkeep files recursively for all
                      sub-directories in the specified path.
  -l, --let-go        Remove the .gitkeep files from the specified path.
  -e, --empty         Create empty .gitkeep files. This will ignore any
                      message provided
  -m, --message TEXT  A message to be included in the .gitkeep file, ideally
                      used to explain why it important to push the specified
                      directory to source control even if it empty.
  -v, --verbose       Print out everything.
  --help              Show this message and exit.

Я надеюсь, что вы найдете это полезным.

Ответ 16

Вы не можете и, к сожалению, никогда не сможете. Это решение, сделанное самим Линусом Торвальдом. Он знает, что хорошо для нас.

Там есть что-то, что я читал однажды.

Я нашел Re: Пустые директории.., но, возможно, есть еще один.

Вы должны жить с обходными решениями... к сожалению.

Ответ 17

Когда вы добавляете файл .gitignore, если вы собираетесь помещать в него какое-либо количество контента (которое вы хотите игнорировать Git), вам может понадобиться добавить одну строку со звездочкой * в убедитесь, что вы случайно не добавили проигнорированный контент.

Ответ 18

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

ruby -e 'require "fileutils" ; Dir.glob(["target_directory","target_directory/**"]).each { |f| FileUtils.touch(File.join(f, ".gitignore")) if File.directory?(f) }'

Я застрял в Rakefile для легкого доступа.

Ответ 19

Решение Jamie Flournoy отлично работает. Вот немного расширенная версия, чтобы сохранить .htaccess:

# Ignore everything in this directory
*
# Except this file
!.gitignore
!.htaccess

С помощью этого решения вы можете зафиксировать пустую папку, например /log, /tmp или /cache, и папка останется пустой.

Ответ 20

Я всегда создаю функцию для проверки моей желаемой структуры папок и создания ее для меня в рамках проекта. Это обостряет эту проблему, поскольку пустые папки хранятся в Git прокси.

function check_page_custom_folder_structure () {
    if (!is_dir(TEMPLATEPATH."/page-customs"))
        mkdir(TEMPLATEPATH."/page-customs");    
    if (!is_dir(TEMPLATEPATH."/page-customs/css"))
        mkdir(TEMPLATEPATH."/page-customs/css");
    if (!is_dir(TEMPLATEPATH."/page-customs/js"))
        mkdir(TEMPLATEPATH."/page-customs/js");
}

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

Ответ 21

Вот хак, но забавно, что он работает (Git 2.2.1). Подобно тому, что предложил @Teka, но легче запомнить:

  • Добавить подмодуль в любой репозиторий (git submodule add path_to_repo)
  • Это добавит папку и файл .submodules. Зафиксируйте изменения.
  • Удалить .submodules файл и зафиксировать изменения.

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

fatal: Недействительное имя объекта b64338b90b4209263b50244d18278c0999867193

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

Ответ 22

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

Файл может быть назван и содержать все, что угодно, но большинство людей использует пустой файл с именем .gitkeep (хотя некоторые люди предпочитают VCS-агностик .keep).

Префикс . обозначает его как скрытый файл.

Еще одна идея - добавить файл README, объясняющий, для чего будет использоваться каталог.

Ответ 23

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

Ответ 24

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

/app/data/**/*.* ! /app/data/**/*.md

Затем вы можете зафиксировать описательные файлы README.md (или пустые файлы, не имеет значения, если вы можете назначить их уникально, как, например, в данном случае *.md) в каждом каталоге, чтобы убедиться, что все каталоги остаются частью репо, но файлы (с расширениями) игнорируются. ОГРАНИЧЕНИЕ: . не допускаются в именах каталогов!

Вы можете заполнить все эти каталоги файлами xml/images или чем-то еще и добавить дополнительные каталоги в /app/data/ течением времени по мере развития хранилища для вашего приложения (с файлами README.md, предназначенными для записи в описании того, что каждый каталог хранения предназначен для точно).

Нет необходимости дополнительно изменять ваш .gitignore или децентрализовать, создавая новый .gitignore для каждого нового каталога. Вероятно, не самое умное решение, но оно является кратким и всегда работает на меня. Красиво и просто! ;)

enter image description here

Ответ 25

Добавление еще одной опции в сражение.

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

Формат, как уже упоминалось, следующий:

*
!.gitignore

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

$ echo "*" > .gitignore && echo '!.gitignore' >> .gitignore && git add .gitignore

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

#!/bin/bash

dir=''

if [ "$1" != "" ]; then
    dir="$1/"
fi

echo "*" > $dir.gitignore && \
echo '!.gitignore' >> $dir.gitignore && \
git add $dir.gitignore

С помощью этого вы можете выполнить его из каталога, который вы хотите добавить, или ссылаться на каталог как на первый и только на параметр:

$ ignore_dir ./some/directory

Еще один вариант (в ответ на комментарий от @GreenAsJade), если вы хотите отслеживать пустую папку, в которой МОЖЕТ содержать отслеживаемые файлы в будущем, но пока пусто, вы можете опустить * из .gitignore и проверить это. В принципе, весь файл говорит: "Не игнорируйте меня", но в противном случае каталог пуст и отслеживается.

Ваш файл .gitignore будет выглядеть так:

!.gitignore

Чтобы он, проверьте это, и у вас есть пустой, но отслеженный каталог, в который вы можете отслеживать файлы через некоторое время.

Причина, по которой я предлагаю сохранить одну строку в файле, заключается в том, что она дает цель .gitignore. В противном случае кто-то из них может подумать, чтобы удалить его. Это может помочь, если вы разместите комментарий над строкой.

Ответ 26

Иногда вам приходится иметь дело с плохими письменными библиотеками или программным обеспечением, которым нужен "настоящий" пустой и существующий каталог. Помещение простого .gitignore или .keep может привести к их повреждению и вызвать ошибку. В этих случаях может помочь следующее, но нет гарантии...

Сначала создайте необходимый каталог:

mkdir empty

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

ln -s .this.directory empty/.keep

Чтобы игнорировать файлы в этом каталоге, вы можете добавить их в свой корень .gitignore:

echo "/empty" >> .gitignore

Чтобы добавить проигнорированный файл, используйте его параметр:

git add -f empty/.keep

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

find empty -type f

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

$ php -r "var_export(glob('empty/.*'));"
array (
  0 => 'empty/.',
  1 => 'empty/..',
)

Но я настоятельно рекомендую использовать это решение только в особых обстоятельствах, хорошо написанный README в пустом каталоге, как правило, является лучшим решением. (И я не знаю, работает ли это с файловой системой Windows...)

Ответ 27

Git не может добавить полностью пустую папку. Таким образом, вам понадобится что-то вроде .keep или .gitkeep или README или README.md или любого пользовательского именованного пустого файла.

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

git add <dir> добавит файлы в каталог.

создание папки в репозитории github

  • <dir>/ для добавления dir.
  • ../ для перехода в родительский каталог.

Опция командной строки: touch .gitkeep

Ответ 28

Простой способ сделать это - добавить файл .gitkeep в каталог, который вы хотите (в настоящее время) оставить пустым.

См. Этот ответ SOF для получения дополнительной информации, которая также объясняет, почему некоторые люди находят противоречивое соглашение о добавлении файла .gitignore (как указано во многих ответах здесь).

Ответ 29

Если вы хотите добавить пустой каталог в репозиторий Git, вы можете сделать одно. Создайте файл с именем .gitignore, а затем запишите его внутри него:

/directory/*
!.gitignore

Первая строка сообщает Git игнорировать все в этом каталоге. Вторая строка сообщает Git не игнорировать файл .gitignore.

Ответ 30

Вы можете сохранить этот код как create_readme.php и запустить PHP код из корневого каталога вашего проекта Git.

> php create_readme.php

Он добавит файлы README ко всем пустым каталогам, чтобы эти каталоги были добавлены в индекс.

<?php
    $path = realpath('.');
    $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path),       RecursiveIteratorIterator::SELF_FIRST);
    foreach($objects as $name => $object){
        if ( is_dir($name) && ! is_empty_folder($name) ){
            echo "$name\n" ;
            exec("touch ".$name."/"."README");
        }
    }

    function is_empty_folder($folder) {
        $files = opendir($folder);
        while ($file = readdir($files)) {
            if ($file != '.' && $file != '..')
                return true; // Not empty
            }
        }
?>

Тогда do

git commit -m "message"
git push