Spostamento del contenuto del repository Git in un altro repository per preservare la cronologia


141

Sto cercando di spostare solo i contenuti di un repository ( repo1) in un altro repository esistente ( repo2) utilizzando i seguenti comandi:

git clone repo1
git clone repo2
cd repo1
git remote rm origin
git remote add repo1
git push

Ma non funziona. Ho recensito un post simile, ma ne ho trovato solo uno che sposta la cartella, non il contenuto.


Vuoi avere il contenuto di repo1 come un ramo su repo2 o come parte del master, in modo che le cartelle di entrambi i repository coesistano nella tua directory di lavoro?
Cronologico

Voglio spostarlo come parte del maestro.
Mario,

4
Questo tutorial è perfetto! smashingmagazine.com/2014/05/19/…
xpto

Risposte:


242

Penso che i comandi che stai cercando siano:

cd repo2
git checkout master
git remote add r1remote **url-of-repo1**
git fetch r1remote
git merge r1remote/master --allow-unrelated-histories
git remote rm r1remote

Dopodiché repo2/masterconterrà tutto da repo2/mastere repo1/master, e avrà anche la storia di entrambi.


Grazie Chronial, voglio solo assicurarmi che il repo1 abbia anche un ramo e cosa succede se voglio spostare quel ramo anche su repo2?
Mario,

bene, repo2 ha anche un secondo ramo? O cosa dovrebbe succedere a quel ramo?
Cronologico

1
Chronial, i comandi sopra non funzionavano! non ha copiato la storia.
Mario

1
OK, ora ha funzionato. Ho usato il seguente comando; cd repo2,> git remote rm origin> git remote aggiungi origin url-of-repo1 ,> git fetch r1remote> git push origin master
Mario

1
@abhijithda La soluzione più semplice sarebbe quella di spostare tutto dentro repo1una sottocartella (dentro repo1) prima di fare l'unione.
Cronologico

55

Perfettamente descritto qui https://www.smashingmagazine.com/2014/05/moving-git-repository-new-server/

Innanzitutto, dobbiamo recuperare tutti i rami e tag remoti dal repository esistente al nostro indice locale:

git fetch origin

Siamo in grado di verificare eventuali rami mancanti di cui abbiamo bisogno per creare una copia locale di:

git branch -a

Usiamo l'URL clonato SSH del nostro nuovo repository per creare un nuovo telecomando nel nostro repository locale esistente:

git remote add new-origin git@github.com:manakor/manascope.git

Ora siamo pronti per inviare tutti i rami e tag locali al nuovo telecomando chiamato new-origin:

git push --all new-origin 
git push --tags new-origin

Rendiamo new-origin il telecomando predefinito:

git remote rm origin

Rinomina new-origin in solo origin, in modo che diventi il ​​telecomando predefinito:

git remote rename new-origin origin

4
Può confermare che questo copia l'intera cronologia e tag. Molto bella. Grazie.
Alex,

Se la nuova origine non ha alcun commit, funziona bene. Tuttavia, se c'è un commit nella nuova origine, il modo menzionato qui non si esprimerà come previsto.
Caot

devi cambiare git checkout BranchNamei rami con poi spingere nuovamente il ramo nel repository remoto con git push --all new-origin ma grazie mille
Raad Altaie

21

Se stai cercando di preservare le filiali esistenti e impegnare la cronologia, ecco un modo che ha funzionato per me.

git clone --mirror https://github.com/account/repo.git cloned-repo
cd cloned-repo
git push --mirror {URL of new (empty) repo}

# at this point only remote cloned-repo is correct, local has auto-generated repo structure with folders such as "branches" or "refs"
cd ..
rm -rf cloned-repo
git clone {URL of new (empty) repo}
# only now will you see the expected user-generated contents in local cloned-repo folder

# note: all non-master branches are avaialable, but git branch will not show them until you git checkout each of them
# to automatically checkout all remote branches use this loop:
for b in `git branch -r | grep -v -- '->'`; do git branch --track ${b##origin/} $b; done

Supponiamo ora di voler sincronizzare i repository di origine e destinazione per un periodo di tempo. Ad esempio, c'è ancora attività all'interno del repository remoto corrente che si desidera trasferire al repository nuovo / sostitutivo.

git clone -o old https://github.com/account/repo.git my-repo
cd my-repo
git remote add new {URL of new repo}

Per rimuovere gli ultimi aggiornamenti (supponendo che non ci siano modifiche locali):

git checkout {branch(es) of interest}
git pull old
git push --all new

NB: Devo ancora usare i sottomoduli, quindi non so quali passi aggiuntivi potrebbero essere richiesti se li hai.


1
Questo ha funzionato semplicemente e facilmente per me. Penso che dovrebbe essere la risposta verificata. Se hai 60 filiali, questa è la strada da percorrere.
rickfoosusa,

7

Approccio più semplice se il codice è già tracciato da Git, quindi impostare un nuovo repository come "origine" su cui inviare.

cd existing-project
git remote set-url origin https://clone-url.git
git push -u origin --all
git push origin --tags

6

Questo ha funzionato per spostare il mio repository locale (inclusa la cronologia) sul mio repository remoto github.com. Dopo aver creato il nuovo repository vuoto su GitHub.com, utilizzo l'URL nel passaggio tre di seguito e funziona benissimo.

git clone --mirror <url_of_old_repo>
cd <name_of_old_repo>
git remote add new-origin <url_of_new_repo>
git push new-origin --mirror

L'ho trovato su: https://gist.github.com/niksumeiko/8972566


1
Questo è il modo più semplice per consentire al repository originale. Copia anche tutti i rami.
Guillermo,

1
Questo copia anche tutti i tag.
corvo

2

Ho usato il metodo seguente per migrare il mio GIT Stash su GitLab mantenendo tutti i rami e la cronologia del commit.

Clonare il vecchio repository su local.

git clone --bare <STASH-URL>

Crea un repository vuoto in GitLab.

git push --mirror <GitLab-URL>

1

Sembra che tu sia vicino. Supponendo che non sia solo un refuso nella tua presentazione, il passaggio 3 dovrebbe esserecd repo2 invece di repo1. E il passaggio 6 non dovrebbe essere git pullpush. Elenco rielaborato:

1. git clone repo1
2. git clone repo2
3. cd repo2
4. git remote rm origin
5. git remote add repo1
6. git pull
7. git remote rm repo1
8. git remote add newremote

Grazie Eric, ma nel passaggio 3 voglio rimuovere il collegamento del repository originale per evitare di apportare modifiche remote .. come voglio spostare i contenuti da repo1 a repo2.
Mario,

Tutto a posto. Ho modificato la mia risposta per cercare di riflettere questo. Solo per essere sicuri, stai cercando di creare un repository, repo2, che è una copia di repo1 ma non conserva repo1 o origine come telecomandi?
Eric Palace,

No, non sto cercando di creare un nuovo repository "repo2". In realtà, ho un repo2 esistente che ha altri contenuti init. Ora voglio spostare tutti i contenuti di repo1 in repo2 con la cronologia. Terrò vuoto il repo1 così com'è nel server.
Mario,

Hai considerato di non usare git? Sembra che potresti semplicemente copiare i file (tramite una gui o scp o ftp) e aggiungerli manualmente al tuo repository git. Potrebbe non essere così efficiente, ma è probabilmente più semplice.
Eric Palace,

L'ho già provato ma ha lasciato la storia. Voglio spostare anche tutta la sua storia.
Mario,

1

Secondo la risposta di @ Dan-Cohn Mirror-push è il tuo amico qui. Questo è il mio passo per migrare i repository:

Mirroring di un repository

1.Aprire Git Bash.

2.Creare un clone nudo del repository.

$ git clone --bare https://github.com/exampleuser/old-repository.git

3.Mirror-push nel nuovo repository.

$ cd old-repository.git
$ git push --mirror https://github.com/exampleuser/new-repository.git

4.Rimuovere il repository locale temporaneo creato nel passaggio 1.

$ cd ..
$ rm -rf old-repository.git

Riferimento e credito: https://help.github.com/en/articles/duplicating-a-repository


-1

Ci sono molte risposte complicate, qui; tuttavia, se non si è interessati alla conservazione dei rami, è sufficiente reimpostare l'origine remota, impostare l'upstream e premere.

Questo ha funzionato per preservare tutta la cronologia degli commit per me.

cd <location of local repo.>
git remote set-url origin <url>
git push -u origin master
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.