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


486

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.

Risposte:


783

Fondamentalmente è necessario "unire all'indietro" - applicare una diff tra la versione corrente e precedente alla versione corrente (quindi si finisce con una copia funzionante che assomiglia alla vecchia versione) e quindi si esegue nuovamente il commit. Quindi, per 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 di Subversion ha una buona sezione su questo .


3
ma l'unione non ha la precedenza sulle mie modifiche e sulla nuova revisione.
Chen Kinnrot,

76
Se si utilizza TortoiseSVN, fare clic con il pulsante destro del mouse sul file selezionare Unisci, quindi Unisci un intervallo di revisioni. Nella casella di registro digitare 140-150 e fare clic sulla casella di controllo Reverse. Dopodiché, impegnati come al solito. Ciò eseguirà la stessa operazione dell'esempio di Jon.
DavGarcia,

8
Con eclipse e subclipse, è possibile fare clic con il tasto destro del mouse sul progetto, Team / Show History, quindi selezionare le revisioni che si desidera "annullare" e con un altro tasto destro selezionare "Ripristina modifiche da revisioni selezionate".
fego,

36
Per tornare alla revisione principale puoi anche scrivere svn merge -r HEAD:140.
Sschmeck,

3
@ Le istruzioni TortoiseSVN di DavGarcia non erano adatte a me, almeno per non ripristinare tutti i file in una revisione (usando TortoiseSVN 1.8.8). Fare clic con il tasto destro sulla cartella, selezionare TortoisSVN-> Mostra registro. Seleziona le revisioni che desideri ripristinare, fai clic con il pulsante destro del mouse come "Ripristina modifiche da questa revisione". Conferma le modifiche.
mhenry1384,

178

È possibile eseguire solo il commit di nuove modifiche a capo della cronologia di sovversione.

Il motivo per cui non puoi fare nulla direttamente con la buona copia che hai sul tuo PC, è che le sue .svncartelle 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 revisione attuale con:

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

    O per controllare le versioni precedenti del progetto, utilizzare:

    svn update -r <earlier_revision_number>

    fino a trovare il numero di revisione corretto.

  2. Annotare il numero di revisione valido (presupponendo 123per 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"

    (lo stesso della 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 .svncartelle):

    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 copierà e cancellerà anche tutti i file dall'albero di lavoro che non sono nella tua buona copia, ma non influenzerà le .svncartelle esistenti .

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

    Se non hai rsync, puoi usarlo cp -ama dovrai anche eliminare manualmente tutti i file indesiderati.

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

    cd project
    svn commit "Reverted to good copy"

2
svn non lo interpreta come una modifica, non posso commetterlo.
Sandburg,

svn merge -r HEAD: 12345. è il comando corretto da ripristinare, non eseguire un aggiornamento -r. Pazzo.
Gufo,

Immagino che questa risposta sia stata votata da persone che non sono riuscite a trovare il loro numero di revisione o che hanno apprezzato la spiegazione principale. Ho aggiornato la risposta ora per includere entrambi gli approcci.
joeytwiddle,

36

Usa questa linea

svn update -r yourOldRevesion

Puoi conoscere la tua attuale revisione usando:

informazioni svn


15
Questo non risolve il problema. Invece, questo produce lo stato in cui si trovava il richiedente al momento di porre la domanda.
Ingo Schalk-Schupp,

1
Se sei stato abbastanza sfortunato da seguire questo consiglio, esegui: "svn resol --accept working -R."
Gufo,

27

Il modo standard di utilizzare 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 trucco:

  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 / nomefile

(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.


Usando Tortoise-svn posso fare clic con il tasto destro su un singolo file e unirlo. Dovrebbe esserci un modo per farlo anche usando svn?
lc.

10
svn cat -r 123 path-in-your-working-copy > path-in-your-working-copy
dash17291

8

Un po 'più vecchio stile

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

quindi il solito

svn diff
svn commit

5

Penso che questo sia più adatto:

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

Per esempio:

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

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


3

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 a Team -> Mostra cronologia.
  2. Fare clic con il tasto destro del mouse sull'intervallo di revisioni che si desidera ignorare.
  3. Seleziona l'opzione "Annulla modifiche".

Ciò eseguirà un'unione inversa, annullando le modifiche nella copia di lavoro.

Basta rivedere il codice e confermare.


2

Fare clic con il tasto destro sulla gerarchia più alta che si desidera ripristinare >> RevertoRevert to Revision


2

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 rendere la svn blamemia modifica della lista come l'origine 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 xxxsia 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.


1

Fare clic con il tasto destro del mouse sul progetto> Sostituisci con> Revisione o URL> Selezionare la revisione specifica che si desidera ripristinare.

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


1

Ci sono molte risposte pericolose su 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.


0

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

Ecco anche una spiegazione per annullare le modifiche.


0

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 a

Unione Cherry-Pick

Dalle pagine man.

  1. Questa forma è chiamata unione 'cherry-pick': '-r N: M' si riferisce alla differenza nella storia del ramo sorgente tra le revisioni N e M.

    Un "intervallo inverso" può essere utilizzato per annullare le modifiche. Ad esempio, quando l'origine e la destinazione si riferiscono allo stesso ramo, una revisione precedentemente impegnata può essere "annullata". In un intervallo inverso , N è maggiore di M in '-r N: M', oppure l'opzione '-c' viene utilizzata con un numero negativo: '-c -M' è equivalente a '-r M:'. Annullare modifiche come questa è anche noto come eseguire una "fusione inversa".


  • Se l'origine è un file, le differenze vengono applicate a quel 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, con una sola revisione, senza modifiche locali e senza sottotitoli.

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.


-1

Quanto segue ha funzionato per me.

Ho apportato molte modifiche locali e avevo bisogno di 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 tutte le righe per ottenere i file appena aggiunti e ignorati.

  3. Sostituisci quelli con //.

  4. e rm -rf tutte le linee.

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

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.