У чому полягає "практична" різниця між сховищем Bare і не-Bare?


213

Я читав про голі та не голі / типові сховища в Git. Я не зміг (теоретично) зрозуміти відмінності між ними, і чому я повинен "підштовхуватися" до голого сховища. Ось угода:

Наразі я єдиний, хто працює над проектом на трьох різних комп’ютерах, але згодом у ньому буде більше людей, тому я використовую Git для контролю версій. Я клоную оголене репо на всіх комп’ютерах, і коли я закінчую свої модифікації на одному з них, я здійснюю і натискаю зміни на оголене репо. З того, що я прочитав, у голого сховища НЕ є "робочого дерева", тож якщо я клоную оголене репо, у мене не буде "робочого дерева".

Я здогадуюсь, що робоче дерево зберігає інформацію про фіксацію, гілки тощо від проекту. Це не відображатиметься в голому репо. Тому мені здається, що краще "натискати" на репо з робочим деревом.

Тоді, чому я повинен використовувати голий сховище, а чому ні? Яка практична різниця? Це, мабуть, не було б корисно для більшості людей, які працюють над проектом.

Які ваші методи такої роботи? Пропозиції?


4
AeroCross ви можете клонувати оголене сховище, щоб створити неоголене сховище (тобто таке, яке має робочу область). Таким чином, за допомогою git cloneви можете вільно конвертувати між голими та неочищеними сховищами.
Дерек Махар

13
@AeroCross: справа не в перетворенні; не має значення, що з іншого боку. Якщо ви біжите, git clone --bareви отримаєте оголене репо, а якщо будете бігати git clone, ви отримаєте неоголене. Кожен публічний проект, який ви коли-небудь клонували (наприклад, розміщений на Github), є голим сховищем на іншому кінці.
Каскабель

1
Джефромі, я виправляв "АероКросс" точку, "тому якщо я клоную голою репо, у мене не буде" робочого дерева "", тож це свого роду перетворення. І не кожен публічний проект повинен бути голим сховищем. Це просто типовий вибір, оскільки оголене сховище є більш ефективним у просторі, оскільки у нього немає робочого дерева (це ж настільки ефективно, як і будь-яке сховище, у якого немає робочого дерева).
Дерек Махар

2
@Derek: Але справа в тому, що, як тільки він знайде каталог .git, вилучення абсолютно не знає, чи віддалений голий чи ні. Він не конвертує. Він просто отримує те, що йому потрібно з пульта, і ставить його куди слід. Не можна нічого конвертувати. Це те, що я намагався наголосити на ОП. І я добре усвідомлюю, що громадські проекти не повинні бути голими, але оскільки люди не дурні, вони, по суті, всі є. Я думаю, що я зробив прийнятне узагальнення.
Каскабель

2
Див. Розділ " Перехід на неоголене сховище", що дає ще одне чудове пояснення використання голого сховища.
Крейг МакКуїн

Відповіді:


95

Інша відмінність між голою та неоголеною сховищем полягає в тому, що у голого сховища немає сховища віддаленого походження за замовчуванням :

~/Projects$ git clone --bare test bare
Initialized empty Git repository in /home/derek/Projects/bare/
~/Projects$ cd bare
~/Projects/bare$ git branch -a
* master
~/Projects/bare$ cd ..
~/Projects$ git clone test non-bare
Initialized empty Git repository in /home/derek/Projects/non-bare/.git/
~/Projects$ cd non-bare
~/Projects/non-bare$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master

З сторінки керівництва для git clone --bare:

Також голови гілок на пульті копіюються безпосередньо у відповідні місцеві гілки філій, не відображаючи їх на refs / remote / origin /. Якщо використовується ця опція, не створюються ані гілки віддаленого відстеження, ані відповідні змінні конфігурації.

Імовірно, коли він створює голий сховище, Git припускає, що голий сховище буде служити сховищем початкових даних для декількох віддалених користувачів, тому він не створює віддалене походження за замовчуванням. Це означає, що основні git pullта git pushоперації не працюватимуть, оскільки Git припускає, що без робочої області ви не збираєтесь вносити жодних змін до голого сховища:

~/Projects/bare$ git push
fatal: No destination configured to push to.
~/Projects/bare$ git pull
fatal: /usr/lib/git-core/git-pull cannot be used without a working tree.
~/Projects/bare$ 

1
Так, я погоджуюсь, що це, мабуть, найбільш суттєва різниця між голими та не голими сховищами Git. Те, що у неоголеного сховища є робоча область, але голий сховище не є важливою різницею, але git clone --no-checkoutможе створити і неоголене сховище без файлів робочої області.
Дерек Махар

10
Неоголений репозиторій також не обов'язково має віддалене "походження" за замовчуванням.
mipadi

2
Ви можете створити репозиторій Git просто за допомогою git init, який створить неоголене репо, без вказаного віддаленого пристрою.
mipadi

1
mipadi, це правда, але це також не клон.
Дерек Махар

1
Це неправильно. Якщо сховище було відредаговане, сховище матиме початкове походження clone. Якщо це було initвідредаговано локально, воно не матиме такого походження. Це не має нічого спільного з тим, голий він чи ні.
Нуфал Ібрагім

62

Відмінність голого та не голого сховища Git є штучним та оманливим, оскільки робоча область не є частиною сховища, а сховище не вимагає робочої області. Строго кажучи, сховище Git включає ті об'єкти, які описують стан сховища. Ці об'єкти можуть існувати в будь-якому каталозі, але зазвичай вони існують у .gitкаталозі в каталозі верхнього рівня робочої області. Робоча область - це дерево директорій, яке представляє певний комітет у сховищі, але воно може існувати у будь-якому каталозі або взагалі не бути. Змінна середовища $GIT_DIRпов'язує робочу область з сховищем, з якого воно походить.

Команди Git git cloneі git initобидва мають параметри, --bareщо створюють сховища без початкової робочої області. Прикро, що Git поєднує дві окремі, але пов'язані між собою концепції робочої області та сховища, а потім використовує заплутаний термін голий, щоб розділити дві ідеї.


61

Оголене сховище - це не що інше, як сама папка .git , тобто вміст оголеного сховища такий же, як вміст папки .git у вашому локальному робочому сховищі.

  • Використовуйте оголене сховище на віддаленому сервері, щоб дозволити декільком учасникам підштовхнути свою роботу.
  • Неоголене - те, що має робоче дерево, має сенс на локальній машині кожного учасника вашого проекту.

60

Я знаю, що на 5 років пізно, але ніхто не відповів на це питання:

Тоді, чому я повинен використовувати голий сховище, а чому ні? Яка практична різниця? Це, мабуть, не було б корисно для більшості людей, які працюють над проектом.

Які ваші методи такої роботи? Пропозиції?

Цитую прямо з книги Loeliger / MCullough (978-1-449-31638-9, p196 / 7):

Голий сховище може здатися малокорисним, але його роль є вирішальною: служити авторитетним центром спільного розвитку. Інші розробники cloneі fetchз голого сховища та pushоновлення до нього ... якщо ви налаштуєте сховище, в яке pushзмінюються розробники , воно повинно бути голим. Фактично, це особливий випадок із загальної найкращої практики, що опублікований сховище має бути голим.


19

Неоголений сховище просто має перевірене робоче дерево. Робоче дерево не зберігає жодної інформації про стан сховища (гілки, теги тощо); швидше, робоче дерево - це лише представлення фактичних файлів у репо, що дозволяє працювати над (редагувати тощо) файли.


Значить, це означає, що я можу додати гілки, теги тощо до голого сховища, а потім витягнути з голого в неперше / виробниче сховище?
AeroCross

2
mipadi, у неоголеного сховища може бути не зареєстроване дерево. Це в тому випадку, якщо ви створюєте неперспективний сховище git clone --no-checkout. У цьому випадку у неоголеного сховища є місце для робочої області, але Git не перевіряє жодних файлів у цю робочу область.
Дерек Махар

17

Голий сховище має переваги в

  • зменшення використання диска
  • менше проблем, пов’язаних із віддаленим натисканням (оскільки жодного робочого дерева немає, щоб вийти з синхронізації чи мати суперечливі зміни)

3
Тож оголене сховище - найкращий / рекомендований спосіб роботи з кількома людьми, які не мають доступу до їх сховищ? (
Начебто

2
AeroCross, я б сказав, голий сховище - хороший вибір для цього сценарію.
Дерек Махар

12

Неоголений сховище дозволяє (у ваше робоче дерево) фіксувати зміни, створюючи нові коміти.

Голі сховища змінюються лише шляхом транспортування змін з інших сховищ.


10

Я, звичайно, не "експерт" Git. Я деякий час використовував TortoiseGit і цікавився, про що йдеться, коли він запитував мене, чи хочу я зробити "голою" репо, коли я її створюю. Я читав цей підручник: https://www.atlassian.com/git/tutorials/setting-up-a-repository/git-init, і він вирішує цю проблему, але все ще не зовсім розумів цю концепцію. Це дуже допомогло: http://bitflop.com/tutorials/git-bare-vs-non-bare-repositories.html . А тепер і перший має сенс!

Згідно з цими джерелами, у двох словах, "голе" репо використовується на сервері, де потрібно встановити точку розподілу. Це не призначено для використання на вашій локальній машині. Ви, як правило, переносите комісії зі своєї локальної машини на оголене репо на віддаленому сервері, і ви та / або інші витягуєте з цього голого репо на свою локальну машину. Таким чином, ваше віддалене зберігання / розповсюдження GitHub, Assembla тощо є прикладом, коли створюється "голе" репо. Ви б зробили його самостійно, якби створили власний аналогічний "центр обміну".


ooooh зараз я отримую це
Fuseteam

9

Git repo за замовчуванням / не голий містить два стани:

  1. Знімок всіх файлів в сховище (це те , що «працює дерево» означає в Git жаргоні)
  2. Історія всіх змін , внесених в усі файли , які коли - небудь були в сховищі (там , здається, не бути коротким шматок Гіт жаргоні , який включає в себе все це)

Знімок є те , що ви , ймовірно , думаєте , як ваш проект: ваш код файли, файли збірка, допоміжні скрипти, і все , що ви версія з Git.

Історія є станом , яке дозволяє перевірити різні фіксації і отримати повну картину того , що файли у вашому сховищі виглядають, коли, що виділяє було додано. Він складається з безлічі структур даних, які є внутрішніми для Git, з якими ви, мабуть, ніколи не взаємоділи безпосередньо. Важливо, що історія не просто зберігає метадані (наприклад, "Користувач U додав це багато рядків до Файлу F за час T як частина Комітету C"), він також зберігає дані (наприклад, "Користувач U додав ці точні рядки до Файлу F" ).

Основна ідея голого сховища полягає в тому, що вам насправді не потрібно робити знімок. Git зберігає знімок навколо, тому що це зручно для людей та інших процесів, що не стосуються Git, які хочуть взаємодіяти з вашим кодом, але знімок - це лише копіювання стану, яке вже є в історії.

Голе сховище являє собою сховище Git , який не має знімка. Він просто зберігає історію.

Чому б ти цього хотів? Ну, якщо ви збираєтесь взаємодіяти зі своїми файлами лише за допомогою Git (тобто ви не збираєтесь редагувати свої файли безпосередньо або використовувати їх для створення виконуваного файлу), ви можете заощадити місце, не затримуючи при цьому знімок. Зокрема, якщо ви десь підтримуєте централізовану версію свого репо на сервері (тобто в основному ви розміщуєте свій власний GitHub), на цьому сервері, ймовірно, має бути голе репо (ви все одно будете використовувати не голий репо на своєму локальна машина, однак, імовірно, ви хочете відредагувати знімок).

Якщо ви хочете більш глибокого пояснення голих репостів та іншого прикладу використання прикладу, я написав тут повідомлення в блозі: https://stegosaurusdormant.com/bare-git-repo/


4

Це не нова відповідь, але це допомогло мені зрозуміти різні аспекти відповідей вище (і це занадто багато для коментаря).

Використовуючи Git Bash, просто спробуйте:

me@pc MINGW64 /c/Test
$ ls -al
total 16
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:35 ./
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:11 ../

me@pc MINGW64 /c/Test
$ git init
Initialized empty Git repository in C:/Test/.git/

me@pc MINGW64 /c/Test (master)
$ ls -al
total 20
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:35 ./
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:11 ../
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:35 .git/

me@pc MINGW64 /c/Test (master)
$ cd .git

me@pc MINGW64 /c/Test/.git (GIT_DIR!)
$ ls -al
total 15
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 ./
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 ../
-rw-r--r-- 1 myid 1049089 130 Apr  1 11:35 config
-rw-r--r-- 1 myid 1049089  73 Apr  1 11:35 description
-rw-r--r-- 1 myid 1049089  23 Apr  1 11:35 HEAD
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 hooks/
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 info/
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 objects/
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 refs/

Те саме git --bare:

me@pc MINGW64 /c/Test
$ ls -al
total 16
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:36 ./
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:11 ../

me@pc MINGW64 /c/Test
$ git init --bare
Initialized empty Git repository in C:/Test/

me@pc MINGW64 /c/Test (BARE:master)
$ ls -al
total 23
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:36 ./
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:11 ../
-rw-r--r-- 1 myid 1049089 104 Apr  1 11:36 config
-rw-r--r-- 1 myid 1049089  73 Apr  1 11:36 description
-rw-r--r-- 1 myid 1049089  23 Apr  1 11:36 HEAD
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:36 hooks/
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:36 info/
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:36 objects/

2

$ git help repository-layout

Репозиторій Git має два різні смаки:

  • .git каталог у корені робочого дерева;
  • .git-каталог, який є голим сховищем (тобто без власного робочого дерева), який, як правило, використовується для обміну історіями з іншими, натискаючи на нього та отримуючи з нього.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.