Jaka jest różnica między „git init” a „git init --bare”?

162

Jaka jest różnica między git initi git init --bare? Okazało się, że --bareserwer Git wymaga wielu postów na blogu ?

Na stronie podręcznika jest napisane:

--bare

Utwórz czyste repozytorium. Jeśli środowisko GIT_DIR nie jest ustawione, jest ustawione na bieżący katalog roboczy

Ale co to właściwie oznacza? Czy jest to wymagane do --barekonfiguracji serwera Git?

Kit Ho
źródło

Odpowiedzi:

143

Non-Bare Git Repo

Ten wariant tworzy repozytorium z katalogiem roboczym, więc możesz faktycznie pracować ( git clone). Po jego utworzeniu zobaczysz, że katalog zawiera folder .git, w którym znajduje się historia i cała hydraulika git. Pracujesz na poziomie, na którym znajduje się folder .git.

Nagie repozytorium Git

Drugi wariant tworzy repozytorium bez katalogu roboczego ( git clone --bare). Nie masz katalogu, w którym możesz pracować. Cała zawartość katalogu jest teraz zawarta w folderze .git w powyższym przypadku.

Dlaczego użyłbyś jednego kontra drugiego

Potrzeba repozytoriów git bez katalogu roboczego polega na tym, że można do niego wypychać gałęzie i nie zarządza to, nad czym ktoś pracuje. Nadal możesz przesłać do repozytorium, które nie jest puste, ale zostaniesz odrzucony, ponieważ możesz potencjalnie przenieść gałąź, nad którą ktoś pracuje w tym katalogu roboczym.

Zatem w projekcie bez folderu roboczego możesz zobaczyć obiekty tylko wtedy, gdy przechowuje je git. Są one kompresowane i serializowane oraz przechowywane pod SHA1 (hash) ich zawartości. Aby pobrać obiekt z czystego repozytorium, musisz git showokreślić sha1 obiektu, który chcesz zobaczyć. Nie zobaczysz struktury podobnej do tego, jak wygląda Twój projekt.

Zwykłe repozytoria to zwykle repozytoria centralne, do których każdy przenosi swoją pracę. Nie ma potrzeby manipulowania rzeczywistą pracą. To sposób na synchronizację wysiłków wielu osób. Nie będziesz mieć możliwości bezpośredniego przeglądania plików projektu.

Możesz nie mieć potrzeby posiadania czystych repozytoriów, jeśli jesteś jedyną osobą pracującą nad projektem lub nie chcesz / potrzebujesz "logicznie centralnego" repozytorium. W takim przypadku ktoś wolałby git pull od innych repozytoriów. Pozwala to uniknąć zastrzeżeń, które ma git podczas wypychania do nie-nagich repozytoriów.

Mam nadzieję że to pomoże

Adam Dymitruk
źródło
Przechowywać , wyrzucić z tej linii - Można by wolą git pull od A druga ... :-)
Arup Rakshit
10
Uważam, że ta odpowiedź jest bardzo niejasna i myląca. Oto niektóre z powodów: meta.stackoverflow.com/questions/339837/ ...
Marko Avlijaš
Bare repositories are usually central repositories where everyone moves their work to.Czy chcesz przez to powiedzieć, że nagie repozytorium jest źródłem, z którego inni współpracownicy projektu mogą sklonować projekt? Oznacza to, że współpracownicy traktują to jako remote?
Minh Tran
112

Krótka odpowiedź

Czyste repozytorium to repozytorium git bez kopii roboczej, dlatego zawartość .git jest na najwyższym poziomie dla tego katalogu.

Użyj repozytorium non-bare do pracy lokalnie, a repozytorium samego jako centralnego serwera / hubu do udostępniania zmian innym osobom. Na przykład, kiedy tworzysz repozytorium na github.com, jest ono tworzone jako czyste repozytorium.

A więc w twoim komputerze:

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

na serwerze:

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

Następnie na kliencie naciskasz:

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

Możesz wtedy zapisać sobie wpisywanie, dodając go jako pilota.

Repozytorium po stronie serwera będzie otrzymywało zatwierdzenia przez pull i push, a nie przez ciebie, edytując pliki, a następnie zatwierdzając je na serwerze, dlatego jest to czyste repozytorium.

Detale

Możesz wypchnąć do repozytorium, które nie jest czystym repozytorium, a git dowie się, że jest tam repozytorium .git, ale ponieważ większość repozytoriów „hubowych” nie potrzebuje kopii roboczej, normalne jest używanie czystego repozytorium do to i zalecane, ponieważ nie ma sensu mieć kopii roboczej w tego rodzaju repozytoriach.

Jeśli jednak wypchniesz do innego repozytorium, robisz kopię roboczą niespójną, a git ostrzeże Cię:

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'.

Możesz pominąć to ostrzeżenie. Ale zalecana konfiguracja jest następująca: użyj repozytorium non-bare do pracy lokalnie oraz repozytorium bare jako hub lub central server do wypychania i ściągania.

Jeśli chcesz udostępnić pracę bezpośrednio kopii roboczej innego programisty, możesz pobrać z siebie repozytoria zamiast wypychać.

duncan
źródło
jeśli chcę pracować z moim projektem na serwerze git, więc nie jest potrzebna opcja --bare, prawda?
Kit Ho
Używasz bare do zdalnego repozytorium, a nie do lokalnego.
duncan
Jeszcze trochę, ale tu kolejne pytanie. Jeśli mamy czyste, zdalne repozytorium, każdy programista może wyciągnąć do niego push, repozytorium jest repozytorium „centralnym”. Ale jeśli pracujemy bez czystego repozytorium, programiści powinni tylko wyciągać od siebie nawzajem, ale nigdy nie pchać. Ostatni scenariusz jest po prostu dobry, jeśli istnieją tylko 2 kopie robocze repozytorium (czyli lokalne repozytoria). Czy to jest poprawne?
Asturio
60

Kiedy przeczytałem to pytanie jakiś czas temu, wszystko mnie zagmatwało. Właśnie zacząłem używać git i są tam te kopie robocze (co wtedy nic nie znaczyło). Spróbuję to wyjaśnić z perspektywy gościa, który dopiero co zaczął git, nie mając pojęcia o terminologii.

Ładny przykład różnic można opisać w następujący sposób :

--baredaje ci tylko miejsce do przechowywania (nie możesz tam rozwijać). Bez --bareniej możesz się tam rozwijać (i mieć miejsce do przechowywania).

git inittworzy repozytorium git z twojego bieżącego katalogu. Dodaje do niego folder .git i umożliwia rozpoczęcie historii zmian.

git init --baretworzy również repozytorium, ale nie ma katalogu roboczego. Oznacza to, że nie możesz edytować plików, zatwierdzać zmian, dodawać nowych plików w tym repozytorium.

Kiedy --baremoże być pomocne? Ty i kilku innych pracujesz nad projektem i używasz git. Projekt był hostowany na jakimś serwerze ( amazon ec2). Każdy z was ma swoją własną maszynę i wciska swój kod ec2. Nikt z was nie tworzy niczego na ec2(używasz swoich maszyn) - po prostu wypychasz swój kod. Więc twój ec2jest tylko magazynem dla całego twojego kodu i powinien być tworzony jako --barei wszystkie twoje maszyny bez --bare(najprawdopodobniej tylko jeden, a inne po prostu sklonują wszystko). Przepływ pracy wygląda następująco:

wprowadź opis obrazu tutaj

Salvador Dali
źródło
1
Więc możemy powiedzieć, że używając --bare repozytorium możemy stworzyć rodzaj architektury klient-serwer, tak jak robi to subversion?
Emiliano Sangoi
14

Domyślne repozytorium Git zakłada, że ​​będziesz go używać jako katalogu roboczego. Zwykle gdy jesteś na serwerze, nie potrzebujesz katalogu roboczego. Tylko repozytorium. W takim przypadku powinieneś skorzystać z --bareopcji.

Sandro Munda
źródło
w repozytorium z opcją --bare, więc nie widzimy całego pliku projektu? Wygląda na to, że tracę cały plik projektu z opcją --bare ..
Kit Ho
11

Repozytorium non-bare jest ustawieniem domyślnym. To jest to, co jest tworzone podczas uruchamiania git initlub co otrzymujesz, gdy klonujesz (bez bareopcji) z serwera.

Kiedy pracujesz z takim repozytorium, możesz przeglądać i edytować wszystkie pliki, które są w repozytorium. Podczas interakcji z repozytorium - na przykład poprzez zatwierdzenie zmiany - Git przechowuje twoje zmiany w ukrytym katalogu o nazwie .git.

Gdy masz serwer git, nie ma potrzeby tworzenia kopii roboczych plików. Wszystko, czego potrzebujesz, to dane Git, które są przechowywane w plikach .git. Surowe repozytorium to dokładnie .gitkatalog, bez obszaru roboczego do modyfikowania i zatwierdzania plików.

Kiedy klonujesz z serwera, Git ma wszystkie informacje potrzebne .gitdo utworzenia kopii roboczej.

Andrzej
źródło
1

Inną różnicą między repozytoriami --bare i Working Tree jest to, że w pierwszym przypadku nie są zapisywane żadne utracone zatwierdzenia, ale tylko te, które należą do ścieżki gałęzi . Z drugiej strony drzewo robocze zachowuje wszystkie zatwierdzenia na zawsze. Zobacz poniżej ...

Utworzyłem pierwsze repozytorium (nazwa: git-bare ) z git init --bare. To serwer. Znajduje się po lewej stronie, gdzie nie ma zdalnych gałęzi, ponieważ jest to samo zdalne repozytorium.

Utworzyłem drugie repozytorium (nazwa: git-working-tree ) z użyciem git clonepierwszego. To jest po prawej. Ma lokalne oddziały połączone ze zdalnymi oddziałami.

(Teksty „pierwszy”, „drugi”, „trzeci”, „czwarty”, „alfa”, „beta” i „delta” są komentarzami do zatwierdzenia. Nazwy „master” i „greek” to nazwy gałęzi).

Repozytoria lokalne i zdalne

Teraz usunę gałąź o nazwie „greek” zarówno w git-bare (command git push --delete origin greek:), jak i lokalnie w git-working-tree (command:) git branch -D greek. Oto jak wygląda drzewo:

Repozytorium git-bare usuwa to, do czego już się nie odwołuje

Git-gołe repozytorium usuwa zarówno oddziału oraz wszystkie odwołuje comits. Na zdjęciu widzimy, że z tego powodu jego drzewo zostało zredukowane.

Z drugiej strony repozytorium git-working-tree , które jest odpowiednikiem powszechnie używanego repozytorium lokalnego, nie usuwa zatwierdzeń, do których można teraz odwoływać się bezpośrednio przez hash za pomocą git checkout 7fa897b7polecenia. Dlatego jego drzewo nie ma zmodyfikowanej struktury.

W SKRÓCIE: zatwierdzenia nigdy nie są upuszczane w repozytoriach drzewa roboczego , ale są usuwane w samych repozytoriach.

W praktyce można odzyskać usuniętą gałąź na serwerze tylko wtedy, gdy istnieje w lokalnym repozytorium.

Ale to jest bardzo dziwne, że wielkość gołego repozytorium nie zmniejsza wielkości dysku po usunięciu pilota oddziału. Oznacza to, że w jakiś sposób pliki nadal tam są. Aby zrzucić repozytorium, usuwając to, do czego już się nie odwołujesz lub do czego nigdy nie można się odwołać (ten drugi przypadek) użyj git gc --prunepolecenia

Sergio Cabral
źródło
Aby przetestować polecenia git, spróbuj: github.com/sergiocabral/App.GitPlayground
Sergio Cabral