Qual è la differenza tra "git init" e "git init --bare"?


162

Qual è la differenza tra git inite git init --bare? Ho scoperto che molti post sul blog richiedono --bareper il loro server Git?

Dalla pagina man , diceva:

--bare

Crea un repository nudo. Se l'ambiente GIT_DIR non è impostato, è impostato sulla directory di lavoro corrente

Ma cosa significa in realtà? È necessario --bareper l'installazione del server Git?

Risposte:


143

Repo Git non nudo

Questa variante crea un repository con una directory di lavoro in modo da poter effettivamente lavorare ( git clone). Dopo averlo creato, vedrai che la directory contiene una cartella .git in cui va la cronologia e tutte le tubature git. Lavori al livello in cui si trova la cartella .git.

Bare Git Repo

L'altra variante crea un repository senza una directory di lavoro ( git clone --bare). Non ottieni una directory in cui puoi lavorare. Tutto nella directory è ora ciò che era contenuto nella cartella .git nel caso precedente.

Perché dovresti usare l'uno contro l'altro

La necessità di repository git senza una directory di lavoro è il fatto che è possibile eseguire il push dei rami su di essa e non gestisce ciò su cui qualcuno sta lavorando. Puoi ancora passare a un repository che non è vuoto, ma verrai rifiutato poiché potresti spostare un ramo su cui qualcuno sta lavorando in quella directory di lavoro.

Quindi in un progetto senza cartella di lavoro, puoi vedere solo gli oggetti mentre git li memorizza. Sono compressi e serializzati e archiviati sotto SHA1 (un hash) del loro contenuto. Per ottenere un oggetto in un repository nudo, è necessario git showe quindi specificare lo sha1 dell'oggetto che si desidera vedere. Non vedrai una struttura come l'aspetto del tuo progetto.

I repository nudi sono in genere repository centrali in cui ognuno sposta il proprio lavoro. Non è necessario manipolare il lavoro effettivo. È un modo per sincronizzare gli sforzi tra più persone. Non sarai in grado di vedere direttamente i tuoi file di progetto.

Potrebbe non essere necessario alcun repository nudo se sei l'unico a lavorare sul progetto o non desideri / hai bisogno di un repository "logicamente centrale". Uno preferirebbe git pull dagli altri repository in quel caso. Questo evita le obiezioni che git ha quando si spinge verso repository non nudi.

Spero che questo ti aiuti


Tieni il , butta un da questa linea - Uno preferirebbe tirare l'altro dall'altro ... :-)
Arup Rakshit

10
Trovo questa risposta molto poco chiara e confusa. Alcuni dei motivi sono qui: meta.stackoverflow.com/questions/339837/…
Marko Avlijaš

Bare repositories are usually central repositories where everyone moves their work to.Intendi dire che un repository nudo è la fonte da cui altri collaboratori del progetto possono clonare un progetto? Cioè, i collaboratori trattano questo come il remote?
Minh Tran,

112

Risposta breve

Un repository nudo è un repository git senza una copia funzionante, quindi il contenuto di .git è di primo livello per quella directory.

Utilizzare un repository non bare per lavorare localmente e un repository bare come server / hub centrale per condividere le modifiche con altre persone. Ad esempio, quando si crea un repository su github.com, viene creato come repository nudo.

Quindi, nel tuo computer:

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

sul server:

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

Quindi sul client, si preme:

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

Puoi quindi salvare te stesso digitando aggiungendolo come telecomando.

Il repository sul lato server eseguirà i commit tramite pull e push, e non modificando i file e quindi eseguendo il commit nella macchina server, quindi è un repository nudo.

Dettagli

È possibile eseguire il push in un repository che non è un repository nudo e git scoprirà che esiste un repository .git lì, ma poiché la maggior parte dei repository "hub" non ha bisogno di una copia funzionante, è normale usare un repository nudo per e raccomandato in quanto non ha senso avere una copia funzionante in questo tipo di repository.

Tuttavia, se passi a un repository non bare, stai rendendo la copia funzionante incoerente e git ti avvertirà:

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

Puoi saltare questo avviso. Ma l'installazione consigliata è: utilizzare un repository non bare per lavorare localmente e un repository bare come hub o server centrale da cui eseguire il push e il pull.

Se si desidera condividere il lavoro direttamente con la copia di lavoro di un altro sviluppatore, è possibile estrarre dagli altri repository invece di inviare.


se voglio lavorare il mio progetto sul server git, quindi non è necessario avere l'opzione --bare, no?
Kit Ho,

Si utilizza bare per il repository remoto, non per quello locale.
Duncan,

È un po 'di tempo, ma ecco un'altra domanda. Se disponiamo di un repository remoto nudo, qualsiasi sviluppatore può farne una spinta, un repository è "centrale". Ma se lavoriamo senza un repository nudo, gli sviluppatori dovrebbero solo tirare l'uno dall'altro, ma mai spingere. L'ultimo scenario è buono, se ci sono solo 2 copie funzionanti del repository (ovvero repository locali). È corretto?
Asturio,

60

Quando ho letto questa domanda qualche tempo fa, tutto mi confondeva. Ho appena iniziato a usare git e ci sono queste copie funzionanti (che non significava nulla in quel momento). Proverò a spiegarlo dal punto di vista del ragazzo, che ha appena iniziato a git senza avere idea della terminologia.

Un bell'esempio delle differenze può essere descritto nel modo seguente :

--bareti dà solo un posto di archiviazione (non puoi svilupparti lì). Senza di --bareessa ti dà la possibilità di svilupparti lì (e avere un posto di archiviazione).

git initcrea un repository git dalla directory corrente. Aggiunge la cartella .git al suo interno e consente di avviare la cronologia delle revisioni.

git init --barecrea anche un repository, ma non ha la directory di lavoro. Ciò significa che non è possibile modificare file, eseguire il commit delle modifiche, aggiungere nuovi file in quel repository.

Quando --barepuò essere utile? Tu e pochi altri ragazzi state lavorando al progetto e usate Git. Hai ospitato il progetto su alcuni server ( amazon ec2). Ognuno di voi ha la propria macchina e si inserisce il proprio codice ec2. Nessuno di voi in realtà sviluppa nulla su ec2(usi i tuoi computer) - semplicemente spingi il tuo codice. Quindi il tuo ec2è solo un archivio per tutto il tuo codice e dovrebbe essere creato come --baree tutte le tue macchine senza --bare(molto probabilmente solo uno, e l'altro semplicemente clonerà tutto). Il flusso di lavoro è simile al seguente:

inserisci qui la descrizione dell'immagine


1
Quindi, potremmo dire che usando un repository --bare possiamo creare una sorta di architettura client-server come fa sovversione?
Emiliano Sangoi,

14

Un repository Git predefinito presuppone che lo utilizzerai come directory di lavoro. In genere, quando ci si trova su un server, non è necessario disporre di una directory di lavoro. Solo il repository. In questo caso, dovresti usare l' --bareopzione.


in un repository con l'opzione --bare, quindi non possiamo vedere tutto il file di progetto? Sembra che perdo tutto il mio file di progetto con l'opzione --bare ..
Kit Ho

11

Un repository non bare è l'impostazione predefinita. È ciò che viene creato durante l'esecuzione git inito ciò che si ottiene clonando (senza l' bareopzione) da un server.

Quando si lavora con un repository come questo, è possibile visualizzare e modificare tutti i file presenti nel repository. Quando interagisci con il repository, ad esempio eseguendo una modifica, Git archivia le modifiche in una directory nascosta chiamata .git.

Quando si dispone di un server Git, non è necessario che ci siano copie funzionanti dei file. Tutto ciò di cui hai bisogno sono i dati Git in cui sono archiviati .git. Un repository nudo è esattamente la .gitdirectory, senza un'area di lavoro per la modifica e il commit dei file.

Quando cloni da un server, Git ha tutte le informazioni necessarie nella .gitdirectory per creare la tua copia di lavoro.


1

Un'altra differenza tra i repository --bare e Working Tree è che nel primo caso non vengono memorizzati commit persi, ma vengono memorizzati solo i commit che appartengono a una traccia branch . D'altra parte, Working Tree mantiene tutti gli impegni per sempre. Vedi sotto...

Ho creato il primo repository (nome: git-bare ) con git init --bare. È il server. È sul lato sinistro, dove non ci sono rami remoti perché questo è il repository remoto stesso.

Ho creato il secondo repository (nome: git-working-tree ) con git clonedal primo. E 'sulla destra. Ha filiali locali collegate a filiali remote.

(I testi "primo", "secondo", "terzo", "quarto", "alfa", "beta" e "delta" sono i commenti di commit. I nomi "master" e "greco" sono nomi di rami.)

Repository locali e remoti

Ora eliminerò il ramo chiamato 'greco' sia in git-bare (comando :) chegit push --delete origin greek localmente in git-working-tree (comando:) git branch -D greek. Ecco come appare l'albero:

Il repository git-bare elimina ciò a cui non si fa più riferimento

Il repository git-bare elimina sia il ramo che tutti i comits referenziati. Nella foto vediamo che il suo albero è stato ridotto per questo motivo.

D'altra parte, il repository git-working-tree , che è equivalente a un repository locale comunemente usato, non elimina i commit, che ora possono essere referenziati direttamente dall'hash con un git checkout 7fa897b7comando. Ecco perché il suo albero non ha una struttura modificata.

IN BREVE: i commit non vengono mai eliminati nei repository dell'albero di lavoro , ma vengono eliminati nei repository nudi .

In termini pratici, è possibile ripristinare un ramo eliminato sul server solo se esiste in un repository locale.

Ma è molto strano che la dimensione del repository nudo non diminuisca nella dimensione del disco dopo aver eliminato un ramo remoto. Cioè, i file sono ancora lì in qualche modo. Per scaricare il repository eliminando ciò a cui non si fa più riferimento o a cui non si può mai fare riferimento (quest'ultimo caso) utilizzare il git gc --prunecomando


Per testare i comandi git prova: github.com/sergiocabral/App.GitPlayground
Sergio Cabral
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.