Not few times I’ve come upon the situation where I’m working over a Subversion working copy locally and I wanted to commit bits of what I’ve already baked and ready to go. Odds are that there’s only one file not belonging to such changeset but mostly there are many files scattered around.
This situation, I learned, can be managed with a lot more flexibility and fun.
svn changelist is a nice tool for such situation. svn changelist allows you to create a list of “files I want to do something with” meaning that you can use the changelist on your usual svn operations, read commit, remove, etc.
Let’s suppose you start with a project myapp, then you start creating three files A, B and C.
dragon% touch A B C
dragon% ls -lh
total 0
-rw-r--r-- 1 rudy rudy 0 Jul 13 20:16 A
-rw-r--r-- 1 rudy rudy 0 Jul 13 20:16 B
-rw-r--r-- 1 rudy rudy 0 Jul 13 20:16 C
dragon% svn add A B C
A A
A B
A C
dragon% svn ci "first commit of A, B and C" .
Adding A
Adding B
Adding C
Transmitting file data ...
Committed revision 1.
Now we want to edit A and add few pieces of text. Then edit B also.
dragon% echo "This file looks empty, so let's put some text inside it" > A
dragon%
dragon% echo "I'm afraid this one also is empty. Just in case" >> B
Now, I need to work on this C file and that implies touching B also. I don’t want to commit the changes I’ve already made since I haven’t made up my mind about them.
dragon% echo "C is a nice name for a source file, but this one doesn't look like one does it?" > C
dragon% echo "I'm going to add few lines to B too" >> B
dragon% svn st
M A
M B
M C
So, let’s suppose I’m ready to hit the key and commit the 2nd revision. But I’m not done on A, so I want to commit just B and C the way they are now. Here svn changelist enters the arena.
I can create a changelist for the two files and do several tasks related to them. Let’s see.
dragon% svn changelist mylist B C
Path 'B' is now a member of changelist 'mylist'.
Path 'C' is now a member of changelist 'mylist'.
Now I have a changelist named mylist that I can do operations with. For instance,
dragon% svn st
M A
--- Changelist 'mylist':
M B
M C
dragon% svn diff --changelist mylist
Index: B
===================================================================
--- B (revision 1)
+++ B (working copy)
@@ -0,0 +1,2 @@
+I'm afraid this one also is empty. Just in case
+I'm going to add few lines to B too
Index: C
===================================================================
--- C (revision 1)
+++ C (working copy)
@@ -0,0 +1 @@
+C is a nice name for a source file, but this one doesn't look like one does it?
Now let’s commit the list.
dragon% svn ci -m "Comitting files from the mylist changelist" --changelist mylist
Sending B
Sending C
Transmitting file data ..
Committed revision 2.
dragon% svn st
M A
Now that I’ve committed the files, the changelist mylist vanishes from our working copy. I cannot do any new operations with it.
Few things you have to consider when using svn changelist.
changelist‘s are created in a one-time list, that means you cannot add another file to an existing list. If I type svn changelist mylist A it will define the changelist mylist to have just one member, A. It will not add A to the existing member files, B and C.
Now, you are free to remove any file from an existing changelist using svn changelist mylist --remove B, for our previous example. That will make the changelist shrink to just have one element, C. You can also have as many changelists as you want, and member files can be associated to each one of them. Use case for that could be a diff over specific files.
For this test project it almost makes no difference using this feature, but when you have lots of file sitting modified on your working copy, this feature will keep your hair on it’s place, and maybe save the day. svn changelist is available since Subversion 1.5.