2016-05-25 15 views
8

Dopo aver riscritto la cronologia di un repository con git filter-branch, vengono modificati tutti gli SHA.Repository con i sottomoduli dopo la riscrittura della cronologia del sottomodulo

Ora, se quel repository (chiamiamolo X) viene utilizzato come sottomodulo git in un altro repository (chiamiamolo Y), abbiamo un problema.
Infatti, Y sa quale versione del sottomodulo X caricare in base allo SHA del commit in tale sottomodulo. Poiché tutti gli SHA in X sono stati modificati, i punti Y vengono convertiti in SHA che non esistono più.

C'è un modo per riscrivere la cronologia di Y in modo che punti ai nuovi SHA di commit del sottomodulo X (sia in commit correnti che passati)?

Immagino che data una corrispondenza tra vecchi SHA e nuovi, questo è possibile in linea di principio, ma temo che possa comportare brutti script di bash.
C'è qualcosa di più semplice?

risposta

7

ma temo che possa comportare brutti script di bash.

Ho paura che lo faccia.

C'è qualcosa di più semplice?

Non che io sappia.
Qui ci sono alcuni indizi (non uno script a tutti gli effetti) di quello che si avrebbe bisogno per questo script funzioni:

Se hai ancora accesso al repo riscritto, la sua storia originale (prima il filtro-ramo) è mantenuto in .git/refs/original.

Questo significa che è possibile ciclo per quella vecchia storia SHA1:

git -C /path/to/rewritten/repo for-each-ref --format="%(refname)" refs/original 

Se i cambiamenti sono stati limitati a un ramo, si può abbinare facilmente la nuova SHA1 con quello vecchio (il primo vecchio corrisponde al primo commit del ramo riscritto, il secondo vecchio ... e così via)

in caso contrario, si dovrebbe cercare un giri al fine di trovare una corrispondenza (stessa data, Sane messaggio di commit)

git rev-list --all \ 
    | while read commit 
do 
... 

Assicurarsi che il repo genitore aggiorna i suoi arbitri per il modulo:

cd parent/repo 
cd asubmodule 
git fetch 

In questo modo, il nuovo SHA1 sono disponibili.

Infine, si può fare un filtro-ramo nel repository genitore, alla ricerca di un gitlink, special entry in the index, abbinando uno dei vecchi SHA1.

Per ogni partita, si controlla il nuovo SHA1 nella cartella del sottomodulo, si torna indietro di un livello fino al repository padre, add e commit: questo registrerà un nuovo gitlink SHA1.

cd parent/repo/asubmodule 
git checkout <new SHA1> 
cd .. 
git add . 
git commit -m "Record new SHA1 for asubmodule"