What you are doing looks like a poor man's VCS, with each file representing a revision. The differences between two consecutive files (revisions) represent a changeset. It sounds like you want to create a patch for a particular changeset:
$ diff file2 file3 > changes.patch
and apply it to an earlier revision:
$ patch file1 < changes.patch
$ cat file1
test1
test3
Or alternatively, perhaps you want to create a patch to reverse a particular changeset:
$ diff file2 file1 > changes.patch
and apply it to your latest revision:
$ patch file3 < changes.patch
$ cat file3
test1
test3
For this particular example, the first approach fails if you use a contextual or unified diff. Neither approach is particularly robust in a more general case. For example, if you need to patch an entire source tree instead of a single file, the names of the files to be updated will be pulled out of the patch file itself.
You should use a real version control system so you don't have to track revisions manually. svn merge
allows you to "patch" a working copy using a specific changeset. You can do this to "rollback" one or more changesets. Say your repo contains a single file, file
, and you've committed three revisions:
# file at r1:
test1
# file at r2:
test1
test2
# file at r3:
test1
test2
test3
You want to reverse the second changeset. First check out the file at r3 (HEAD):
$ svn checkout svn://path/to/repo
A repo/file
Checked out revision 3.
Next do a reverse merge of the changes from changeset 2 (i.e. the changes made between revision 1 and revision 2) into your working copy:
$ cd repo
$ svn merge -c -2 svn://path/to/repo
In this particular case, you will get a conflict which you will have to manually resolve. In real-world repositories, you may or may not get conflicts when you try to reverse earlier changesets.