2012-10-23 10 views
7

Ci sono due scenari che mi interessano.Sono possibili operazioni simultanee con i repository Git?

  • Il repository è condivisa e due utenti vuole spingere modifiche ad esso allo stesso tempo
  • voglio pianificare un "gc" notte o settimanale usando un lavoro cron. Corre e qualcuno vuole spingere o clonare durante l'operazione.

C'è un rischio di corruzione in uno di questi scenari?

+0

Per il numero 1, presumo che tu stia parlando di spinte simultanee a diversi rami? Spinte simultanee allo stesso ramo viene risposto altrove su SO. – cmbuckley

+0

puoi fornire un link? – dromodel

+2

[q8424232] (http: // stackoverflow.com/domande/8424232/sono-concurrent-git-spinge-sempre-safe-se-il-secondo-push-solo-ha-fast-forward); [q6028141] (http://stackoverflow.com/questions/6028141/concurrent-git-pull-and-push-on-same-remote-repo-from-different-locations) potrebbe essere anche interessante. – cmbuckley

risposta

7

Git consente operazioni simultanee utilizzando un Pessimistic Concurrency Control.

Se necessario, git crea alcuni file speciali che fungono da blocchi.

In particolare, ogni volta che l'indice viene modificato da un'operazione, git crea un file denominato index.lock nella directory .git per bloccare la risorsa condivisa. Git crea a necessità altri file di blocco: ad esempio, un file .keep viene creato durante le operazioni git index-pack.

In generale, non ci si deve preoccupare delle operazioni simultanee con git: è progettato con cura per supportarle.

Qualcuno potrebbe dire che non dovresti preoccuparti di eseguire gc con un cron job, dato che git stesso attiva di tanto in tanto gc. Anche se questo è vero, la stessa man page raccomanda:

Users are encouraged to run this task on a regular basis 
within each repository to maintain good disk space utilization 
and good operating performance. 

Quindi, penso che non è una cattiva idea quella di pianificare un'attività di lavoro per eseguire la raccolta dei rifiuti di git. Mi chiedo solo se si tratta di un'ottica prematura o se stai cercando di risolvere un problema reale e misurato. Personalmente non ho mai avuto problemi che mi richiedessero di eseguire manualmente lo gc, ma non sarei sorpreso se il tuo caso fosse abbastanza diverso.

2

In generale, "git gc" può eliminare oggetti che un altro processo concorrente utilizza ma non ha creato un riferimento a.
Git 2.12 (1 ° trim. 2017) ha di più su questo.

Vedi commit f1350d0 (15 nov 2016) di Matt McCutchen (mattmccutchen).
(fusa per Junio C Hamano -- gitster -- in commit 979b82f 10 Gen 2017)

E vedere Jeff King's comment:

versioni moderne di git fare due cose per aiutare con questo:

  • qualsiasi oggetto a cui fa riferimento un oggetto "recente" (entro le 2 settimane) è considerato anche recente.Quindi, se si crea un nuovo impegno oggetto che punta ad un albero, prima ancora che si fa riferimento il commit quell'albero è protetto

  • quando uno scrittura oggetto è ottimizzato fuori perché abbiamo già l'oggetto , git aggiornerà il mtime sul file (oggetto allentato o packfile) per rinfrescare lo

Questo non è perfetto, però. È possibile decidere di fare riferimento a un oggetto esistente così come viene eliminato. E il processo di sfoltimento in sé è non atomico (ed è complicato farlo così, solo per quello che ci viene promesso dal filesystem ).

Se si dispone di dati a esecuzione prolungata (ad esempio, un file di indice temporaneo che potrebbe contenere letteralmente in giro per giorni o settimane), penso che questo sia un potenziale problema . E la soluzione è probabilmente quella di utilizzare i ref in qualche modo per puntare ai tuoi oggetti.
Se sei preoccupato per un'operazione a breve termine in cui si verifica l'esecuzione di git-gc in qualche caso, sono d'accordo che è possibile un problema , ma sospetto qualcosa che puoi ignorare nella pratica.

Per un server multiutente occupato, è consigliabile disattivare completamente l'auto-gc, e reimballare manualmente con "-k" per sicurezza.

questo motivo git gc man page ora include:

D'altra parte, quando 'git gc' corre in concomitanza con un altro processo, v'è un rischio che l'eliminazione di un oggetto che l'altro processo sta utilizzando ma non ha creato un riferimento a. Ciò potrebbe causare l'errore dell'altro processo o danneggiare il repository se l'altro processo in seguito aggiunge un riferimento all'oggetto eliminato.

Git ha due caratteristiche che mitigano notevolmente questo problema:

  • Ogni oggetto con data di modifica più recente rispetto alla data di --prune è mantenuto, insieme a tutto raggiungibile da esso.

  • La maggior parte delle operazioni che aggiungono un oggetto al database aggiornano l'ora di modifica dell'oggetto se è già presente in modo che sia applicabile il numero 1 .

Tuttavia, queste caratteristiche a corto di una soluzione completa, quindi gli utenti che comanda eseguire contemporaneamente devono vivere con qualche rischio di corruzione (che sembra essere bassa, in pratica) a meno che non si spengono spazzatura automatica raccolta con 'git config gc.auto 0'.

Problemi correlati