2012-01-19 15 views
17

Voglio clonare il repository del kernel di Linux, ma solo dalla versione 3.0 in poi, poiché il repo del kernel è così grande che rende i miei strumenti di versionamento più veloci se riesco a fare un clone poco profondo. Il nocciolo della mia domanda è: come posso dire a git quale sia il valore "n" per il parametro --depth? Speravo che questo avrebbe funzionato:git shallow clone al tag specifico

git clone http://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git --depth v3.0

grazie.

+0

Vedere anche [Come rimuovere la cronologia precedente da un repository git?] (Http://stackoverflow.com/questions/4515580/how-do-i-remove-the-old-history-from-a- git-repository) – Alberto

risposta

2

Sfortunatamente il parametro --depth di git clone accetta solo un numero, il numero di revisioni su cui il repository di clonazione deve essere troncato.

Una possibile soluzione è quella di clonare l'intero repository e quindi troncarne la cronologia per mantenere solo i commit dopo la v3.0. Ecco un buon how-to: http://bogdan.org.ua/2011/03/28/how-to-truncate-git-history-sample-script-included.html

git checkout --orphan temp v3.0 
git commit -m "Truncated history" 
git rebase --onto temp v3.0 master 
git branch -D temp 
git gc 
+0

Questo dovrebbe funzionare come la soluzione che ho fornito, ma vorrei anche suggerire di cancellare tutti gli altri riferimenti locali e di eseguire i passaggi di pulizia che ho nella mia soluzione. Senza di ciò, il repository conterrà comunque la cronologia completa e gli oggetti extra. Con questo repository ci sono circa 2 milioni di oggetti in giro del necessario. – James

+0

Buona nota, aggiunta – tomgi

+0

Questa strategia richiede la gestione di conflitti in conflitto e corre il rischio di produrre una copia non esatta del master finale a seconda di come vengono gestite le unioni. Poiché il repository è così grande è molto improbabile che si possano fare le unioni a mano in modo da poter aggiungere l'opzione '-Xours' o' -Xtheirs 'al comando rebase. Sono sicuro che troveresti che il risultato finale differisce dalla fonte del master ref. – James

7

Leggere completamente per una soluzione, ma purtroppo, git clone non funziona nel campo della moda si richiede. Il parametro --depth limita il numero di revisions non il numero di commits. Non esiste un parametro clone che limiti la quantità di commit. Nella tua situazione, anche se sapessi che ci sono state al massimo 10 differenze di revisione dal file che è cambiato di più tra la versione 3.0 e la più recente HEAD nel repository e utilizzato --depth 10 potresti ancora ottenere la maggior parte o l'intera cronologia dei pronti contro termine. Poiché alcuni oggetti potrebbero non avere un massimo di 10 revisioni e la loro cronologia verrà riportata all'inizio della loro prima apparizione nel repository.

Ora ecco come fare ciò che ti piace: La chiave del tuo problema è che ti serve il commit tra la versione 3.0 e la più recente recente che desideri. Ecco i passi che ho fatto a fare proprio questo:

  • git clone http://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git --depth 10075 smaller_kernel_repo
  • cd smaller_kerenel_repo
  • Determinare la sha di v3.0 git log --oneline v3.0^..v3.0
  • creare un punto di innesto a partire da questa sha (è 02f8c6aee8df3cdc935e9bdd4f2d020306035dbe)
  • echo "02f8c6aee8df3cdc935e9bdd4f2d020306035dbe" > .git/info/grafts
  • Per aggirare alcuni problemi con alcune voci del registro del kernel fare: export GIT_AUTHOR_NAME="tmp" e export GIT_COMMITTER_NAME="tmp"

  • C'è una bella avviso circa nella pagina man su git filter-branch riscrivere la storia, seguendo i punti di innesto ... così lascia abuso che, ora gestito git filter-branch e sedersi e aspettare ... (e aspettare e Aspettiamo)

Ora è necessario ripulire tutto:

git reflog expire --expire=now --all 
git repack -ad # Remove dangling objects from packfiles 
git prune  # Remove dangling loose objects 

Questo processo richiede molto tempo, ma non molto complesso. Spero che ti risparmi tutto il tempo che speravi a lungo termine. A questo punto si avrà essenzialmente un repository con una cronologia modificata di solo v3.0 in poi dal repository linux-stable.git.Proprio come se si usasse lo --depth su clone si hanno le stesse restrizioni sul repository e si potranno modificare e inviare patch solo dalla cronologia che si ha già. Ci sono modi per aggirare questo problema .. ma merita il proprio Q & A.

Sono in procinto di testare gli ultimi passaggi da solo, ma l'operazione git filter-branch è ancora in corso. Aggiornerò questo post con qualsiasi problema, ma andrò avanti e pubblicarlo in modo da poter iniziare questo processo se lo trovi accettabile.

UPDATE

Soluzione di problema (fatale: vuoto ident <> non è consentito). Questo problema deriva da un problema nella cronologia del commit del repository di Linux.

cambiare il comando git filter-branch a:

git filter-branch --commit-filter ' 
    if [ "$GIT_AUTHOR_EMAIL" = "" ]; 
    then 
      GIT_AUTHOR_EMAIL="[email protected]"; 
      GIT_AUTHOR_NAME='tmp' 
      GIT_COMMITTER_NAME='Me' 
      GIT_COMMITTER_EMAIL='[email protected]' 
      git commit-tree "[email protected]"; 
    else 
      git commit-tree "[email protected]"; 
    fi ' 
+1

Penso che complicare troppo le cose per distinguere rigorosamente tra * revision * e * commit * qui. Mentre sono a conoscenza della [differenza formale] (http://stackoverflow.com/a/11792712/1127485), nel contesto di 'git clone --depth ' il numero di revisioni è uguale al numero di commit dal suggerimenti. – sschuberth

0

Il parametro --depth sembra essere solo un numero (il "specificata numero di revisioni"), non è un tag.

possibile idea (da testare):

Si potrebbe utilizzare git describe anche se al fine di ottenere l'etichetta più recente da voi attuale capo, così come il numero di commit tra detti tag e HEAD.
Se il "tag più recente" non è il tag, è sufficiente ripetere il processo, a partire dal commit a cui fa riferimento l'ultimo tag, fino a trovare il tag (v3.0 nel tuo caso, ad esempio).

La somma di tutti quei numeri di commit fornirà la profondità da dare al comando git clone, purché il tag sia accessibile dall'attuale HEAD.

17

Che ne dici di clonare il tag su una profondità di 1?

  • git clone --branch mytag0.1 --depth 1 https://example.com/my/repo.git
+0

In che modo ** NON ** è la risposta accettata? – tftd

1

Per chi ha già un clone questo comando ottenere il numero di commit tra la punta del ramo di corrente e il tag 5.6:

$ git rev-list HEAD ^5.6 --count 
407 

ho trovato questo progetto di attuazione rev-list utilizzando l'API GitHub: https://github.com/cjlarose/github-rev-list

La pagina man molto lunga su rev-list indica che c'è molto da fare dietro le quinte. Esistono molti percorsi diversi per poter contare i commit attraverso i rami e le fusioni vanno e vengono. (?) Per questo caso l'uso però che probabilmente può essere ignorato

0

Per rendere @ n8henrie rispondere a un po 'più completo, è possibile aggiungere l'opzione --single-branch, in questo modo:

git clone --single-branch --branch mytag0.1 --depth 1 https://example.com/my/repo.git 

In questo stato si ottiene solo gli oggetti repository relativi a questo particolare tag, che nella mia esperienza, in molti casi, risparmiano molto spazio.Da git-clone docs:

- [no-] singolo ramo

Clone solo la storia che porta alla punta di un singolo ramo, sia specificato dall'opzione --branch o HEAD punti del telecomando ramo primario a. Ulteriori recuperi nel repository risultante aggiorneranno solo il ramo di tracciamento remoto per il ramo questa opzione è stata utilizzata per la clonazione iniziale. Se il HEAD sul remoto non puntava a nessun ramo quando è stato creato il clone --single-branch, non viene creato alcun ramo di localizzazione remota.

Una nota ulteriore: se si sta clonando un repo locale da un'altra cartella sullo stesso computer, è necessario fare riferimento ad esso utilizzando il protocollo file://, invece di specificare solo il nome della cartella.