You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@subversion.apache.org by Zachary Pincus <zp...@stanford.edu> on 2005/02/24 04:24:35 UTC

Commit a mixed revision working copy as new HEAD?

Hello,

I'm wondering if there is a way to commit a mixed revision working copy 
as the new HEAD.

This need came about because I was trying to figure out how to back out 
of some problems I had. Specifically, I needed to un-delete one file 
and roll back another file to the exact state it was several revisions 
earlier.

It was easy to do the following:
svn update -r100 file1     # roll back to the the good revision of file1
svn update -r120 file2     # get the last version of file2 before it 
was deleted

Now I had a working copy that looked exactly like what I wanted HEAD to 
look like. Unfortunately, I couldn't figure out a way to commit things 
like this.

Instead, for the roll back I had to execute:
svn merge -rHEAD:100 file1

and for the undelete I had to execute:
svn copy -r120 URL://repository/very/long/path/to/the/darn/file2 file2

This all seems clunky and counterintuitive. Using svn merge for the 
roll-back isn't really the first thing I thought of, since I didn't 
want to merge a single patch (or "backward patch"), but just revert to 
a prior state entirely. And using svn copy required typing in a long 
URL path, which I found odd since svn update didn't require a URL.

It seems like these two tasks are basically identical: take a file from 
a previous revision and add it to the working copy in a way that it can 
be committed to HEAD. However the tool you have to use is different 
depending on the current state of the file in the repository. That is, 
svn copy can't be used for the roll-back task because it refuses to 
overwrite the existing (wrong) version of file1, while svn merge can't 
be used for the undelete task because it can't find file2 in the local 
copy or in the HEAD version of the repository, so it doesn't know what 
to merge.

So here we have two semantically similar operations that require two 
completely different commands with different syntax, where neither 
command is perfectly suited to the task. If there were some way to take 
a working copy after some careful svn updates (note that svn update has 
consistent syntax and semantics for file retrieval) and commit that as 
the new HEAD, I would be overjoyed. Is this possible?

Zach Pincus

Department of Biochemistry and Program in Biomedical Informatics
Stanford University School of Medicine


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org

Re: Commit a mixed revision working copy as new HEAD?

Posted by Ryan Schmidt <su...@ryandesign.com>.
On 24.02.2005, at 07:57, Zachary Pincus wrote:

> So again, is there any way to convince svn to commit a mixed revision 
> working copy as the new HEAD? Or are we really stuck with either (a) 
> using svn cat, which ignores history, or (b) using svn merge and svn 
> copy, tools which are too general for the specific problems at hand 
> and thus have nasty and inconsistent syntax for wholesale file 
> reversion and undeletion. (Note that the merge/copy syntax is great 
> for the more general tasks for which these tools were designed!)

I really don't understand the problem. "svn merge" is the tool you want 
to use for this.

If you deleted a file and committed that as revision 10, and then later 
realized that you shouldn't have deleted it, what you need to do is get 
a current working copy of head and do a reverse merge, that is, merge 
the change from revision 10 to revision 9. This should restore the file 
in your working copy. (Shouldn't it? I haven't done this yet but that's 
what I understand should happen.) Then you test your working copy and 
check it in as a new revision.

You wrote about restoring individual files in your previous messages. 
Subversion does not track individual files. You need to speak of 
"restoring the project to the state it was in in revision X". Perhaps 
in the very simplest case you make exactly one change in exactly one 
file and commit that, but often you make changes to many files, and 
those changes depend on each other, and they're all committed at once. 
To undo this operation, you don't want to talk about restoring these 5 
files to their previous revisions -- in particular because other 
unrelated changes to these 5 files may have taken place since then 
which should not be removed. Rather, you want to back out the bad 
changes made to these 5 files. That's what reverse-merging is about.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org

Re: Commit a mixed revision working copy as new HEAD?

Posted by Zachary Pincus <zp...@stanford.edu>.
Hello and thanks for your reply!

As I mentioned in my original message, I understand that it is possible 
to do these tasks with svn merge and svn copy. The problem is that the 
syntax is a bit hard to both grok and explain (I'm trying to teach some 
others how to use svn too!), and in the case of svn copy, requires 
typing in long URLs seemingly unnecessarily.

And, as I noted, svn merge only for "roll backs" and svn copy only for 
undelete; I've not been able to get a backward merge to work properly 
when the file in question does not exist in the HEAD, and I've not been 
able to get a copy to work when it would need to overwrite a file.

So again, is there any way to convince svn to commit a mixed revision 
working copy as the new HEAD? Or are we really stuck with either (a) 
using svn cat, which ignores history, or (b) using svn merge and svn 
copy, tools which are too general for the specific problems at hand and 
thus have nasty and inconsistent syntax for wholesale file reversion 
and undeletion. (Note that the merge/copy syntax is great for the more 
general tasks for which these tools were designed!)

If only there were some command like "svn revert" that took a file 
revision number as the state to revert to! Perhaps there is?

Zach


>  Or, you can take advantage of Subversions smarts and do this:
>
>     svn copy -r100 http://server/repos/path/to/file.c ./file.c
>
>   which will make sure that the history of your item is (mostly)
>   preserved
>   (if you use the cat example above, it'll show up as a new item)
>
>   Or, you can do the "merge in reverse" approach, by doing something
>   like:
>
>     svn merge -r 100:99 http://server/repos/path/to/file.c
>
>   which merge in your "delete of file.c" *backwards* (i.e. undelete
>   it).  Again, I believe, preserving history. (maybe not in this case,
>   one of the developers could answer that).
>
>   Both of these use cases is documented in the Subversion book at:
>
>   http://svnbook.red-bean.com/en/1.1/ch04s04.html#svn-ch-4-sect-4.2
>
> daniel


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org

Re: Commit a mixed revision working copy as new HEAD?

Posted by Daniel Patterson <da...@danpat.net>.
Matthew S. Moore wrote:
>> This need came about because I was trying to figure out how to back 
>> out of some problems I had. Specifically, I needed to un-delete one 
>> file and roll back another file to the exact state it was several 
>> revisions earlier.
>>
>> It was easy to do the following:
>> svn update -r100 file1     # roll back to the the good revision of file1
>> svn update -r120 file2     # get the last version of file2 before it 
>> was deleted
>>
> Zachary,
> 
>   I am new to subversion (less than two weeks, but three years with 
> ClearCase) but I think the solution to simplify this process of rolling 
> back some files is to use svn cat:
> 
> svn cat -r100 file1 > file1  # copy the old version over your working copy.
> svn cat -r120 file2 > file2
> 

   Or, you can take advantage of Subversions smarts and do this:

     svn copy -r100 http://server/repos/path/to/file.c ./file.c

   which will make sure that the history of your item is (mostly)
   preserved
   (if you use the cat example above, it'll show up as a new item)

   Or, you can do the "merge in reverse" approach, by doing something
   like:

     svn merge -r 100:99 http://server/repos/path/to/file.c

   which merge in your "delete of file.c" *backwards* (i.e. undelete
   it).  Again, I believe, preserving history. (maybe not in this case,
   one of the developers could answer that).

   Both of these use cases is documented in the Subversion book at:

   http://svnbook.red-bean.com/en/1.1/ch04s04.html#svn-ch-4-sect-4.2

daniel

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org

Re: Commit a mixed revision working copy as new HEAD?

Posted by Zachary Pincus <zp...@stanford.edu>.
Thanks for the reply!

One nice thing about using svn update, merge and copy is that they are  
all savvy to the file's history -- the fact that the version being  
copied or moved is in fact already under svn control, and has its own  
provenance that should be recorded.

So, while svn cat has the right syntax, you lose the record of where  
the file came from. In most cases, it should be a minor loss. (I'll use  
svn cat for similar tasks now that I know about it!) Still, I wonder if  
there is a way to get both a coherent syntax for these operations and  
be able to retain full provenance information.

Thanks,

Zach



On Feb 23, 2005, at 8:36 PM, Matthew S. Moore wrote:

> Zachary Pincus wrote:
>> Hello,
>> I'm wondering if there is a way to commit a mixed revision working  
>> copy as the new HEAD.
>> This need came about because I was trying to figure out how to back  
>> out of some problems I had. Specifically, I needed to un-delete one  
>> file and roll back another file to the exact state it was several  
>> revisions earlier.
>> It was easy to do the following:
>> svn update -r100 file1     # roll back to the the good revision of  
>> file1
>> svn update -r120 file2     # get the last version of file2 before it  
>> was deleted
> Zachary,
>
>   I am new to subversion (less than two weeks, but three years with  
> ClearCase) but I think the solution to simplify this process of  
> rolling back some files is to use svn cat:
>
> svn cat -r100 file1 > file1  # copy the old version over your working  
> copy.
> svn cat -r120 file2 > file2
>
>   Then you should be able to perform a commit as usual!
>
> Matthew
>
> --  
>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
> ~~
> Matthew S Moore                          Alaska Satellite Facility
> Configuration Manager                    Geophysical Institute
> & Development Engineer                   University of Alaska Fairbanks
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
> ~~
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
> For additional commands, e-mail: users-help@subversion.tigris.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org

Re: Commit a mixed revision working copy as new HEAD?

Posted by "Matthew S. Moore" <mm...@asf.alaska.edu>.
Zachary Pincus wrote:
> Hello,
> 
> I'm wondering if there is a way to commit a mixed revision working copy 
> as the new HEAD.
> 
> This need came about because I was trying to figure out how to back out 
> of some problems I had. Specifically, I needed to un-delete one file and 
> roll back another file to the exact state it was several revisions earlier.
> 
> It was easy to do the following:
> svn update -r100 file1     # roll back to the the good revision of file1
> svn update -r120 file2     # get the last version of file2 before it was 
> deleted
> 
Zachary,

   I am new to subversion (less than two weeks, but three years with ClearCase) 
but I think the solution to simplify this process of rolling back some files is 
to use svn cat:

svn cat -r100 file1 > file1  # copy the old version over your working copy.
svn cat -r120 file2 > file2

   Then you should be able to perform a commit as usual!

Matthew

-- 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Matthew S Moore                          Alaska Satellite Facility
Configuration Manager                    Geophysical Institute
& Development Engineer                   University of Alaska Fairbanks
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org

Re: Commit a mixed revision working copy as new HEAD?

Posted by Steve Greenland <st...@lsli.com>.
On Thu, Feb 24, 2005 at 03:05:05PM -0800, Zachary Pincus wrote:
> Note that, 'svn update -r25 svn_wc.h' is able to properly retrieve the 
> file without complaint. Is this then a problem with svn merge? Or is 
> this behavior by design?

I suspect it's by design: not in the sense that someone said "don't let
it do this", but just by the fact that the existence of a file is a
property of the *directory* that it's in. When you delete a file, you
modify the directory, not the file. So if you delete three files, and
commit, it's an atomic change to the directory.

I doubt that helps much, but perhaps it clarifies what is happening.

Steve



-- 
"Outlook not so good." That magic 8-ball knows everything! I'll ask
about Exchange Server next.
                           -- (Stolen from the net)

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org

Re: Commit a mixed revision working copy as new HEAD?

Posted by Zachary Pincus <zp...@stanford.edu>.
On Feb 24, 2005, at 2:04 PM, Ben Collins-Sussman wrote:
> The fact that's it's a binary file only means that the file can't be 
> "contextually" patched.   As long as you have no local modifications 
> to your files, 'svn merge -rHEAD:X' will have no problem tweaking your 
> working copy to look like revision X.  Remember that under the hood, 
> svn uses binary-diffs on everything.

You are correct that 'svn merge -rHEAD:X' works fine for whatever kind 
of file. All I was pointing out was that 'svn merge -rY:X' is rarely 
appropriate for binary files if Y != HEAD. (As in the quoted text 
below.) This was in reference to several suggestions to the effect that 
one should never try to revert a file wholesale, and should always just 
use 'svn merge -rY:X' to back out bad changes one at a time.

>
>> That is, the only svn merge command that makes sense is "svn merge 
>> -rHEAD:nnn Figure1.ai" or whatever, where nnn is the last good 
>> version. But, despite several assertions to the contrary, a "backward 
>> patch" like this with svn merge simply cannot back out of a file 
>> deletion. (Go ahead, try it.)
>
> Huh?  That's simply not true.  Watch:

Interesting. You can use merge to back out a deletion of some set of 
files within a directory, as in your example below. However, it's not 
possible to use merge to back out of the deletion of a single file or 
directory selectively. That is,
'svn merge -rHEAD:25 .'
works fine, and will back down all files in the directory to the state 
at revision 25, as you showed. However, try:
'svn merge -rHEAD:25 svn_wc.h'
This time, merge will complain with the error:
svn: 'svn_wc.h' has no URL

Note that, 'svn update -r25 svn_wc.h' is able to properly retrieve the 
file without complaint. Is this then a problem with svn merge? Or is 
this behavior by design? I know that part of my difficulty here is that 
I keep insisting on rolling back changes to individual files, while svn 
is more organized around the idea of sets of files being changed 
atomically... however, this mode makes most sense for the sort of 
art-revisioning I'm trying to do.

Thanks for helping elucidate this issue!

Zach Pincus



> [sussman@BenBook:~/scratch]$ svn co file:///usr/local/svn/testrepos wc
> A  wc/svn_error_codes.h
> A  wc/svn_diff.h
> A  wc/svn_fs.h
> A  wc/svn_dav.h
> [...]
> A  wc/svn_ra.h
> A  wc/svn_opt.h
> Checked out revision 25.
> [sussman@BenBook:~/scratch]$ cd wc
> [sussman@BenBook:~/scratch/wc]$
> [sussman@BenBook:~/scratch/wc]$ svn rm svn_wc.h
> D         svn_wc.h
> [sussman@BenBook:~/scratch/wc]$ svn commit -m "deleted svn_wc.h"
> Deleting       svn_wc.h
>
> Committed revision 26.
> [sussman@BenBook:~/scratch/wc]$ svn update
> At revision 26.
> [sussman@BenBook:~/scratch/wc]$ svn merge -rHEAD:25 .
> A  svn_wc.h
> [sussman@BenBook:~/scratch/wc]$ svn status
> A  +   svn_wc.h


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org

Re: Commit a mixed revision working copy as new HEAD?

Posted by Ben Collins-Sussman <su...@collab.net>.
On Feb 24, 2005, at 3:29 PM, Zachary Pincus wrote:
>
> Note that the svn book takes great pains to say that svn should be 
> useful for storing things other than code. So I use it to store, among 
> other things, various revisions of figures I'm working on for papers 
> or presentations. These are binary files, and so using svn merge to 
> "back out" one bad change while leaving the rest of the changes intact 
> is totally inapplicable.

The fact that's it's a binary file only means that the file can't be 
"contextually" patched.   As long as you have no local modifications to 
your files, 'svn merge -rHEAD:X' will have no problem tweaking your 
working copy to look like revision X.  Remember that under the hood, 
svn uses binary-diffs on everything.

> That is, the only svn merge command that makes sense is "svn merge 
> -rHEAD:nnn Figure1.ai" or whatever, where nnn is the last good 
> version. But, despite several assertions to the contrary, a "backward 
> patch" like this with svn merge simply cannot back out of a file 
> deletion. (Go ahead, try it.)

Huh?  That's simply not true.  Watch:


[sussman@BenBook:~/scratch]$ svn co file:///usr/local/svn/testrepos wc
A  wc/svn_error_codes.h
A  wc/svn_diff.h
A  wc/svn_fs.h
A  wc/svn_dav.h
[...]
A  wc/svn_ra.h
A  wc/svn_opt.h
Checked out revision 25.
[sussman@BenBook:~/scratch]$ cd wc
[sussman@BenBook:~/scratch/wc]$
[sussman@BenBook:~/scratch/wc]$ svn rm svn_wc.h
D         svn_wc.h
[sussman@BenBook:~/scratch/wc]$ svn commit -m "deleted svn_wc.h"
Deleting       svn_wc.h

Committed revision 26.
[sussman@BenBook:~/scratch/wc]$ svn update
At revision 26.
[sussman@BenBook:~/scratch/wc]$ svn merge -rHEAD:25 .
A  svn_wc.h
[sussman@BenBook:~/scratch/wc]$ svn status
A  +   svn_wc.h


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org

Re: Commit a mixed revision working copy as new HEAD?

Posted by Zachary Pincus <zp...@stanford.edu>.
This procedure seems like it's workable:

> svn checkout http://head-of-repository wc-dir
> svn update -r100 wc-dir/file1
> svn update -r120 wc-dir/file2
> ...etc... to get the WC based on the right revisions of all the files,
>           and any additional edits needed
> svn delete http://head-of-repository
> svn copy wc-dir http://head-of-repository

It's still a little clumsy because of having to type in potentially 
very long URLs in the svn copy step, but it seems like a good start. 
Also, is there any way at all to force svn copy to overwrite an 
existing file or directory? Though that might be there for our 
protection...

Now, let me motivate why I'm trying to (ab)use svn in this manner, 
instead of just using svn merge to back out changes selectively, which 
people have said is the "right" way to do things.

Note that the svn book takes great pains to say that svn should be 
useful for storing things other than code. So I use it to store, among 
other things, various revisions of figures I'm working on for papers or 
presentations. These are binary files, and so using svn merge to "back 
out" one bad change while leaving the rest of the changes intact is 
totally inapplicable. The only sensible way for me to back out changes 
to artwork is to just revert it to a previous state! That is, the only 
svn merge command that makes sense is "svn merge -rHEAD:nnn Figure1.ai" 
or whatever, where nnn is the last good version. But, despite several 
assertions to the contrary, a "backward patch" like this with svn merge 
simply cannot back out of a file deletion. (Go ahead, try it.)

So then to back out of a deletion, you need to use the much clumsier 
svn copy syntax.

Now, try (like I am) to convince other people doing art to use SVN -- 
it should be a godsend to them. But without a simple and coherent way 
to back out file changes that doesn't involve mysterious merge 
incantations and even more mysterious copy procedures, there's no 
chance anyone will adopt it! The svn update command is so great for 
backing out changes to files, it's a shame that there's no simple way 
to say "svn commit" after those changes. Using svn delete and copy is 
fine, and at least is intuitive, but it's still a lot of keystrokes 
spent typing in URLs that svn should already know.

To make svn as simple for working with versioned binary files as it is 
for working with code files, perhaps there ought to be some "svn 
rollback" type command command that just reverts files from previous 
state in such a way that svn commit then commits the changes. This 
could just be a wrapper around "svn merge -rHEAD:", except that svn 
merge doesn't seem to be able to deal with deleted files.

Zach



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org

RE: Commit a mixed revision working copy as new HEAD?

Posted by Dale Worley <dw...@pingtel.com>.
> From: Dale Worley [mailto:dworley@pingtel.com]
>
> svn checkout http://head-of-repository wc-dir
> svn update -r100 wc-dir/file1
> svn update -r120 wc-dir/file2
> ...etc... to get the WC based on the right revisions of all the files,
>           and any additional edits needed
> svn delete http://head-of-repository
> svn copy wc-dir http://head-of-repository

> Of course, it vaporizes any changes committed between the
> checkout and the
> copy, but any method of fixing the problem is going to have
> problems like
> that.

Hmmm, I think you can get around that last restriction as follows:  Copy
down the revision from "svn checkout", call it A.  Copy down the revision
from "svn copy", call it B.  The problem is that any changes committed from
rev A to rev B-1 are lost.  (If we were using "svn merge" to make our
changes, its "BASE = HEAD" test would stop us if B-1 > A.)  But those
changes are in the history, and we can use "svn merge" to re-install them:

svn checkout http://head-of-repository new-wc-dir
svn merge -r A:B-1 new-wc-dir
svn commit -m 'Reinstall changes from revs A through B-1.' new-wc-dir

Another example of the incredible power of Subversion.

Dale


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org

RE: Commit a mixed revision working copy as new HEAD?

Posted by Dale Worley <dw...@pingtel.com>.
> From: Zachary Pincus [mailto:zpincus@stanford.edu]

> I'm wondering if there is a way to commit a mixed revision
> working copy
> as the new HEAD.

I think what you're looking for is:

svn checkout http://head-of-repository wc-dir
svn update -r100 wc-dir/file1
svn update -r120 wc-dir/file2
...etc... to get the WC based on the right revisions of all the files,
          and any additional edits needed
svn delete http://head-of-repository
svn copy wc-dir http://head-of-repository

That gets all the history connections right.

Though it probably won't work if you are really updating the entire
repository tree, because I don't expect you can delete the top directory.
(You can probably fake it by doing "svn delete" on each member of
head-of-repository and "svn copy" on each member of wc-dir.)  But it should
work if "head-of-repository" is any sub-directory of the repository.  (And
you have a branch structure in place already, don't you?  So you shouldn't
be wanting to do this on the top dir anyway.)

Of course, it vaporizes any changes committed between the checkout and the
copy, but any method of fixing the problem is going to have problems like
that.

Dale


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org