Temporarily put away uncommitted changes in Subversion (a la “git-stash”)

前端 未结 16 1582
轮回少年
轮回少年 2020-11-28 17:18

While programming software stored in a Subversion repo, I often modify some files, then notice that I\'d like to do some preparatory change for my main work. E.g. while impl

相关标签:
16条回答
  • 2020-11-28 18:01

    You can do it easily using Intellij IDEA - Shelve Changes

    0 讨论(0)
  • 2020-11-28 18:02

    Use:

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

    It will create a branch from the current location and current revision, and then it will commit the changes in working copy to that branch without switching to it.

    usage: copy SRC[@REV]... DST

    SRC and DST can each be either a working copy (WC) path or URL:

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

    Note that changes in working copy won't be automatically reverted (cp is just CoPying changes to a new branch) and you have to revert them manually.

    To restore the changes, you can just merge the changes from newly created branch to your working copy.

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

    --ignore-ancestry is used in order not to update merge info in working copy.

    Use:

    svn ls -v ^/trash-stash/
    

    to see what you have at stash path. Committed revisions are also printed.

    If you don't need the stash anymore, just run:

    svn rm ^/trash-stash/my-stash
    

    This solution is better than using patch in that if new changes in working copy or on the current branch conflict with the changes in the stash, you can resolve the conflicts using svn means, whereas patch in some cases will just fail or even apply patch incorrectly.

    0 讨论(0)
  • 2020-11-28 18:05

    another option is to copy your current checkout to a new directory and revert all your changes. this way you’ll save the hassle of creating a temporary branch on your server—after all stashing is a local operation, which not everybody should see and can be done quite often.

    after committing your hotfix you can update your main working copy and delete your “stashing area”

    0 讨论(0)
  • 2020-11-28 18:05

    Based on the Walter's answer I have created the following aliases in my bashrc file:

    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'
    

    These aliases are much easier to use and remember.

    Usage:

    svn.stash to stash changes and svn.stash.apply to apply stash.

    0 讨论(0)
  • 2020-11-28 18:06

    As of 1.10.0 (2018-04-13), you have experimental svn shelve command. (TortoiseSVN supports the command) It's nothing but a helper to save a patch and apply back, so it has same limitations as svn diff + patch (i.e. can't handle binary files and renames). (Edit: Looks like binary support is coming at next version 1.11.0)

    Edit^2: With 1.11.0 (released 2018-10-30), binary files are supported. Shelving renamed files remained unsupported. Shelving in 1.11 is incompatible with shelves created by 1.10.

    Edit^3: With 1.12.0 (released 2019-04-24), Copying and renaming are supported. Shelving in 1.12 is incompatible with shelves created by earlier versions.

    Edit^4: There is no change around shelving with 1.13.0 and 1.14.0. Commands are still marked as experimental and you need to define SVN_EXPERIMENTAL_COMMANDS=shelf3 to enable the feature. It looks like the feature is currently untriaged.

    Design notes can be found at developers' Wiki.

    $ svn x-shelve --help
    x-shelve: Move local changes onto a shelf.
    usage: x-shelve [--keep-local] SHELF [PATH...]
    
      Save the local changes in the given PATHs to a new or existing SHELF.
      Revert those changes from the WC unless '--keep-local' is given.
      The shelf's log message can be set with -m, -F, etc.
    
      'svn shelve --keep-local' is the same as 'svn shelf-save'.
    
      The kinds of change you can shelve are committable changes to files and
      properties, except the following kinds which are not yet supported:
         * copies and moves
         * mkdir and rmdir
      Uncommittable states such as conflicts, unversioned and missing cannot
      be shelved.
    
      To bring back shelved changes, use 'svn unshelve SHELF'.
    
      Shelves are currently stored under <WC>/.svn/experimental/shelves/ .
      (In Subversion 1.10, shelves were stored under <WC>/.svn/shelves/ as
      patch files. To recover a shelf created by 1.10, either use a 1.10
      client to find and unshelve it, or find the patch file and use any
      1.10 or later 'svn patch' to apply it.)
    
      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:
      -q [--quiet]             : print nothing, or only summary information
      --dry-run                : try operation but make no changes
      --keep-local             : keep path in working copy
    
    (...)
    
    $ svn x-unshelve --help
    x-unshelve: Copy shelved changes back into the WC.
    usage: x-unshelve [--drop] [SHELF [VERSION]]
    
      Apply the changes stored in SHELF to the working copy.
      SHELF defaults to the newest shelf.
    
      Apply the newest version of the shelf, by default. If VERSION is
      specified, apply that version and discard all versions newer than that.
      In any case, retain the unshelved version and versions older than that
      (unless --drop is specified).
    
      With --drop, delete the entire shelf (like 'svn shelf-drop') after
      successfully unshelving with no conflicts.
    
      The working files involved should be in a clean, unmodified state
      before using this command. To roll back to an older version of the
      shelf, first ensure any current working changes are removed, such as
      by shelving or reverting them, and then unshelve the desired version.
    
      Unshelve normally refuses to apply any changes if any path involved is
      already modified (or has any other abnormal status) in the WC. With
      --force, it does not check and may error out and/or produce partial or
      unexpected results.
    
      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:
      --drop                   : drop shelf after successful unshelve
    (...)
    
    $ svn help | grep x-
     x-shelf-diff
     x-shelf-drop
     x-shelf-list (x-shelves)
     x-shelf-list-by-paths
     x-shelf-log
     x-shelf-save
     x-shelve
     x-unshelve
    
    0 讨论(0)
  • 2020-11-28 18:06

    I have also wanted this feature. I currently use TortoiseSVN.

    I have not found a hardfast solution except to export the tree, revert back to repository make my changes and commit, then compare the changes from the exported tree back into my source controlled directory using a tool like Beyond Compare.

    Or, another solution might be to branch from the HEAD to another directory, make your changes and the commit. Once you're ready to merge those back to your other working copy, do an update and merge your changes.

    0 讨论(0)
提交回复
热议问题