Comment revenir à une ancienne version de notre code dans Subversion?

486

Je travaille sur un projet avec un ami et je veux revenir à une ancienne version de notre code et la définir comme actuelle. Comment fait-on ça?

J'utilise "anksvn" sur vs08.

J'ai la version que je veux sur mon PC, mais la validation échoue; Le message que je reçois est «la validation a échoué, le fichier ou le répertoire est obsolète».

J'ai également le client subversion sur mon PC.

Chen Kinnrot
la source

Réponses:

783

Fondamentalement, vous devez «fusionner en arrière» - appliquer un diff entre la version actuelle et la version précédente à la version actuelle (vous vous retrouvez donc avec une copie de travail ressemblant à l'ancienne version), puis recommencer. Ainsi, par exemple, pour revenir de la révision 150 (actuelle) à la révision 140:

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

Le livre rouge de Subversion contient une bonne section à ce sujet .

Jon Skeet
la source
3
mais la fusion ne remplace pas mes modifications et la nouvelle révision.
Chen Kinnrot
76
Si vous utilisez TortoiseSVN, cliquez avec le bouton droit sur le fichier, sélectionnez Fusionner, puis Fusionner une plage de révisions. Dans la zone de journal, tapez 140-150 et cliquez sur la case à cocher inversée. Après cela, engagez-vous comme d'habitude. Cela effectuera la même opération que l'exemple de Jon.
DavGarcia
8
Avec eclipse et subclipse, vous pouvez cliquer avec le bouton droit de la souris sur votre projet, Équipe / Afficher l'historique, puis sélectionner puis les révisions que vous souhaitez "annuler" et avec un autre clic droit sélectionner "Annuler les modifications des révisions sélectionnées".
fego
36
Pour revenir de la révision de tête, vous pouvez également écrire svn merge -r HEAD:140.
sschmeck
3
@ Les instructions TortoiseSVN de DavGarcia ne me convenaient pas, du moins de ne pas rétablir tous les fichiers d'une révision (en utilisant TortoiseSVN 1.8.8). Faites un clic droit sur le dossier, sélectionnez TortoisSVN-> Afficher le journal. Sélectionnez la ou les révisions que vous souhaitez annuler, cliquez avec le bouton droit de la souris sur «Annuler les modifications de cette révision». Validez les modifications.
mhenry1384
178

Vous ne pouvez valider de nouvelles modifications qu'en tête de l'historique de subversion.

La raison pour laquelle vous ne pouvez rien faire directement avec la bonne copie que vous avez sur votre PC, c'est que ses .svndossiers savent qu'il s'agit de code du passé, donc nécessite une mise à jour avant tout commit.

Trouver le bon numéro de révision et revenir

  1. Recherchez le numéro de révision de l'ancienne copie souhaitée.

    Obtenez votre révision actuelle avec:

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

    Ou pour vérifier les anciennes versions de votre projet, utilisez:

    svn update -r <earlier_revision_number>

    jusqu'à ce que vous trouviez le bon numéro de révision.

  2. Notez le bon numéro de révision (en supposant 123pour les exemples ci-dessous).

  3. Mise à jour vers la dernière révision:

    svn update
  4. Annulez toutes les modifications entre la révision souhaitée et la dernière version:

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

    (identique à la réponse de Jon Skeet ci-dessus.)

Si vous ne trouvez pas le numéro de révision

Si vous ne trouvez pas l'ancienne copie et que vous souhaitez simplement valider les fichiers actuellement sur votre PC:

  1. Faites une copie de votre bonne version (mais sans aucun .svndossier):

    cd ..
    rsync -ai --exclude=.svn  project/  project-good/
  2. Assurez-vous maintenant que vous disposez de la dernière version:

    cd project
    svn update
    # or make a fresh checkout
    svn checkout <url>
  3. Copiez votre bonne version par-dessus la copie de travail.

    Cette commande copiera et supprimera également tous les fichiers de l'arborescence de travail qui ne sont pas dans votre bonne copie, mais cela n'affectera pas les .svndossiers existants .

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

    Si vous n'avez pas rsync, vous pouvez l'utiliser, cp -amais vous devrez également supprimer manuellement tous les fichiers indésirables.

  4. Vous devriez pouvoir engager ce que vous avez maintenant.

    cd project
    svn commit "Reverted to good copy"
joeytwiddle
la source
2
svn ne l'interprète pas comme une modification, je ne peux pas le commettre.
Sandburg
svn merge -r HEAD: 12345. est la commande correcte pour revenir, ne pas faire de mise à jour -r. Vous fou.
Chouette
Je suppose que cette réponse a été votée par des personnes qui n'ont pas pu trouver leur numéro de révision ou qui ont apprécié l'explication principale. J'ai mis à jour la réponse maintenant pour inclure les deux approches.
joeytwiddle
36

Utilisez simplement cette ligne

mise à jour svn -r yourOldRevesion

Vous pouvez connaître votre révision actuelle en utilisant:

info svn

M.Othman
la source
15
Cela ne résout pas le problème. Au lieu de cela, cela produit l'état dans lequel le demandeur se trouvait au moment de poser sa question.
Ingo Schalk-Schupp
1
Si vous avez eu la malchance de suivre ce conseil, exécutez: "svn résoudre - accepter de travailler -R."
Owl
27

La manière standard d'utiliser la fusion pour annuler l'intégralité de l'enregistrement fonctionne très bien, si c'est ce que vous voulez faire. Parfois, cependant, tout ce que vous voulez faire est de restaurer un seul fichier. Il n'y a aucun moyen légitime de le faire, mais il y a un hack:

  1. Trouvez la version que vous souhaitez en utilisant le journal svn.
  2. Utilisez la sous-commande d'exportation de svn:

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

(Où 123 est le numéro de révision d'une bonne version du fichier.) Ensuite, déplacez ou copiez ce seul fichier pour écraser l'ancien. Archivez le fichier modifié et vous avez terminé.

Facture
la source
En utilisant Tortoise-svn, je peux faire un clic droit sur un seul fichier et le fusionner. Il devrait y avoir un moyen de le faire en utilisant svnégalement?
lc.
10
svn cat -r 123 path-in-your-working-copy > path-in-your-working-copy
dash17291
8

Un peu plus old-school

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

puis l'habituel

svn diff
svn commit
Yauhen Yakimovich
la source
5

Je pense que cela convient le mieux:

Faites la fusion vers l'arrière, par exemple, si le code validé contient la révision de la révision 5612 à 5616, fusionnez-la simplement vers l'arrière. Cela fonctionne de mon côté.

Par exemple:

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

Il contiendrait un code fusionné à l'ancienne révision, alors vous pourriez le valider.

hpal
la source
3

C'est ce que j'ai fait et travaillé pour moi.

Je souhaite annuler les modifications apportées à plusieurs validations que j'ai effectuées pendant certaines périodes et je souhaite revenir au point de validation précédent.

  1. Accédez à Équipe -> Afficher l'historique.
  2. Cliquez avec le bouton droit sur la ou la plage de révisions que vous souhaitez ignorer.
  3. Sélectionnez l'option "Annuler les modifications".

Cela exécutera une fusion inverse, annulant les modifications dans votre copie de travail.

Examinez simplement le code et validez.

Ziya
la source
2

Cliquez avec le bouton droit sur la hiérarchie la plus élevée que vous souhaitez rétablir >> RevertouRevert to Revision

Yuval Adam
la source
2

La plupart des réponses précédentes utilisaient une fusion inversée, et c'est généralement la bonne réponse. Cependant, il y a une situation (qui vient de m'arriver) où ce n'est pas le cas.

J'ai accidentellement changé un fichier avec des fins de ligne Unix en fins de ligne DOS lors d'une petite modification et je l'ai validé. Ceci est facilement annulé, soit en changeant les fins de ligne et en recommençant, soit par une fusion inverse, mais cela a pour effet de faire de svn blamelist my edit la source de chaque ligne du fichier. (Fait intéressant, TortoiseSVN sur Windows n'est pas affecté par cela; uniquement la ligne de commande svn blame.)

Si vous souhaitez conserver l'historique tel que rapporté par svn blame, je pense que vous devez procéder comme suit:

  • Supprimez le fichier et validez.
  • Dans le référentiel, copiez la bonne copie précédente du fichier dans l'en-tête et validez.
  • Restaurez toutes les modifications que vous souhaitez conserver.

La suppression est un peu effrayante, mais n'oubliez pas que le fichier est toujours enregistré dans le référentiel, donc le restaurer n'est pas un problème. Voici du code pour illustrer les étapes. Supposons qu'il xxxs'agit du numéro de révision de la dernière bonne copie.

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"

Notez que pour une copie dans le référentiel, la destination doit être un répertoire, pas un nom de fichier.

user2554330
la source
1

Cliquez avec le bouton droit sur le projet> Remplacer par> Révision ou URL> Sélectionnez la révision spécifique que vous souhaitez rétablir.

Maintenant, validez la version locale du code de mise à jour dans le référentiel. Cela ramènera la base de code à la révision spécifique.

KayV
la source
1

Il y a beaucoup de réponses dangereuses sur cette page. Notez que depuis SVN version 1.6, effectuer une mise à jour -r peut provoquer des conflits d'arborescence, qui dégénèrent rapidement en un cauchemar kafkeresque potentiellement perdant des données où vous recherchez des informations sur les conflits d'arborescence.

La bonne façon de revenir à une version est la suivante:

svn merge -r HEAD:12345 .

Où 12345 est le numéro de version. N'oubliez pas le point.

Hibou
la source
0

Synchronisez avec l'ancienne version et validez-la. Cela devrait faire l'affaire.

Voici également une explication de l'annulation des modifications.

Mork0075
la source
0

La réponse de Jon Skeet est à peu près la solution en un mot, mais si vous êtes comme moi, vous voudrez peut-être une explication. Le manuel Subversion appelle cela un

Fusion de cerises

Depuis les pages de manuel.

  1. Cette forme s'appelle une fusion 'au choix': '-r N: M' fait référence à la différence dans l'historique de la branche source entre les révisions N et M.

    Une «plage inverse» peut être utilisée pour annuler les modifications. Par exemple, lorsque source et cible font référence à la même branche, une révision précédemment validée peut être «annulée». Dans une plage inverse , N est supérieur à M dans '-r N: M', ou l'option '-c' est utilisée avec un nombre négatif: '-c -M' est équivalent à '-r M:'. L'annulation de modifications comme celle-ci est également connue sous le nom de «fusion inverse».


  • Si la source est un fichier, des différences sont appliquées à ce fichier (utile pour la fusion inverse de modifications antérieures). Sinon, si la source est un répertoire, la cible par défaut est '.'.

    En utilisation normale, la copie de travail doit être à jour, en une seule révision, sans modifications locales et sans sous-arborescence commutée.

Exemple:

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

Ceci remplacera la copie locale [2983] (qui, selon la citation ci-dessus, devrait être synchronisée avec le serveur - votre responsabilité) avec la révision 289 du serveur. Le changement se produit localement, ce qui signifie que si vous avez effectué un check-out net, les modifications peuvent être inspectées avant de les valider.

Jonathan Komar
la source
-1

Ce qui suit a fonctionné pour moi.

J'ai eu beaucoup de changements locaux et j'ai dû supprimer ceux de la copie locale et extraire la dernière version stable de SVN.

  1. Vérifiez l'état de tous les fichiers, y compris les fichiers ignorés.

  2. Grep toutes les lignes pour obtenir les fichiers nouvellement ajoutés et ignorés.

  3. Remplacez-les par //.

  4. et rm -rf toutes les lignes.

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

shah1988
la source