2010-03-23 3 views
23

Stiamo migrando da Subversion a Mercurial. Per facilitare la migrazione, stiamo creando un repository Mercurial intermedio che è un clone del nostro repository Subversion. Tutti gli sviluppatori inizieranno il passaggio al repository Mercurial e periodicamente trasferiremo le modifiche dal repository Mercurial intermedio al repository Subversion esistente. Dopo un periodo di tempo, sarà semplicemente obsoleto il repository Subversion e il repository Mercurial intermedio diventerà il nuovo sistema di record.Mercurial to Mercurial to Subversion Workflow Problem

Dev 1 Local --+--> Mercurial --+--> Subversion 
Dev 2 Local --+    + 
Dev 3 Local --+    + 
Dev 4 -------------------------+ 

Ho testato questo fuori, ma io continuo a correre in un problema quando spingo cambiamenti dal mio repository locale, al repository Mercurial intermedio, e poi su nel nostro repository Subversion.

alt text http://bmurphy.mediafly.com.s3.amazonaws.com/images/mercurial/01.png

sulla mia macchina locale, ho un changeset che è impegnato e pronto per essere spinto al nostro repository Mercurial intermedio. Qui si può vedere che è la revisione # 2263 con hash 625 ...

alt text http://bmurphy.mediafly.com.s3.amazonaws.com/images/mercurial/02.png

ho solo spingere questo changeset al repository remoto.

alt text http://bmurphy.mediafly.com.s3.amazonaws.com/images/mercurial/03.png

Finora, tutto sembra buono. Il changeset è stato spinto.

hg update 
1 files updated, 0 files merged, 0 files removed, 0 files unresolved 

Ora passo al repository remoto e aggiorno la directory di lavoro.

hg push 
pushing to svn://... 
searching for changes 
[r3834] bmurphy: database namespace 
pulled 1 revisions 
saving bundle to /srv/hg/repository/.hg/strip-backup/62539f8df3b2-temp 
adding branch 
adding changesets 
adding manifests 
adding file changes 
added 1 changesets with 1 changes to 1 files 
rebase completed 

Successivamente, sposto la modifica fino a Subversion, funziona perfettamente. A questo punto, la modifica è nel repository Subversion e restituisco l'attenzione al mio client locale.

alt text http://bmurphy.mediafly.com.s3.amazonaws.com/images/mercurial/04.png

tiro modifiche alla mia macchina locale. Eh? Ora ho due changeset. Il mio changeset originale appare ora come un ramo locale.

alt text http://bmurphy.mediafly.com.s3.amazonaws.com/images/mercurial/05.png

L'altro changeset ha un nuovo numero di revisione 2264, e un nuovo hash 10c1 ...

alt text http://bmurphy.mediafly.com.s3.amazonaws.com/images/mercurial/06.png

Comunque, aggiorno il mio repo locale alla nuova revisione.

alt text http://bmurphy.mediafly.com.s3.amazonaws.com/images/mercurial/07.png

che sto ora commutato.

alt text http://bmurphy.mediafly.com.s3.amazonaws.com/images/mercurial/08.png

Così, ho finalmente fare clic sul "determinare e segnare di modifiche in uscita" e come si può vedere Mercurial vuole ancora spingere i miei gruppi di modifiche precedenti, anche se hanno già spinto.

Chiaramente, sto facendo qualcosa di sbagliato.

Inoltre non riesco a unire le due revisioni.Se unisco le due revisioni sul mio computer locale, finisco con un "merge" commit. Quando spingo tale unione a eseguire il commit nel repository Mercurial intermedio, non posso più inviare modifiche al nostro repository Subversion. Io alla fine con il seguente problema:

hg update 
0 files updated, 0 files merged, 0 files removed, 0 files unresolved 

hg push 
pushing to svn://... 
searching for changes 
abort: Sorry, can't find svn parent of a merge revision. 

e devo rollback l'unione per tornare a uno stato funzionante.

Cosa mi manca?

+7

Tutte le immagini sono rotti: - \ –

risposta

22

Non stai facendo nulla di sbagliato, in realtà nella tua situazione il comportamento che stai vedendo è il risultato atteso (anche se un po 'confuso per un nuovo utente Mercurial).

hgsubversion è veramente buono per due cose:

  1. utilizzando Mercurial come client per Subversion, senza scambiare modifiche al di fuori di svn
  2. Conversione repository Subversion a Mercurial

Stai cercando usarlo come un gateway più generalizzato, che è un problema molto più difficile. La sovversione ha una visione molto rigida del mondo e dobbiamo lavorare al suo interno. La verità è che l'hash di revisione può essere visto come definitivo solo quando si usa hgsubversion dopo che la revisione è stata estratta da Subversion. Pertanto, se i tuoi sviluppatori condividono direttamente i changeset tra i repository Mercurial, senza Subversion come intermediario, ciò avverrà.

Il rebase è automatico e non facoltativo per un motivo molto fondamentale: Subversion esegue tale rebase quando si preme. Se avevi delle modifiche non tagliate quando avevi premuto, Subversion ti ha fatto il rebase e, in caso di successo (con un algoritmo di rebasing stupidamente semplice) accetta il commit senza alcuna indicazione che si sia verificato un rebase. Stiamo mettendo insieme due modelli diversi.

Suggerirei di trasferire tutti a Mercurial in una volta sola - un approccio ibrido come questo renderà Mercurial più difficile a breve termine di quanto dovrebbe essere, e potenzialmente confonderà gli utenti di nuovo in DVCS.

+2

@dalroth avrà bisogno di un processo come questo: l'utente spinge r1: r2 a hg-gateway, hg-gateway deve automaticamente passare a subversion, l'utente deve ora pull, e infine l'utente deve 'hg strip r1' – Harvey

+0

@Harvey - Can I ottenere un chiarimento? Ho una squadra che vorrebbe passare a hg, ma svn governa la terra desolata qui. Se impostiamo un master hg repo, e solo spingiamo a/pull dal master svn da lì, andrà tutto bene? Versione più lunga: il mio capo sarebbe d'accordo con noi passare a hg, ma solo se una squadra fa prima un programma pilota. C'è abbastanza codice comune (per non parlare del fatto che la macchina di compilazione sta ancora eseguendo svn) che passare a hg completamente è fuori questione. – moswald

+1

@mos: Funzionerà, in effetti, è ciò che faccio personalmente. Il trucco è imparare il workflow svn modificato hg <-> hgsubversion <->. Una volta che "ottieni" come funziona, non avrai problemi. Dovrai semplicemente digitare qualche altro comando. In realtà ho iniziato a scrivere script per rendere più semplice il processo (che è ripetitivo). Flusso tipico: [in "hg" repo] commettono un sacco di modifiche; spingerli a "hsububversion"; [passa a "hgsubversion"] hg update (hgsubversion ha bisogno di questo); hg push su "svn" (che si riavvia automaticamente dopo aver premuto e rimosso localmente i changeset); ... continua ... – Harvey

3

In primo luogo, lasciami dire che piacere leggere una domanda così dettagliata. :)

Il problema si verifica quando si esegue il comando hg push dal repository svn da remoto. Ecco che l'uscita dal vostro esempio:

hg push 
pushing to svn://... 
searching for changes 
[r3834] bmurphy: database namespace 
pulled 1 revisions 
saving bundle to /srv/hg/repository/.hg/strip-backup/62539f8df3b2-temp 
adding branch 
adding changesets 
adding manifests 
adding file changes 
added 1 changesets with 1 changes to 1 files 
rebase completed 

io non sono un utente HG-sovversione, ma che la produzione dice che nel processo di fare la spinta che avete richiesto, è tirare le modifiche dal repository svn, trovare un nuova revisione e quindi facendo un rebase del tuo changeset 10c1 dopo (discendente di) la revisione appena estratta. Lo rebase command prende le storie delle diramazioni e trasforma le storie in una storia lineare, ma in tal modo cambia i genitori dei changeset, che cambiano i loro hash, che assomigliano a quello che ti sta succedendo.

Anche in questo caso, non è un utente di HG-sovversione, quindi non posso dire se quel tiro/rebase è sempre dovrebbe accadere e come questo dovrebbe funzionare, ma la pagina hgsubversion wiki dice:

È può usare i consueti comandi Mercurial per lavorare con questo repository. Se si dispone di una serie di commit su un determinato settore , e desidera spostare loro di la punta di quel ramo, utilizzare la hg rebase comando --svn mentre sulla punta del vostro lavoro, e quelli di modifiche volontà viene automaticamente ridefinito sopra del nuovo lavoro upstream.

che rende il suono non normalmente automatico.

Non riesco a capire dalla tua introduzione, sono ancora creati nuovi changeset in svn o creati solo in mercurial?

Se vengono creati solo in mercurial, una soluzione potrebbe essere quella di impostare un repository svn-gateway sul sistema remoto, e fare il push da lì, e non tirare mai da quel repo in mercuriale. Quindi i changeset in quel repository avrebbero hashid diversi a causa del rebase, ma non tornerebbero al repository remoto principale e ai sistemi dell'utente finale.

La soluzione più grande è capire perché "hg push svn: // .. sta ridefinendo tutti i changeset in uscita". Rispondi a questo e il comportamento si fermerà.

+0

Ho provato a guardare più da vicino a questo, ma ancora senza fortuna. Non riesco a trovare un modo per hg push dal repository intermedio senza fare automaticamente un rebase, e hg rebase --svn non fa nulla perché è già nella versione più recente. – bmurphy1976

+0

Sì, parla ai ragazzi di hg-sovversione sul perché sta facendo un rebase e se può essere evitato. Temo di essere solo bravo per il lavoro in giro (cosa che fa la soluzione di 3 pronti contro termine). –

+0

@Dalroth, @ Ry4an: hgsubversion deve fare il rebase a causa di stranezze con sovversione. La soluzione definitiva sarebbe se hgsubversion potesse rilevare quando si crea un clone hg di un clone hgsubversion. Quindi, eseguirà le necessarie strisce downstream e rebase automaticamente. Io uso questo processo ora al lavoro. Funziona, ma devi abituarti. Diventa più complicato se il tuo clone di hgsubversion non viene aggiornato automaticamente con il server di subversion (perché devi estrarre SVN e poi rebase le modifiche sul nuovo suggerimento). – Harvey

1

Ora stiamo usando il comando di innesto per fare qualcosa di simile a questo. Effettivamente ricreamo ogni changeset prima di spingerlo per evitare di spingere i changeset di fusione.

Il nostro obiettivo è contribuire in modo pulito a un progetto che utilizza la sovversione.

  • Creare un ramo di sovversione per tutte le modifiche. Scaricalo in Mercurial.
    $ cd [svn-checkout] ; svn cp trunk branches/hg-bridge
    $ cd [hgsubversion bridge] ; hg pull ; hg update hg-bridge

  • Controlla la tua repo locale per i nuovi cambiamenti
    $ hg in [repo] # shows <rev> IDs you can use later

  • Tirare le modifiche che si desidera entrare in svn da un repo locale
    $ hg pull [repo]

  • Innestare tutte le modifiche che si desidera contribuire:
    $ hg graft [rev] [rev] # rev could be 645 or b7a92bbb0e0b. Best use the second>.
    è necessario specificare ogni giro individualmente,
    ma si può innestare più giri in un unico comando.

  • controllare ciò che spingerebbe:
    $ hg outgoing

  • Spingere le modifiche:
    $ hg push
    Questo potrebbe mostrano alcune revisioni tirato indipendenti
    e dovrebbero mostrare le nuove revisioni come tirato,
    insieme ai percorsi per il backup di pacchetti (che non dovrebbero essere necessari). (Il commento può essere utilizzato anche tu nder la GPLv2 o successiva)