[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

svn rm behaviour (was: svn rm --force always fails)

From: William Uther <will+_at_cs.cmu.edu>
Date: 2002-04-17 19:01:19 CEST

On 17/4/02 12:31 AM, "cmpilato@collab.net" <cmpilato@collab.net> wrote:

> cmpilato@collab.net writes:
>> I haven't debugged this one bit, but I wonder if it has something to
>> do with the presence of unversioned files in the directory
>> (libtool.m4, config.*, etc.) ...
> No. Never mind me. Duh.
> Of course we can't `svn rm --force' a directory. Until `svn revert'
> can recover from such a maneuver, I think we intentionally disallow
> it. However, I think the proper thing to do would be to just silently
> ignore the --force for dirs, and have `svn help rm' note that --force
> is ignored for directories at this time.

Hi all,

  The default behaviour of svn rm is one of the few things I find a little
counter-intuitive about svn. I'd like 'svn rm' to be like 'rm' as much as
possible. The current behaviour is different to 'rm'. Moreover, the
current behaviour doesn't match the manual. The current behaviour *does*
match the help string, but there are cases where this is not as safe a
behaviour as the manual - you can lose local changes easily.

  I've attached summaries of, and comments on, the various behaviours below
as well as a log demonstrating the current behaviour. One of the behaviours
I list below is a proposed new behaviour.

  If people think my proposed 'svn rm' behaviour is worth implementing I'd
be willing to write the patch.


\x/ill :-}

----- current documented behaviour (summary of manual :

'svn rm' marks a file for removal, but does not remove it. "If foo.c is
locally modified, this command will return an error". Dirs can be
recursively removed, but if any file is modified the command will return an

"When the user runs @samp{svn commit}, and items are scheduled for
removal, the items are first removed from the repository. If there are
server-side conflicts, then (as usual) an error message will explain
that the working copy is out-of-date."

The --force behaviour means "remove this file immediately". The only way to
remove a modified file is to 'svn revert' it first.

-- comments on manual

The manual differs from reality. svn does not currently check for local
mods during the 'svn rm' command. Also, svn will not remove a file that is
marked for deletion when the user commits.

The manual also differs from what I'd like. I'd prefer it if the original
'svn rm' actually removed the file from the user dir (but left it in the
text-base). The file must be un-modified for the 'svn rm' to succeed. This
means it can be recovered with an 'svn revert' -- there is no reason to keep
it around.

Once the file is being removed from the user dir, the '--force' flag is
unused. It can have its meaning changed to 'ignore local mods'. This is
more what '--force' means to me anyway.

----- current documented behaviour (svn help rm)

    If run on a working-copy TARGET, item is scheduled for deletion
    upon next commit. (The working item itself will only be removed
    if --force is passed.) If run on URL, item is deleted from
    repository via an immediate commit.

-- comments on help

This is the current actual behaviour (as at 0.11 tarball - see log below).

Note that there is no mention made of local modifications. The file is
marked for removal regardless.

Note that '--force', like in the manual, causes the file to be removed
immediately. It still doesn't check for local mods. This means that you
can't just alias 'svnrm' to 'svn rm --force' to get the automatic removal
behaviour I'd like without possibly losing local mods.

There is no information about what happens on commit in the help text (or it
is ambiguous). In the log below you can see that commit doesn't do any
removal of files from the user dir. This means that currently an 'svn rm'
'svn commit' combination removes the file from the repository and the
text-base, but not the user copy. An 'svn up' after the commit doesn't

----- proposed new behaviour

'svn rm' looks to see if the file is modified. If it is then the command
fails: use '--force', or run 'svn revert' before removing the file. If the
file is not locally modified or '--force' is specified, then the file is
marked for removal and the file is removed from user section of the working
copy. (it is still in text-base and can be recovered to its unmodified form
with an 'svn revert')

On commit the file is removed from the entries and text-base. It should
already have been removed from the user-dir. I believe this requires no
changes to the current commit system.

-- notes on proposed behaviour

This requires two changes from current behaviour. Both are in 'svn rm'. I)
Check for local mods and fail if there are any (unless --force is
specified). II) remove the file from the user dir.

---- start log

# first some setup
# make a repository, check out a dir from it, add a file and commit

% svn --version
Subversion Client, version 0.10.2 (r1682)
   compiled Apr 12 2002, 19:54:55
% mkdir svntest
% cd svntest
% svnadmin create repos
% svn mkdir file:///Users/will/svntest/repos/trunk -m "add trunk dir"
% svn co file:///Users/will/svntest/repos/trunk
% cd trunk
% cat > testfile
this is a file
% svn add testfile
A testfile
% svn commit -m "added testfile"
Adding testfile
Transmitting file data .
Committed revision 2.

# now lets do a basic 'svn rm'

% svn rm testfile
D testfile
% ls

# The file is still there. Note: There were no changes from the last
committed version - svn revert could simply copy from the text-base to
recover the file. There is no reason not to remove this file.

% svn commit -m "Out out damn file"
Deleting testfile

Committed revision 3.
% ls

# The file is still there. Again - no changes from the committed version.
# I find it really counter-intutive that the file is STILL there.

# Set things up again

% svn add testfile
A testfile
% svn commit -m "re-add the testfile"
Adding testfile
Transmitting file data .
Committed revision 4.

# test svn rm --force

% svn rm --force testfile
D testfile
% ls

# yay - file is gone
# bring it back for further tests

% svn revert testfile
Reverted testfile

# lets test what happens when the file is not clean

% cat >> testfile
add a little more
% svn rm testfile
D testfile

# the file is marked for deletion - this conflicts with the behaviour
specified in the manual.

% svn commit -m "try committing rm of dirty file"
Deleting testfile

Committed revision 5.

# If I didn't get conflicts before, I sure expected them there

% ls

# file is still there.
# set things up to play again

% rm testfile
% cat > testfile
this is a new file
% svn add testfile
A testfile
% svn commit -m "another file to play with"
Adding testfile
Transmitting file data .
Committed revision 6.

% cat >> testfile
Wheeeee, more lines
% svn rm --force testfile
D testfile
% ls

# file is gone and we lost data doing it (not surprising given the --force
# shows that --force currently means 'actually remove the file', not 'ignore

#lets test to see if updating after removing the file works...

# bring the file back again

% svn revert testfile
Reverted testfile

# remove, commit, update

% svn rm testfile
D testfile
% ls
% svn commit -m "removed yet again"
Deleting testfile

Committed revision 7.
% svn up
D ./testfile
% ls

# well, 'svn up' said it would delete the file, but it didn't. The file is
still there.

To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Wed Apr 17 19:45:11 2002

This is an archived mail posted to the Subversion Dev mailing list.