Mettre temporairement les changements non engagés dans Subversion (a la " git-stash")

Lors de la programmation d'un logiciel stocké dans un repo Subversion, je modifie souvent certains fichiers, puis je remarque que j'aimerais faire des changements préparatoires pour mon travail principal. Par exemple, lors de l'implémentation de nouvelles fonctionnalités, je remarque un refactoring qui pourrait m'aider.

Afin de ne pas mélanger deux modifications non liées, dans ces cas, je voudrais "ranger" mes modifications, c'est-à-dire revenir à la version du référentiel, faire d'autres modifications, les valider, puis "récupérer" mes modifications.

Git-stash permet de faire exactement cela. Y a-t-il un moyen de le faire avec Subversion, directement ou avec un plugin ou un script? Les plugins Eclipse seraient également bien.

274
demandé sur Cœur 0000-00-00 00:00:00

15 réponses

Quand j'ai des modifications non validées d'une tâche dans ma copie de travail et que je dois passer à une autre tâche, je fais l'une des deux choses suivantes:

  1. Consultez une nouvelle copie de travail pour la deuxième tâche.

    Ou

  2. Démarrer une branche:

    workingcopy$ svn copy CURRENT_URL_OF_WORKING_COPY SOME_BRANCH
    workingcopy$ svn switch SOME_BRANCH
    workingcopy$ svn commit -m "work in progress"
    workingcoyp$ svn switch WHATEVER_I_WAS_WORKING_ON_BEFORE
    

J'ai quelques scripts qui aident à automatiser cela.

66
répondu bendin 2018-06-08 10:38:44

Cet article de blog conseille d'utiliser diff et patch.

  • git stash devient approximativement svn diff > patch_name.patch; svn revert -R .
  • git stash apply devient patch -p0 < patch_name.patch

Notez que cela ne cache pas les changements de métadonnées ou (je pense) le répertoire crée / supprime. (Oui, svn les suit séparément du contenu du répertoire, contrairement à git.)

303
répondu Walter Mundt 2010-08-02 19:22:41

Vous pouvez stocker vos modifications actuelles avec svn diff dans un fichier patch, puis restaurer votre copie de travail:

svn diff > stash.patch
svn revert -R .

Après avoir implémenté votre fonctionnalité préparatoire, vous pouvez ensuite appliquer votre patch avec l'utilitaire patch:

patch < stash.patch

Comme d'autres l'ont noté, cela ne fonctionnera pas avec svn:properties et les opérations d'arborescence (Ajouter, Supprimer, Renommer des fichiers et des répertoires).

Les fichiers binaires peuvent également donner des problèmes, Je ne sais pas comment patch (ou TortoiseSVN dans ce cas les gère).

162
répondu knittl 2014-10-10 08:43:01

Le moyen le plus simple serait d'utiliser une branche temporaire, comme ceci:

$ svn copy ^/trunk ^/branches/tempbranch
$ svn switch ^/branches/tempbranch
$ svn commit -m "Stashed"
$ svn switch ^/trunk
$ ... hack away in trunk ...
$ svn commit -m "..."
$ svn merge ^/branches/tempbranch .
$ svn rm ^/branches/tempbranch
$ ... continue hacking

Cela pourrait (et devrait probablement) être mis dans un script si cela est fait sur une base plus régulière.

39
répondu JesperE 2009-10-12 12:34:47

À partir du 2018-04-13 (Subversion 1.10.0), vous avez experimental svn shelve commande . (TortoiseSVN prend en charge la commande )

Actuellement, ce n'est rien d'autre qu'une aide pour enregistrer un patch et l'appliquer, donc il a les mêmes limites que svn diff + patch (c'est-à-dire ne peut pas gérer les fichiers binaires et renommer). (Edit: On dirait que le support binaire arrive à la prochaine version )

$ svn shelve --help
x-shelve (shelve): Put a local change aside, as if putting it on a shelf.
usage: 1. x-shelve [--keep-local] NAME [PATH...]
       2. x-shelve --delete NAME
       3. x-shelve --list

  1. Save the local change in the given PATHs to a patch file, and
     revert that change from the WC unless '--keep-local' is given.
     If a log message is given with '-m' or '-F', include it at the
     beginning of the patch file.

  2. Delete the shelved change NAME.
     (A backup is kept, named with a '.bak' extension.)

  3. List shelved changes. Include the first line of any log message
     and some details about the contents of the change, unless '-q' is
     given.

  The kinds of change you can shelve are those supported by 'svn diff'
  and 'svn patch'. The following are currently NOT supported:
     mergeinfo changes, copies, moves, mkdir, rmdir,
     'binary' content, uncommittable states

  To bring back a shelved change, use 'svn x-unshelve NAME'.

  Shelved changes are stored in <WC>/.svn/shelves/

  The shelving feature is EXPERIMENTAL. This command is likely to change
  in the next release, and there is no promise of backward compatibility.

Valid options:
  --delete                 : delete the shelved patch
  --list                   : list shelved patches
  -q [--quiet]             : print nothing, or only summary information
  --dry-run                : try operation but make no changes
  --keep-local             : keep path in working copy
(...)

$ svn unshelve --help
x-unshelve (unshelve): Bring a shelved change back to a local change in the WC.
usage: 1. x-unshelve [--keep-shelved] [NAME]
       2. x-unshelve --list

  1. Apply the shelved change NAME to the working copy.
     Delete the patch unless the '--keep-shelved' option is given.
     (A backup is kept, named with a '.bak' extension.)
     NAME defaults to the most recent shelved change.

  2. List shelved changes. Include the first line of any log message
     and some details about the contents of the change, unless '-q' is
     given.

  Any conflict between the change being unshelved and a change
  already in the WC is handled the same way as by 'svn patch',
  creating a 'reject' file.

  The shelving feature is EXPERIMENTAL. This command is likely to change
  in the next release, and there is no promise of backward compatibility.

Valid options:
  --keep-shelved           : do not delete the shelved patch
  --list                   : list shelved patches
  -q [--quiet]             : print nothing, or only summary information
  --dry-run                : try operation but make no changes
(...)
9
répondu snipsnipsnip 2018-06-05 06:25:08

Je ne connais pas de moyen facile de le faire avec juste svn. Honnêtement, je conseillerais d'utiliser git-svn pour faire un repo git qui agit comme une copie de travail svn, et juste en utilisant git stash avec cela. Remplacez simplement git pull par git svn rebase et git push par git svn dcommit et vous pouvez réellement conserver 90% de votre flux de travail git et toujours parler à un serveur svn.

7
répondu Walter Mundt 2010-08-02 19:18:39

Il existe un petit script Python 2 appelé svn-stash Disponible sous GPL 3: https://github.com/frankcortes/svn-stash .

Cela fonctionne comme les solutions svn diff/patch mentionnées et offre la poussée et l'éclatement des changements en tant que diffs dans un répertoire local. Malheureusement, les cachettes ne peuvent pas être nommées, et seul le dernier peut être sauté (Eh bien, oui, c'est une pile, mais il n'y a pas de vraie raison pour une telle limitation.) Mais alors, vous pouvez toujours construire les fonctionnalités manquantes dans le source.

Il est écrit pour * ix, mais après avoir remplacé chaque " / " par os.sep cela fonctionne aussi bien sous Windows.

Si vous utilisez svn 1.7 ou supérieur, vous devez changer is_a_current_stash(): supprimer la ligne if ".svn" in os.listdir(CURRENT_DIR):, car il n'y a qu'un seul niveau supérieur .svn subdir dans 1.7 WC.

4
répondu cxxl 2013-06-14 16:56:54

Vous pouvez le faire facilement en utilisant Intellij IDEA - Shelve Changes

4
répondu lili 2016-06-02 13:27:41

Une autre option consiste à copier votre commande actuelle dans un nouveau répertoire et à annuler toutes vos modifications. de cette façon, vous économiserez les tracas de la création d'une branche temporaire sur votre serveur-après tout, le stashing est une opération locale, que tout le monde ne devrait pas voir et peut être fait assez souvent.

Après avoir validé votre correctif, vous pouvez mettre à jour votre copie de travail principale et supprimer votre "zone de stockage"

3
répondu knittl 2009-10-12 19:03:18

J'ai aussi voulu cette fonctionnalité. J'utilise actuellement TortoiseSVN.

Je n'ai pas trouvé de solution hardfast sauf pour exporter l'arborescence, revenir au référentiel faire mes modifications et valider, puis comparer les modifications de l'arborescence exportée dans mon répertoire contrôlé par la source en utilisant un outil comme Beyond Compare.

Ou, une autre solution pourrait être de brancher de la tête à un autre répertoire, faire vos modifications et le commit. Une fois que vous êtes prêt à fusionner ceux de retour à votre autre copie de travail, faites une mise à jour et fusionnez vos modifications.

1
répondu Anthony Shaw 2009-10-12 12:30:07

Je garde toujours une deuxième caisse, que j'appelle "trunk_clean". Chaque fois que j'ai besoin de faire un changement rapide et isolé lié à ce que je fais, je m'engage juste sur cette caisse à la place.

1
répondu angularsen 2013-07-12 14:16:46

Les idées de branchement et de correction ci-dessus sont géniales, mais elles ne fonctionnent pas bien pour moi. J'utilise un outil de diff visuel, donc l'exécution de git diff ne produit pas de correctifs basés sur du texte. Notre système de construction crée un nouvel environnement chaque fois qu'une branche est créée, de sorte que la création de branches temporaires "stash" deviendrait désordonnée.

Au lieu de cela, j'ai écrit un petit script shell {[5] } qui copie un fichier dans un répertoire "étagère", ajoute un horodatage et rétablit la modification. Ce n'est pas aussi robuste que les solutions ci-dessus, mais il évite également certains des pièges que j'ai rencontrés.

0
répondu Ryan DeBeasi 2015-09-15 18:28:44

Sur la base de la réponse de Walter, j'ai créé les alias suivants dans mon fichier bashrc:

alias svn.stash='read -p "saving local changes in raq.patch. Existing stash in raq.patch will be overwritten. Continue?[y/N]" && [[ $REPLY =~ ^[yY] ]] && rm -f raq.patch && svn diff > raq.patch && svn revert -R .'
alias svn.stash.apply='patch -p0 < raq.patch; rm -f raq.patch'

Ces alias sont beaucoup plus faciles à utiliser et à mémoriser.

Utilisation:

svn.stash {[9] } pour stocker les modifications et svn.Stash.appliquer appliquer cachette.

0
répondu Raheel 2018-03-12 09:47:09

Utilisation:

svn cp --parents . ^/trash-stash/my-stash

Il créera une branche à partir de l'emplacement actuel et de la révision actuelle, puis il validera les modifications de la copie de travail à cette branche sans y passer.

Utilisation: copiez SRC [@REV]... DST

SRC et DST peuvent chacun être un chemin de copie de travail (WC) ou une URL:

WC  -> URL:  immediately commit a copy of WC to URL

Notez que les modifications de la copie de travail ne seront pas automatiquement annulées ({[5] } est juste copiant les modifications apportées à une nouvelle branche) et vous devez annuler - les manuellement.

Pour restaurer les modifications, vous pouvez simplement fusionner les modifications de la branche nouvellement créée vers votre copie de travail.

svn merge --ignore-ancestry ^/trash-stash/my-stash -c <commited revision>

--ignore-ancestry est utilisé afin de ne pas mettre à jour les informations de fusion dans la copie de travail.

Utilisation:

svn ls -v ^/trash-stash/

Pour voir ce que vous avez à ranger chemin. Les révisions engagées sont également imprimées.

Si vous n'avez plus besoin de la cachette, exécutez simplement:

svn rm ^/trash-stash/my-stash

Cette solution est meilleure que d'utiliser patch en ce que si de nouveaux changements dans la copie de travail ou sur le courant conflit de branche avec les changements dans la Réserve, vous pouvez résoudre les conflits en utilisant des moyens svn, alors que patch dans certains cas échouera ou même appliquera le patch de manière incorrecte.

0
répondu anton_rh 2018-06-13 11:46:05

Dans ma pratique, j'utilise git init pour créer un référentiel Git dans le répertoire trunk de mon référentiel Subversion, puis j'ajoute *.git aux Suctions ignore patterns.

Après avoir modifié certains fichiers, si je veux continuer mon travail avec la ligne principale Subversion, j'utilise simplement git stash pour stocker mon travail. Après m'être engagé dans le dépôt Subversion, j'utilise git stash pop pour restaurer mes modifications.

-2
répondu yhluo 2018-06-08 10:51:11