Come posso tornare a una versione precedente del nostro codice in Subversion?

StackOverflow https://stackoverflow.com/questions/814433

  •  03-07-2019
  •  | 
  •  

Domanda

Sto lavorando a un progetto con un amico e voglio tornare a una versione precedente del nostro codice e impostarlo come corrente. Come lo faccio?

Sto usando " anksvn " su vs08.

Ho la versione che desidero sul mio PC, ma il commit non riesce; Il messaggio che ricevo è " commit non riuscito, file o directory non aggiornati. "

Ho anche il client Subversion sul mio PC.

È stato utile?

Soluzione

Fondamentalmente devi " unire all'indietro " - applica una diff tra la versione corrente e precedente in alla versione corrente (così finisci con una copia funzionante che assomiglia alla vecchia versione) e poi esegui nuovamente il commit. Quindi, ad esempio, per passare dalla revisione 150 (attuale) alla revisione 140:

svn update
svn merge -r 150:140 .
svn commit -m "Rolled back to r140"

Il libro rosso Subversion ha un buona sezione su questo .

Altri suggerimenti

Puoi solo applicare nuove modifiche nella head della cronologia delle sovversioni.

Il motivo per cui non puoi fare nulla direttamente con la buona copia che hai sul tuo PC, è che le sue cartelle .svn sanno che è un codice del passato, quindi richiede un aggiornamento prima di qualsiasi commit.

Trova il numero di revisione valido e ripristina

  1. Trova il numero di revisione della vecchia copia che desideri. Ottieni la tua attuale revisione con:

    svn info --show-item revision
    # or
    svn log
    

    Oppure usa:

    svn update -r <earlier_revision_number>
    

    per controllare varie versioni precedenti del progetto, fino a trovare il numero di revisione corretto.

  2. Annota il numero di revisione valido (supponendo 123 per gli esempi seguenti).

  3. Aggiornamento all'ultima revisione:

    svn update
    
  4. Annulla tutte le modifiche tra la revisione desiderata e l'ultima versione:

    svn merge -r HEAD:123 .
    svn commit "Reverted to revision 123"
    

    (uguale alla risposta di Jon Skeet sopra.)

Se non riesci a trovare il numero di revisione

Se non riesci a trovare la vecchia copia e desideri semplicemente eseguire il commit dei file attualmente sul tuo PC:

  1. Crea una copia della tua versione valida (ma senza cartelle .svn ):

    cd ..
    rsync -ai --exclude=.svn  project/  project-good/
    
  2. Ora assicurati di avere l'ultima versione:

    cd project
    svn update
    # or make a fresh checkout
    svn checkout <url>
    
  3. Copia la tua versione valida sopra la copia di lavoro.

    Questo comando copia e cancella anche tutti i file dall'albero di lavoro che non sono nella tua buona copia, ma non influirà sulle cartelle .svn esistenti.

    cd ..
    rsync -ai --exclude=.svn --delete  project-good/  project/
    

    Se non hai rsync, puoi usare cp -a ma dovrai anche eliminare manualmente tutti i file indesiderati.

  4. Dovresti essere in grado di impegnare ciò che hai adesso.

    cd project
    svn commit "Reverted to good copy"
    

Usa questa linea

  

svn update -r yourOldRevesion

Puoi conoscere la tua attuale revisione usando:

  

informazioni svn

Il modo standard di usare l'unione per annullare l'intero check-in funziona alla grande, se è quello che vuoi fare. A volte, tuttavia, tutto ciò che vuoi fare è ripristinare un singolo file. Non esiste un modo legittimo per farlo, ma esiste un hack:

  1. Trova la versione che desideri utilizzando il registro svn.
  2. Usa il sottocomando di esportazione svn:

    svn export http: // url-to-your-file @ 123 / tmp / filename

(dove 123 è il numero di revisione per una buona versione del file.) Quindi spostare o copiare quel singolo file per sovrascrivere quello vecchio. Controlla il file modificato e il gioco è fatto.

Un po 'più vecchio stile

svn diff -r 150:140 > ../r140.patch
patch -p0 < ../r140.patch

quindi il solito

svn diff
svn commit

Penso che questo sia il più adatto:

Esegui l'unione all'indietro, ad esempio, se il codice di commit contiene la revisione da giri da 5612 a 5616, basta unirlo all'indietro. Funziona alla mia fine.

Ad esempio:

svn merge -r 5616:5612 https://<your_svn_repository>/

Conterrebbe un codice unito alla precedente revisione, quindi è possibile eseguirne il commit.

Questo è quello che ho fatto e lavorato per me.

Voglio annullare le modifiche in più commit che ho fatto per determinate volte e voglio passare al punto di commit precedente.

  1. Vai al team - > Mostra cronologia.
  2. Fai clic con il pulsante destro del mouse sull'intervallo di revisioni che desideri ignorare.
  3. Seleziona " Annulla modifiche " opzione.

Questo eseguirà un'unione inversa, annullando le modifiche nella tua copia di lavoro.

Rivedi il codice e esegui il commit.

Fai clic con il pulsante destro del mouse sulla gerarchia più alta che desideri ripristinare > > Ripristina o Ripristina revisione

Fai clic con il pulsante destro del mouse sul progetto > Sostituisci con > Revisione o URL > Seleziona la revisione specifica che desideri ripristinare.

Ora esegui il commit della versione del codice di aggiornamento locale nel repository. Ciò ripristinerà la base di codice alla revisione specifica.

La maggior parte delle risposte precedenti ha utilizzato un'unione inversa, e di solito è la risposta giusta. Tuttavia, c'è una situazione (che mi è appena successa) in cui non lo è.

Ho modificato accidentalmente un file con terminazioni di linea Unix in terminazioni di riga DOS quando ho apportato una piccola modifica e l'ho eseguito il commit. Questo può essere facilmente annullato, modificando le terminazioni di riga e eseguendo nuovamente il commit, oppure mediante una fusione inversa, ma ha l'effetto di fare in modo che svn blame elenchi la mia modifica come fonte di ogni riga del file. (È interessante notare che TortoiseSVN su Windows non ne è influenzato; solo la riga di comando svn blame .)

Se vuoi mantenere la cronologia come riportato da svn blame , penso che devi fare quanto segue:

  • Elimina il file e esegui il commit.
  • Nel repository, copia la precedente copia valida del file nell'intestazione e esegui il commit.
  • Ripristina tutte le modifiche che desideri conservare.

L'eliminazione è un po 'spaventosa, ma ricorda che hai sempre salvato il file nel repository, quindi ripristinarlo non è un grosso problema. Ecco un po 'di codice per illustrare i passaggi. Supponiamo che xxx sia il numero di revisione dell'ultima copia valida.

svn rm svn+ssh://path/to/file
svn copy svn+ssh://path/to/file@xxx svn+ssh://path/to -m"Restore good copy"
svn update
<restore the edits>
svn commit -m"Restore edits"

Si noti che per una copia nel repository, la destinazione deve essere una directory, non un nome file.

Sincronizzazione con la versione precedente e commit. Questo dovrebbe fare il trucco.

Ecco anche una spiegazione delle modifiche annullate.

La risposta di Jon Skeet è praticamente la soluzione in breve, tuttavia se sei come me, potresti volere una spiegazione. Il manuale di Subversion lo chiama

Cherry-Pick Merge

Dalle pagine man.

  
      
  1. Questo modulo è chiamato unione 'cherry-pick':   '-r N: M' si riferisce alla differenza nella storia di    ramo di origine tra le revisioni N e M.

         

    È possibile utilizzare un 'intervallo inverso' per annullare le modifiche. Ad esempio, quando    sorgente e destinazione si riferiscono allo stesso ramo, un commit precedentemente    la revisione può essere "annullata". In un intervallo inverso , N è maggiore di M in    '-r N: M' o l'opzione '-c' viene utilizzata con un numero negativo: '-c -M'    è equivalente a '-r M:'. Si annullano anche modifiche come questa    mentre esegue una "fusione inversa".

  2.   

  
      
  • Se l'origine è un file, vengono applicate delle differenze   file (utile per l'unione inversa delle modifiche precedenti). Altrimenti,   se l'origine è una directory, per impostazione predefinita la destinazione è ".".

         

    Nell'uso normale la copia di lavoro dovrebbe essere aggiornata, in un'unica soluzione    revisione, senza modifiche locali e senza sottotitoli commutati.

  •   

Esempio:

svn merge -r 2983:289 path/to/file

Questo sostituirà la copia locale [2983] (che, secondo la citazione sopra, dovrebbe essere sincronizzata con il server - la tua responsabilità) con la revisione 289 dal server. La modifica avviene localmente, il che significa che se si dispone di un checkout pulito, è possibile controllare le modifiche prima di eseguirle.

Ci sono molte risposte pericolose in questa pagina. Si noti che dalla versione 1.6 di SVN, fare un aggiornamento -r può causare conflitti tra alberi, che si trasformano rapidamente in un incubo kafkeresque potenzialmente in perdita di dati in cui si cerca su Google informazioni su conflitti tra alberi.

Il modo corretto di ripristinare una versione è:

svn merge -r HEAD:12345 .

Dove 12345 è il numero di versione. Non dimenticare il punto.

Quanto segue ha funzionato per me.

Ho apportato molte modifiche locali e ho dovuto scartarle nella copia locale e verificare l'ultima versione stabile in SVN.

  1. Controlla lo stato di tutti i file, inclusi i file ignorati.

  2. Grep su tutte le righe per ottenere i file appena aggiunti e ignorati.

  3. Sostituisci quelli con //.

  4. e rm -rf tutte le righe.

    svn status --no-ignore | grep '^ [? I]' | sed " s / ^ [? I] // " | xargs -I {} rm -rf " {} "

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top