The Not-So-Boring Guide to Subversion (Episode 2)

Chris says, You are ever-so-slightly urged to read Episode One of the Not-So-Boring Guide to SVN before you read Episode Two. And no, I would not, could not, on a train.
Welcome back to the Not-So-Boring guide to SVN. On the last episode, we learned about Checking Out files from the dark-scary Repository, making a commit-ment to the files if we make changes to them, and making sure we Update our files on occasion to verify that we are working with the latest-greatest code.
Creating your own Repository
All of the above options assume that you're working for an Open-Source project or a company where the SVN Repository is already set up and ready-to-go. You, however, I know are different. You've got your own ideas. You don't want to work for the man. You want to be the man. You've been watching the Apprentice, listening to Venture Voice, and are done and gets things smart. Great. Have I got the answer for you!
The create function creates a repository where-ever you want it. You want it on the moon? No Problem.
$ svn create /repos/on/the/moon
What about on an elephant?
$ svn create /repos/on/the/elephant
If you don't want to host it locally, you can always check out the plethora of hosting options. Services like Beanstalk and Dreamhost making hosting a Subversion Repository easy cheesy.
Next, import your project into the Repository so it can be checked out and worked on by you and your army of programming minions that you will hire for paltry wages but that you will supply with unlimited free cokes, 30-inch monitors, and Aeron Chair's.
$ svn import ProjectFileTree file://repos/on/the/elephant/ProjectName
Once in the repository, you can use the check-out command to begin work on the project.
$ svn checkout file://repos/on/the/elephant/ProjectName
And while we're add it, go ahead and update those files. You never know where they've been.
$ svn updateAll Deer May Cough (On) Moles
Now you're ready to go ahead and edit those files to your little heart's content. Subversion automatically detects which files have been changed (remember the secret .SVN files). BUT (and this is a BIG BUT), if you intend to make any changes to the Project File Tree such as adding a new file, deleting a file, copying a file, moving a file to another location, or making a new directory, SVN needs a little guidance. Thus, the following commands are provided.
Add a File or Directory to the Repository.
$ svn add VeryPracticalFileNameDelete a File or Directory from the Repository.
$ svn delete ExtreamlyPracticalDirectoryNameCopy a File and Add to the Repository
$ svn copy Roger CopyOfRogerMkDir creates a new Directory in the Repository.
$ svn mkdir DirectoryName
Move is kind of wierd. Strange even. It moves a file from one part of the Repository to the other.
$ svn move Here Thereis the exact same thing as as saying:
$ svn copy Here There $ svn delete Here
Strange huh? But it makes sense if you think long and hard about it. Because if you were moving 'Here' to 'There,' it wouldn't be 'Here' anymore would it? It would be 'There.' Actually, think of the move command like the Cut command on your computer. If you cut a file from a directory and paste it in another directory, you have essentailly moved it to the new directory. Whew.
Break Time: Here's a picture of My Dear Aunt Sally. Stunning isn't she?
If you remember back to your years of golden locks and curls, Please Excuse My Dear Aunt Sally was a way to remember the Order of Operations: Parentheses, Exponents, Multiplication, Division, Addition, Subtraction. To help you remember Add, Delete, Mkdir, Copy, and Move (the four things you may have to do if you intend to make any changes to the projects file tree), come up with your own Memory Jogging Device and write them in the blanks below!
ADD DELETE MKDIR COPY MOVE
____________ ____________ ____________ ____________ ____________
No, I don't care about the frequency. What's the status Kenneth?
Before making a commitment to the Repository, it is in good form and fashion to run a status on your Working Copy. Status gives you an overview of the changes you've made to your Working Copy since your last commit.
$ svn status A who/is/this/me.cpp M doing/this/synthetic.h
A is for Apple. In Subversion speak, 'A' means that your file me.cpp is scheduled for addition.
M is for Moose. In Subversion speak, 'M' means that your file synthetic.h has been modified since your last commit.
C is for Cardigan. In Subversion speak, 'C' means that your file is in a state of conflict!
D is for Done. In Subversion speak, 'D' means that your file is scheduled for deletion.
There are several reasons why the status command should become your new best friend.
- All the other kids are doing it and it's better then jumping off a cliff.
- By seeing the changes you have made, you will have a better idea of how to document those changes in your -m flag once you decide to commit those changes.
- The status can alert you to potential conflicts between the changes you have made and the local changes in your working copy.
- You don't have to have a network connection.
- See Number One. (Oh no, infinite loop!)
I'm not going to spend my life being Burnt Sienna either.
I used to love Michael Jackson. I listened to 'Dangerous' like a million times growing up. One of my favorite Michael Jackson videos was "Black or White." You know the where Macaulay Culkin is punk teenager and at the end all these people from different backgrounds and ethnicities morph into each other. Like a man from African becomes an Indian woman. And that woman becomes a Chinese Man, who then turns into a New Yorker from the bronx. This is the same video in which Michael sings, "I'm not gonna spend my life being a color" which I think it a great thing to say because we I too think that we should not spend our lives being "green" or "acqa" or "mother-of-pearl," but instead be human beings. Anyway, the entire premise of the video was great because it preached that we should look past our differences and embrace our collective similarities.
Thankfully, Subversion doesn't see it this way. It does not look past our differences. In fact, it keeps record of them. Using the Diff command, one can see the differences between your working copy and the last version that has been committed.
$ svn diff Index: ThreatenAnimal.rb =================================================================== --- ThreatenAnimal.rb (revision 5) +++ ThreatenAnimal.rb (working copy) @@ -1,2 +1,2 @@ -puts 'Stop Looking At Me Pignot Noir!' +puts 'Stop Looking At Me Pignot Grigio!'
It seems as if i changed 'Stop Looking at me Pignot Noir' to 'Stop looking at me 'Pignot Grigio.' The Diff command prints the differences to the console window in a very easy-to-understand format. Are you ready?
- Lines that have '-' at the beginning are removed.
- Lines that have '+' at the beginning are added
Instead of printing all this useful information to the console where it could possibly be lost forever, why not print it to a file?
$ svn diff > thedifferencefile
Now you can E-mail the file to your friends, IM it to your significant other, facebook it just "because you can", or print it for religious reasons.
We all Make Mistakes
When I was six grade I got caught shop-lifting a yin-yang chain from the spectacular Spencer's gifts. I put it in my hat. The store-man saw me in the security mirror. He took me to the back and called my parents. My dad came and yelled at me. He took me home. My mom yelled at me. I was ashamed. What I am saying is that we all make mistakes, but unfortunately, unlike Subversion, real-life doesn't have a revert command.
Above, in ThreatenAnimal.rb I changed the line 'Stop looking at me Pignot-Noir' to 'Stop looking at me Pignot-Grigio' which, in hindsight, was kind of dumb. I mean, I really don't want Pignor-Noir to look at me, but the bottom line is that Pignot-Grigio, with it's fantastic flavorings of citrus and rutabaga, can look at me all day long if it wants to. I made a mistake. How can I possibly go back to how things used to be?
$ svn revert ThreatenAnimal.rb Reverted 'ThreatenAnimal.rb'
Simple. The Revert command reverts the file to it pre-modified state by overwriting it with the cached version of the file in the secret-hidden .svn folder. NOTE: This can only be done if the file has not-yet been committed.
Conflict Resolution 101
The situation is as follows: You are driving down the left-lane of a two-lane highway when traffic comes to a stand-still. You see that this is because your lane is coming to an end up ahead because of construction and everyone in your lane is merging into the right lane. You think of yourself as a nice-guy good-citizen type, so instead of waiting till the very last second to merge, you put your right-blinker on, and merge your way into the right lane whenever you can get someone to let you in. I found out this week that this is stupid way to merge. In fact, you think you are doing the correct thing, the morally-upright thing, but really you are slowing down traffic even more. If no one were to merge until the very last second, you would save upwards of 20% or more time. But there's nothing to tell people this. No sign or indication. In fact, it is counter-intuitive to wait until the very last second to merge and if you wait till the very last second everyone else thinks you are a jerk.
Merging files in Subversion in tricky. It's not easy, and, like on the highway, you could come off looking like a big jerk. Let me demonstrate. You edit ThreatenAnimal.rb one more time changing "Pignont Noir" to "Madame Bovary." At the same-time, your teammate Jake Gyllenhaal checks-out, edits, and commits ThreatenAnimal.rb to look like the following:
puts 'Stop Looking At Me Pignot Noir!' puts 'But, I mean, you can look look look' puts 'If you really really want to'
Jake obviously has some feelings for Pignot Noir. Which I think is a little strange. But you don't know about these changes yet. So before you commit your changes, you decide to do a final update to make sure everything is in tip-top order.
$ svn update
C ThreatenAnimal.rb
Updated to revision 7.The 'C' next to TheatenAnimal.rb stands for Conflict!
When a Subversion Conflict happens three new files are created in the same directory as TheatenAnimal.rb.
$ ls
ThreatenAnimal.rb ThreatenAnimal.rb.r6
ThreatenAnimal.rb.mine ThreatenAnimal.rb.r7- ThreatenAnimal.rb now contains special markers like <<<<<<<< and ====== and >>>>>>>> which "visibly demonstrate" the differences between between your copy and Jake's to help you make a decision about how to merge both files.
- TheatenAnimal.rb.mine contains the your file as it existed in your Working Copy before you did the update. Ex. puts 'Stop Looking at me Madame Bovary!'
- ThreatenAnimal.rb.r6 contains the file as it looked when you originally checked it out from the Repository. Ex. puts 'Stop Looking at me Pignot Noir'
- TheatenAnimal.rb.r7 contains Jake's version of the file that he committed to the Repository
At this stage you've got choices.
- Merge the conflict by hand. Open up TheatenAnimal.rb, look at the markers. Make decisions.
- Copy one of the temporary files on top of your working file.
- Run svn revert TheatenAnimal.rb to throw away all of your changes
- Freak out.
While #4 seems incredibly promising, option #1 is possibly more satisfying. But who I am to judge? So you open up TheatenAnimal.rb in your favorite text editor and see the following:
<<<<<<<<< .mine puts 'Stop Looking At Me Madame Bovary!' ======= puts 'Stop Looking At Me Pignot Noir!' puts 'But, I mean, you can look look look' puts 'If you really really want to' >>>>>>>>>> .r7
The text between <<<<<<<<.mine and ===== shows your copy
The text between ======= and >>>>>>>>> .r7 shows Jake's copy
Now, this is where you have to be careful. A "big jerk" would just delete all the changes Jake made (which would be sad because he's a very busy man between programming and his full fledged acting career) and keep all of your own changes. But you aren't a jerk, are you? So you call up Jake, and the following conversation takes place.
Jake: "Hello?"
You: "Jake!"
Jake: "Oh hey man."
You: "Hey, uh yeah. Just a quick question. I know you are busy making Donnie Darko II."
Jake: "Yeah, it's cool man. What's up?"
You: "Well, you know TheatenAnimal.rb? I know you are in love with Pignot Noir, but I really need it to be Madame Bovary. She's, well, theatening, but classic. You know? Is that cool?"
Jake: "Oh yeah man. I totally understand. I'm in love with Madame Bovary too, but don't really want her to loook at me. It's complicated."
You: "So, you trust the changes I'll make?"
Jake: "Do it Doug."
So, you merge both Jake's file and your file together. The final outcome is below.
puts 'Stop Looking At Me Madame Bovary!' puts 'But, I mean, you can look look look' puts 'If you really really want to'
The conflict between You and Jake is now resolved. Tell subversion that.
$ svn resolved ThreatenAnimal.rb Resolved conflicted state of 'ThreatenAnimal.rb'
The resolve command resolves the conflict and deletes all the temporary files created when the whole conflict between you and Jake started.
You are now ready to commit the merged file.
$svn commit -m "My compromise with Jake with a strange fear and a love of Madame Bovary" Sending ThreatenAnimal.rb Transmitting file data . Committed revision 8.
Version Control can be complicated sometimes especially when celebrities are involved. Jake's cool, but most of them are a bunch of babies.









