Questa è solo un'idea, non ho testarlo per questo scenario ma l'ho usato (in un modo diverso) a join two Git
repositories and keep the original commit dates.
Se la cronologia ha diramazioni e fusioni, credo sia impossibile riordinarle e mantenere la struttura, anche manuale. Il meglio che puoi ottenere è una storia lineare.
Salva l'hash e il timestamp commit (%ct
= data, %at
= Data Autore commit) in un file, ordinarli per data autore:
$ git log --pretty='%H %at %ct' --author-date-order --reverse > /tmp/hashlist
Se l'ordine fornito dal comando di cui sopra non soddisfa È quindi forzare l'ordine di classificare l'uscita utilizzando il suo secondo campo (la data autore):
$ git log --pretty='%H %at %ct' | sort -k 2 > /tmp/hashlist
Creare un nuovo repository per contenere la storia ordinati per data di autore. Creare un primo commit impostazione della data committer in passato (prima il più vecchio commit nel repository):
$ GIT_COMMITTER_DATE='2010-01-01 12:00:00' GIT_AUTHOR_DATE='2010-01-01 12:00:00' git commit --allow-empty
mettere il proprio data nel comando precedente.
Aggiungere il vecchio repository come remoto in quello nuovo, recuperare tutti i suoi commit. NON impostare il ramo master
del nuovo repository per tenere traccia di quello del vecchio repository.
creare uno script che sarà ciliegia scegliere il previsto impegno e applicarla sulla parte superiore del ramo di corrente, mantenendo la data autore originale e la data commettere:
$ echo '[email protected]$2 [email protected]$3 git cherry-pick $1' > /tmp/pick
$ chmod +x /tmp/pick
Se non si desidera mantenere sia la la data originale dell'autore o la data del commit (o entrambi) rimuovono quindi il corrispondente incarico dalla riga di comando precedente.
Utilizzare il nuovo script con xargs
per selezionare ogni commit nell'ordine selezionato e confermarlo sopra il nuovo ramo master.
$ cat /tmp/hashlist | xargs -n 3 /tmp/pick
Se tutto è andato bene, rimuovere i file temporanei creati durante il processo.
$ rm /tmp/hashlist
$ rm /tmp/pick
Osservazione:
- Si otterrà una storia lineare. I rami e le fusioni originali non verranno ricreati nella nuova cronologia della cronologia.
- I rami non raggruppati non verranno affatto copiati. È possibile utilizzare
git rebase
per copiarli e allegarli ai nuovi commit.
- Anche se il repository non ha diramazioni, c'è ancora un'alta probabilità di ottenere conflitti su scelte piccanti; dipende molte delle modifiche introdotte dai commit nel nuovo ordine.
- Se non funziona, è sempre possibile rimuovere il nuovo repository e ricominciare (o uscire provando); il vecchio repository non è cambiato.
La tua idea sembra logica. I cherry-pick sono in esecuzione ora. Sperando in assenza di conflitti/minori – Blitzkr1eg
Hai avuto molti conflitti, quindi ho abbandonato questo approccio. Quindi li lascioi A1-A2-A3-B1-B2-B3-C1-C2-C3 come se fossero dopo l'unione. – Blitzkr1eg
Quando crea un diff, 'git' registra non solo le linee modificate ma anche il contesto del cambiamento (1 riga prima e 1 riga dopo il cambiamento). Usa queste linee quando applica una diff per assicurarsi che il diff possa essere applicato in sicurezza. Se le linee di contesto non corrispondono (ad esempio perché sono state aggiunte/modificate da un commit che era precedente nella linea temporale originale ma si desidera applicare successivamente nella linea temporale modificata) viene visualizzato un conflitto. Sfortunatamente risolvere i conflitti automaticamente non è sicuro. Se si verificano molti conflitti, è possibile che non sia possibile modificare l'ordine dei commit. – axiac