Jaka jest praktyczna różnica między repozytorium Bare i non-Bare?

213

Czytałem o repozytoriach Git i nagich i domyślnych / domyślnych. Nie byłem w stanie dość dobrze (teoretycznie) zrozumieć różnic między nimi i dlaczego powinienem „przepychać” do czystego repozytorium. Oto oferta:

Obecnie jestem jedynym pracującym nad projektem na 3 różnych komputerach, ale później będzie w to zaangażowanych więcej osób, więc używam Git do kontroli wersji. Klonuję nagie repo na wszystkich komputerach, a kiedy skończę modyfikacje na jednym z nich, zatwierdzam i przekazuję zmiany do samego repo. Z tego, co przeczytałem, nagie repozytorium NIE ma „działającego drzewa”, więc jeśli sklonuję nagie repozytorium, nie będę mieć „działającego drzewa”.

Zgaduję, że działające drzewo przechowuje informacje o zatwierdzeniu, gałęzie itp. Z projektu. Nie pojawiłoby się to w nagim repozytorium. Wydaje mi się więc, że lepiej „wypychać” zatwierdzenia do repozytorium za pomocą działającego drzewa.

Następnie, dlaczego powinienem użyć gołego repozytorium i dlaczego nie? Jaka jest praktyczna różnica? Podejrzewam, że nie byłoby to korzystne dla większej liczby osób pracujących nad projektem.

Jakie są twoje metody tego rodzaju pracy? Propozycje?

AeroCross
źródło
4
AeroCross, to można sklonować repozytorium gołego stworzyć repozytorium non-gołe (to znaczy taki, który posiada obszar roboczy). Dzięki temu git clonemożesz swobodnie konwertować między nagimi i nie nagimi repozytoriami.
Derek Mahar
13
@AeroCross: Nie chodzi o konwersję; nie ma znaczenia, co jest na drugim końcu. Jeśli uruchomisz git clone --bare, otrzymasz nagie repozytorium, a jeśli uruchomisz git clone, dostaniesz repozytorium inne niż nagie. Każdy projekt publiczny, który kiedykolwiek sklonowałeś (na przykład hostowany na github), jest na drugim końcu zwykłym repozytorium.
Cascabel,
1
Jefromi, poprawiałem punkt AeroCross, więc jeśli sklonuję nagie repo, nie będę miał „działającego drzewa”, więc jest to rodzaj konwersji. I nie każdy projekt publiczny musi być czystym repozytorium. Jest to po prostu typowy wybór, ponieważ samo repozytorium zajmuje więcej miejsca, ponieważ nie ma działającego drzewa (jest jednak tak samo wydajne jak każde repozytorium, które nie ma działającego drzewa).
Derek Mahar
2
@Derek: Ale chodzi o to, że jak tylko znajdzie katalog .git, pobieranie jest całkowicie nieświadome, czy pilot jest pusty. Nie konwertuje. Po prostu pobiera to, czego potrzebuje od pilota, i umieszcza go tam, gdzie powinien. Nie ma nic do konwersji. Właśnie to chciałem podkreślić w OP. I jestem w pełni świadomy, że projekty publiczne nie muszą być nagie, ale ponieważ ludzie nie są głupi, w zasadzie wszyscy są. Myślę, że dokonałem akceptowalnego uogólnienia.
Cascabel,
2
Zobacz Prześlij do repozytorium typu non-bare, które daje kolejne doskonałe wyjaśnienie użycia samego repozytorium.
Craig McQueen

Odpowiedzi:

95

Kolejną różnicą między repozytorium nagim i innym niż repozytorium jest to, że repozytorium nagie nie ma domyślnego repozytorium zdalnego pochodzenia :

~/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

Ze strony podręcznika dla git clone --bare:

Również głowy oddziałów na pilocie są kopiowane bezpośrednio do odpowiednich lokalnych szefów oddziałów, bez mapowania ich na referencje / piloty / pochodzenie /. Gdy ta opcja jest używana, nie są tworzone gałęzie zdalnego śledzenia ani powiązane zmienne konfiguracyjne.

Przypuszczalnie, gdy utworzy ono puste repozytorium, Git zakłada, że ​​puste repozytorium będzie służyć jako repozytorium źródłowe dla kilku zdalnych użytkowników, więc nie tworzy domyślnego zdalnego źródła. Oznacza to, że podstawowe git pulli git pushoperacje nie będą działać, ponieważ Git zakłada, że ​​bez obszaru roboczego nie zamierzasz dokonywać żadnych zmian w czystym repozytorium:

~/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$ 
Derek Mahar
źródło
1
Tak, zgadzam się, że jest to prawdopodobnie najistotniejsza różnica między nagimi i nie nagimi repozytoriami Git. Fakt, że repozytorium inne niż nagie ma obszar roboczy, ale samo repozytorium nie stanowi istotnej różnicy, ale git clone --no-checkoutmoże również tworzyć repozytorium nie nagie bez plików obszaru roboczego.
Derek Mahar
10
Repozytorium, które nie jest nagie, niekoniecznie musi również mieć domyślne zdalne „pochodzenie”.
mipadi
2
Możesz po prostu utworzyć repozytorium Git git init, które utworzy repozytorium non-bare bez określonego zdalnego.
mipadi
1
mipadi, to prawda, ale to też nie jest klon.
Derek Mahar
1
To jest niepoprawne. Repozytorium będzie miało domyślne pochodzenie, jeśli zostało cloneedytowane. Jeśli został on initedytowany lokalnie, nie będzie miał takiego pochodzenia. Nie ma to nic wspólnego z tym, czy jest goły, czy nie.
Noufal Ibrahim
62

Rozróżnienie między nagim i nie nagim repozytorium Git jest sztuczne i wprowadza w błąd, ponieważ obszar roboczy nie jest częścią repozytorium, a repozytorium nie wymaga obszaru roboczego. Ściśle mówiąc, repozytorium Git obejmuje te obiekty, które opisują stan repozytorium. Obiekty te mogą istnieć w dowolnym katalogu, ale zwykle istnieją w .gitkatalogu w katalogu najwyższego poziomu obszaru roboczego. Obszar roboczy jest drzewem katalogów, które reprezentuje określone zatwierdzenie w repozytorium, ale może istnieć w dowolnym katalogu lub wcale. Zmienna środowiskowa $GIT_DIRłączy obszar roboczy z repozytorium, z którego pochodzi.

Polecenia Git git clonei git initoba mają opcje, --barektóre tworzą repozytoria bez początkowego obszaru roboczego. To niefortunne, że Git łączy dwa oddzielne, ale powiązane pojęcia przestrzeni roboczej i repozytorium, a następnie używa mylącego terminu „ nagi”, aby rozdzielić te dwa pomysły.

Derek Mahar
źródło
61

Nagie repozytorium to nic innego jak sam folder .git , tzn. Zawartość pustego repozytorium jest taka sama jak zawartość folderu .git w lokalnym repozytorium roboczym.

  • Skorzystaj z repozytorium gołego na zdalnym serwerze, aby umożliwić wielu współautorom przekazywanie swojej pracy.
  • Nie goły - ten, który ma działające drzewo, ma sens na lokalnej maszynie każdego współautora twojego projektu.
Deepak Sharma
źródło
60

5 lat za późno, wiem, ale nikt tak naprawdę nie odpowiedział na pytanie:

Dlaczego więc mam korzystać z samego repozytorium, a dlaczego nie? Jaka jest praktyczna różnica? Podejrzewam, że nie byłoby to korzystne dla większej liczby osób pracujących nad projektem.

Jakie są twoje metody tego rodzaju pracy? Propozycje?

Aby zacytować bezpośrednio z książki Loeliger / MCullough (978-1-449-31638-9, p196 / 7):

Samo repozytorium może wydawać się mało przydatne, ale jego rola jest kluczowa: służyć jako autorytatywny punkt centralny dla wspólnego rozwoju. Inni deweloperzy clonei fetchod gołego repozytorium i pushaktualizacje do niego ... jeśli założyć repozytorium, do którego deweloperzy pushzmiany, to powinny być nagie. W efekcie jest to szczególny przypadek bardziej ogólnej najlepszej praktyki, zgodnie z którą opublikowane repozytorium powinno być puste.

EML
źródło
19

Repozytorium inne niż zwykłe ma po prostu sprawdzone drzewo robocze. Drzewo robocze nie przechowuje żadnych informacji o stanie repozytorium (gałęzie, znaczniki itp.); działające drzewo jest raczej reprezentacją rzeczywistych plików w repozytorium, co pozwala na pracę nad (edycję itp.) plikami.

mipadi
źródło
Oznacza to, że mogę dodawać gałęzie, znaczniki itp. Do nagiego repozytorium, a następnie przeciągać go z nagiego do repozytorium produkcyjnego?
AeroCross
2
mipadi, repozytorium inne niż nagie może nie mieć drzewa wyewidencjonowanego. Dzieje się tak, jeśli utworzysz repozytorium, które nie jest nagie git clone --no-checkout. W tym przypadku repozytorium non-bare ma lokalizację dla obszaru roboczego, ale Git nie pobiera żadnych plików do tego obszaru roboczego.
Derek Mahar
17

Samo repozytorium ma zalety

  • zmniejszone użycie dysku
  • mniej problemów związanych ze zdalnym wypychaniem (ponieważ nie ma działającego drzewa, aby się zsynchronizować lub wprowadzić sprzeczne zmiany)
sehe
źródło
3
Czyste repozytorium jest najlepszym / zalecanym sposobem pracy z kilkoma osobami bez dostępu do repozytoriów ICH? (Trochę jak SVN?)
AeroCross
2
AeroCross, powiedziałbym, że nagie repozytorium jest dobrym wyborem dla tego scenariusza.
Derek Mahar
12

Nie nagie repozytorium pozwala (do twojego drzewa roboczego) przechwytywać zmiany poprzez tworzenie nowych zatwierdzeń.

Nagie repozytoria są zmieniane tylko poprzez transport zmian z innych repozytoriów.

Nitin
źródło
10

Na pewno nie jestem „ekspertem” Gita. Używam TortoiseGit od dłuższego czasu i zastanawiałem się, o czym on mówi, kiedy pyta mnie, czy chcę zrobić „gołe” repozytorium za każdym razem, gdy je utworzę. Czytałem ten samouczek: https://www.atlassian.com/git/tutorials/setting-up-a-repository/git-init i rozwiązuje ten problem, ale nadal nie do końca rozumiałem tę koncepcję. Ten bardzo pomógł: http://bitflop.com/tutorials/git-bare-vs-non-bare-repositories.html . Teraz pierwszy też ma sens!

Według tych źródeł w skrócie repozytorium typu „goły” jest używane na serwerze, na którym chcesz skonfigurować punkt dystrybucji. Nie jest przeznaczony do użytku na lokalnej maszynie. Zazwyczaj wypychasz zatwierdzenia z komputera lokalnego do nagiego repozytorium na zdalnym serwerze, a ty i / lub inni ściągacie z tego nagiego repo do komputera lokalnego. Zatem Twoje zdalne repozytorium GitHub, Assembla itp. Jest przykładem, w którym tworzone jest repozytorium „bare”. Zrobiłbyś to sam, gdybyś założył własne analogiczne „centrum udostępniania”.

BuvinJ
źródło
ooooh teraz rozumiem
Fuseteam
9

Domyślne / nie tylko repozytorium Git zawiera dwa elementy stanu:

  1. Migawka wszystkich plików w repozytorium (to właśnie działa „drzewo” oznacza w żargonie Git)
  2. Historię wszystkich zmian wprowadzonych do wszystkich plików, które kiedykolwiek w repozytorium (nie wydaje się być zwięzły kawałek z Git żargonie, że obejmuje to wszystko)

Migawka jest to, czego prawdopodobnie myśleć jako projektu: pliki kod, pliki budować, skrypty pomocnicze, a coś, co wersja z Git.

Historia jest stan, który pozwala sprawdzić inny popełnić i uzyskać pełny zrzut co pliki w repozytorium wyglądało, kiedy to commit został dodany. Składa się z szeregu struktur danych, które są wewnętrzne w Git, z którymi prawdopodobnie nigdy nie korzystałeś bezpośrednio. Co ważne, historia nie tylko przechowuje metadane (np. „Użytkownik U dodał tak wiele wierszy do pliku F w czasie T jako część Commit C”), ale także przechowuje dane (np. „Użytkownik U dodał te dokładne wiersze do pliku F” ).

Kluczową ideą nagiego repozytorium jest to, że tak naprawdę nie potrzebujesz migawki. Git utrzymuje migawkę, ponieważ jest wygodny dla ludzi i innych procesów innych niż Git, które chcą wchodzić w interakcje z twoim kodem, ale migawka to tylko powielanie stanu, który jest już w historii.

Gołe repozytorium jest repozytorium Git, że nie ma migawkę. Po prostu przechowuje historię.

Dlaczego miałbyś tego chcieć? Cóż, jeśli masz zamiar wchodzić w interakcję z plikami tylko za pomocą Git (to znaczy, nie zamierzasz bezpośrednio edytować plików ani używać ich do budowy pliku wykonywalnego), możesz zaoszczędzić miejsce, nie trzymając się migawki. W szczególności, jeśli utrzymujesz scentralizowaną wersję swojego repozytorium gdzieś na serwerze (tzn. W zasadzie hostujesz swój własny serwis GitHub), ten serwer prawdopodobnie powinien mieć nagie repozytorium (nadal używałbyś repozytorium non-go na swoim komputer lokalny, ponieważ prawdopodobnie będziesz chciał edytować migawkę).

Jeśli chcesz uzyskać bardziej szczegółowe wyjaśnienie samego repozytorium i inny przykładowy przypadek użycia, napisałem post na blogu tutaj: https://stegosaurusdormant.com/bare-git-repo/

Greg Owen
źródło
4

To nie jest nowa odpowiedź, ale pomogła mi zrozumieć różne aspekty powyższych odpowiedzi (i to za dużo na komentarz).

Korzystając z Git Bash, po prostu spróbuj:

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/

To samo z 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/
Christoph
źródło
2

$ git help repository-layout

Repozytorium Git jest dostępne w dwóch różnych wersjach:

  • katalog .git w katalogu głównym działającego drzewa;
  • katalog .git, który jest pustym repozytorium (tj. bez własnego drzewa roboczego), który jest zwykle używany do wymiany historii z innymi przez wpychanie do niego i pobieranie z niego.
MichK
źródło