211
votes

I wanted to submit a diff for review, for an Open Source Project.

I got the code using SVN (from terminal, Ubuntu). And I did minor edits in few files. Now there is only a single change I want to submit. Rest of the changes I made, were for debugging, and are no longer required.

I have generated diff using svn di > ~/os/firstdiff.diff

So my question, How to discard my local changes?

Is there a SVN way to do it? If not, I will have to go to each file and delete all my edits. Then I would generate a new diff, and submit it.

8

8 Answers

271
votes

Just use the svn revert command, for example:

svn revert some_file.php

It is (as every other svn command) well documented in the svnbook resource or man page, or even with the svn help command.

207
votes

You need to revert all the changes using the svn revert command:

  • Revert changes to a file: svn revert foo.c
  • Revert a whole directory of files: svn revert --recursive .
15
votes

To discard local changes in one particular file:

$ svn revert example_directory/example_file.txt

To discard local changes in one particular folder:

$ svn revert -R example_directory/
7
votes

Simple svn revert was enough for the original poster. However, a simple svn revert will not do in the more general case where you

  1. have both edits that you want to share and edits that are you do not want to share in the same file,
  2. have local changes that you are still interested in keeping for your own private benefit.

@ErichBSchulz's suggestion of using git add -p is very reasonable and much more generally applicable in such a case. The answer was just lacking some details. Assuming your current directory is the directory you want to make the sharable patch, you could do something like this:

  1. Checkout pristine version from subversion to a different directory (choose a directory name that does not exist, here using subdirectory TMP/).

    $ url=$(svn info . | awk '/^URL/ {print $2}')
    $ svn checkout "$url" TMP
    
  2. Using that pristine svn checkout as a basis, init a git repository, ignoring .svn directories; commit everything in svn head to your temporary git repository

    $ cd TMP                                                     
    $ git init && echo ".svn/" > .gitignore
    $ git add -A && git commit
    $ cd ..
    
  3. Copy the newly prepared git repository meta data to your original working directory; as the pristine subversion checkout directory is not needed, you can get rid of it. Your working directory is now both git and subversion repository:

    $ mv TMP/.git .
    $ rm -rf TMP/
    
  4. You can now use powerful and convenient git add -p to interactively choose exactly what you want to share, and commit them to your git repository. If you need to add files to the commit, do also git add <file-to-add> before git commit

    $ git add -p                            
    <interactively select (and edit) the chunks you want to share>
    $ git add ${the_list_of_files_not_in_yet_in_svn_you_want_to_add}
    $ git commit
    
  5. Using the commit, prepare a patch that you want to share. For this purpose, you could also use git diff HEAD^..HEAD, or git format-patch (the latter can be used to directly prepare emails to be sent containing the patch or multiple patches):

    $ git show -p HEAD > my-mighty-patch.patch
    

To get rid of git meta data, just do rm -rf .git/. If you plan to continue hacking with the original working directory, you could continue using git to manage your local changes. In this case you would probably benefit from the investment of learning how to use git svn.

Note: If you are familiar with git this is rather trivial thing to improvise. Otherwise this looks maybe a bit messy. You could generalize the approach by writing a script out of these steps to implement a "interactive commit" or "interactive patch creation" for svn that could be used without any understanding of git.

4
votes

You could use

 svn diff important/file1.c important/file2.c > $HOME/os/firstdiff.diff

When publishing your diff, don't forget to tell the revision against which you are diff-ing.

As others replied, you could also use svn revert carefully. It depends if you want to keep your local changes for your future work or not...

3
votes

Go to the root of that repository and run the following command

svn revert --depth=infinity .
1
votes

You can use the commit command on the file you want to put, and use svn revert command to discard the remaining local changes

1
votes

I realise this is an old query, but... This can now be accomplished easily:

svn revert -R --remove-added /path/to/dir && svn cleanup --remove-unversioned /path/to/dir

The first part recursively reverts changes, and removes added-but-not-committed files.

The second part removes any unversioned or ignored items in the path.

The best source for the above info. I'm aware of is the svn client itself:

❯ svn help revert
revert: Restore pristine working copy state (undo local changes).
usage: revert PATH...

  Revert changes in the working copy at or within PATH, and remove
  conflict markers as well, if any.

  This subcommand does not revert already committed changes.
  For information about undoing already committed changes, search
  the output of 'svn help merge' for 'undo'.

Valid options:
  --targets ARG            : pass contents of file ARG as additional args
  -R [--recursive]         : descend recursively, same as --depth=infinity
  --depth ARG              : limit operation by depth ARG ('empty', 'files',
                             'immediates', or 'infinity')
  -q [--quiet]             : print nothing, or only summary information
  --changelist [--cl] ARG  : operate only on members of changelist ARG
  --remove-added           : reverting an added item will remove it from disk

❯ svn help cleanup
cleanup: Either recover from an interrupted operation that left the working copy locked,
or remove unwanted files.
usage: 1. cleanup [WCPATH...]
       2. cleanup --remove-unversioned [WCPATH...]
          cleanup --remove-ignored [WCPATH...]
       3. cleanup --vacuum-pristines [WCPATH...]

  1. When none of the options --remove-unversioned, --remove-ignored, and
    --vacuum-pristines is specified, remove all write locks (shown as 'L' by
    the 'svn status' command) from the working copy.  Usually, this is only
    necessary if a Subversion client has crashed while using the working copy,
    leaving it in an unusable state.

    WARNING: There is no mechanism that will protect write locks still
             being used by other Subversion clients. Running this command
             without any options while another client is using the working
             copy can corrupt the working copy beyond repair!

  2. If the --remove-unversioned option or the --remove-ignored option
    is given, remove any unversioned or ignored items within WCPATH.
    Note that the 'svn status' command shows unversioned items as '?',
    and ignored items as 'I' if the --no-ignore option is given to it.

  3. If the --vacuum-pristines option is given, remove pristine copies of
    files which are stored inside the .svn directory and which are no longer
    referenced by any file in the working copy.