В чем разница между «git init» и «git init --bare»?

162

В чем разница между git initи git init --bare? Я обнаружил, что --bareдля их Git-сервера требуется много сообщений в блоге ?

Со страницы руководства он сказал:

--bare

Создать голое хранилище. Если среда GIT_DIR не установлена, она устанавливается в текущий рабочий каталог

Но что это на самом деле означает? Требуется ли --bareдля настройки Git-сервера?

Кит Хо
источник

Ответы:

143

Non-Bare Git Repo

Этот вариант создает хранилище с рабочим каталогом, чтобы вы могли работать ( git clone). После его создания вы увидите, что каталог содержит папку .git, в которую попадает история и вся сантехника git. Вы работаете на уровне, где находится папка .git.

Голый Гит Репо

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

Почему вы используете один против другого

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

Таким образом, в проекте без рабочей папки вы можете видеть объекты только по мере их сохранения в git. Они сжимаются и сериализуются и хранятся в SHA1 (хэш) их содержимого. Чтобы получить объект в пустом хранилище, вам нужно, git showа затем указать sha1 объекта, который вы хотите увидеть. Вы не увидите такую ​​структуру, как ваш проект.

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

Вам может не понадобиться никаких пустых репозиториев, если вы единственный, кто работает над проектом, или вам не нужен / не нужен «логически центральный» репозиторий. Один предпочел бы git pull из других хранилищ в этом случае. Это позволяет избежать возражений, возникающих у git при отправке в непокрытые репозитории.

Надеюсь это поможет

Адам Димитрук
источник
Держите , выбросить от этой линии - Один предпочел бы GIT тянуть от А другой ... :-)
Arup Ракшит
10
Я нахожу этот ответ очень неясным и запутанным. Некоторые из причин здесь: meta.stackoverflow.com/questions/339837/…
Марко Авлияш
Bare repositories are usually central repositories where everyone moves their work to.Вы хотите сказать, что пустой репозиторий является источником, из которого другие участники проекта могут клонировать проект? То есть сотрудники воспринимают это как remote?
Минь
112

Короткий ответ

Пустой репозиторий - это репозиторий git без рабочей копии, поэтому содержимое .git является верхним уровнем для этого каталога.

Используйте не пустой репозиторий для локальной работы и пустой репозиторий в качестве центрального сервера / концентратора, чтобы поделиться своими изменениями с другими людьми. Например, когда вы создаете репозиторий на github.com, он создается как пустой репозиторий.

Итак, на вашем компьютере:

git init
touch README
git add README
git commit -m "initial commit"

на сервере:

cd /srv/git/project
git init --bare

Затем на клиенте вы нажимаете:

git push username@server:/srv/git/project master

Затем вы можете сохранить набор текста, добавив его в качестве удаленного.

Хранилище на стороне сервера будет получать коммиты через pull и push, а не от вас, редактируя файлы и затем коммитируя их на серверном компьютере, поэтому это пустой репозиторий.

подробности

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

Однако, если вы перешли в не пустой репозиторий, вы делаете рабочую копию несовместимой, и git предупредит вас:

remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require 'git reset --hard' to match
remote: error: the work tree to HEAD.
remote: error: 
remote: error: You can set 'receive.denyCurrentBranch' configuration variable to
remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in some
remote: error: other way.
remote: error: 
remote: error: To squelch this message and still keep the default behaviour, set
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.

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

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

Duncan
источник
если я хочу работать над своим проектом на git-сервере, то нет необходимости иметь опцию --bare, не так ли?
Кит Хо,
Вы используете bare для удаленного хранилища, а не для локального.
Дункан
Еще немного, но тут другой вопрос. Если у нас есть пустой удаленный репозиторий, любой разработчик может подтолкнуть его, а репозиторий является «центральным». Но если мы работаем без простого репозитория, разработчики должны только отталкиваться друг от друга, но никогда не проталкивать. Последний сценарий просто хорош, если есть только 2 рабочие копии репо (или локальные репо). Это верно?
Asturio
60

Когда я прочитал этот вопрос некоторое время назад, меня все смутило. Я только начал использовать git и есть эти рабочие копии (которые в то время ничего не значили). Я попытаюсь объяснить это с точки зрения парня, который только начал заниматься git, не имея понятия о терминологии.

Хороший пример различий можно описать следующим образом :

--bareдает вам просто место для хранения (вы не можете развиваться там). Без --bareэтого дает вам возможность развиваться там (и иметь место для хранения).

git initсоздает репозиторий git из вашего текущего каталога. Он добавляет в него папку .git и позволяет начать историю изменений.

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

Когда --bareможет быть полезно? Вы и несколько других парней работаете над проектом и используете git. Вы размещали проект на каком-либо сервере ( amazon ec2). У каждого из вас есть свой компьютер, и вы запускаете свой код ec2. Никто из вас на самом деле ничего не разрабатывает ec2(вы используете свои машины) - вы просто продвигаете свой код. Таким образом, ваше ec2хранилище всего вашего кода должно создаваться как --bareи на всех ваших машинах --bare(скорее всего, только один, а другие просто клонируют все). Рабочий процесс выглядит так:

введите описание изображения здесь

Сальвадор Дали
источник
1
Итак, мы могли бы сказать, что с помощью репозитория --bare мы можем создать некую архитектуру клиент-сервер, как это делает Subversion?
Эмилиано Сангой
14

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

Сандро Мунда
источник
в репозитории с опцией --bare, поэтому мы не можем увидеть весь файл проекта? Кажется, что я теряю все мои файлы проекта с опцией --bare ..
Кит Хо
11

Неполное хранилище используется по умолчанию. Это то, что создается при запуске git initили то, что вы получаете при клонировании (без bareопции) с сервера.

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

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

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

Андрей
источник
1

Еще одно различие между репозиториями --bare и Working Tree заключается в том, что в первом случае не сохраняются потерянные коммиты, а только те коммиты, которые принадлежат ветви ветки. . С другой стороны, Working Tree всегда сохраняет все коммиты. Увидеть ниже...

Я создал первый репозиторий (имя: git-bare ) сgit init --bare . Это сервер. Он находится слева, где нет удаленных веток, потому что это сам удаленный репозиторий.

Я создал второй репозиторий (имя: git-working-tree ) сgit clone первого. Это справа. Он имеет локальные филиалы, связанные с удаленными филиалами.

(Тексты «первый», «второй», «третий», «четвертый», «альфа», «бета» и «дельта» являются комментариями к коммиту. Имена «мастер» и «греческий» - это названия ветвей.)

Локальные и удаленные репозитории

Теперь я буду удалять ветку с именем «greek» как в git-bare (command :), такgit push --delete origin greek и локально в git-working-tree (command:) git branch -D greek. Вот как выглядит дерево:

Репозиторий git-bare удаляет то, на что больше нет ссылок

ГИТ-голое хранилище удаляет как ветвь , и все ссылки comits. На рисунке мы видим, что его дерево было сокращено по этой причине.

С другой стороны, репозиторий git-working-tree , эквивалентный обычно используемому локальному репозиторию, не удаляет коммиты, на которые теперь может ссылаться только ваш хеш с помощьюgit checkout 7fa897b7 команды. Вот почему его дерево не имеет своей измененной структуры.

Вкратце: коммиты никогда не удаляются в репозиториях рабочего дерева , но удаляются в пустых репозиториях.

В практическом плане вы можете восстановить удаленную ветку на сервере, только если она существует в локальном хранилище.

Но очень странно, что размер чистого хранилища не уменьшается в размере диска после удаления удаленной ветви. То есть файлы все еще там как-то есть. Чтобы выгрузить репозиторий, удалив то, на что больше нет ссылок, или то, на что больше нельзя ссылаться (последний случай), используйте git gc --pruneкоманду

Серхио Кабрал
источник
Чтобы проверить команды git, попробуйте: github.com/sergiocabral/App.GitPlayground
Серхио Кабрал,