SVN Primer

From Kolmafia
(Redirected from Svn)
Jump to navigation Jump to search


Subversion (svn) is a centralized version control system. A repository (repo) exists online — this repo contains a scripting project. KoLmafia can download scripts from an online SVN repo and automatically install them for the user. It can even automatically update scripts to the latest version without any effort from the user.

Non-Technical FAQ

Q. What is this "SVN" thinggy?
A. It's a better way for users to install scripts.

Q. What do I have to know about SVN to use this feature?
A. Absolutely nothing! There's a Script Manger under the Scripts menu. You can select scripts you want to install, right-click and select "install script." Then the magic happens. It's really simple.

Script Manager Abridged.png

Q. At the top of the page you said "automatically update scripts." None of my scripts have updated themselves so how does that work?
A. There's a preference you have to set to enable it which is off by default. Go to Preferences -> SVN -> Check "Update installed SVN projects on login." That will cause all your SVN installed scripts to be updated once a day.

Preferences SVN.png

Q. Why is SVN good for KoLmafia scripts?
A. There are a whole bunch of reasons. I'll enumerate:

  1. It makes finding the script you want easy. Just read down the list checking the description for each.
  2. It makes script installation easier. The user doesn't have to ensure that the script is downloaded into the correct directory or fret about putting multiple files into multiple directories.
  3. It makes script updating easier. All scripts can be updated automatically at first run of the day, or the user can type svn update to manually update all scripts.
  4. It is easier for the scripter to publish his scripts and keep them up to date.
  5. When you recommend a script in chat, you can tell them its name in the Script Manager without their having to go download something from the KoLmafia forum.

Q. Why was this added to mafia?
A. We understand that a lot of people don't use scripts, even scripts that will help them a lot. This is because they find it troublesome to find and install scripts. The intention is to make it easy to install scripts. Even a script like Character Info Toolbox which contains more than 30 files is easy to install now. Just install it from Mafia's Script Manager and every single file will be placed in the correct directory. If you don't like it, you can use the Script Manager to delete it and all those files are removed.

Q. Wait! Does this mean I don't have to find the correct thread on the KoLmafia forum and login there to install a script?
A. Yup. It's incomprehensible to most of us, but we've noticed that people hate reading our forum. Now you won't have to do that.

Q. This sounds like black magic!
A. Please state your problem in the form of a question.
Q. How does that work?
A. Black magic. Not really, but it is very impressive and you don't really need to know the mechanics. Just trust that it works.

Revision Merging

There is another even more impressive ability of the KoLmafia's svn update: Revision Merging! This is only helpful to people who know how to modify someone's script, but you only need to understand a few lines of any script to make this worth reading.

The real awesome here is aimed at people who sometimes like to make small modifications to their scripts. People like you with a little bit of scripting ability. I suspect you've sometimes made a tiny tweak to a script to make it more perfect for your specific needs. Then the original author updates his script and you're stuck trying to decide if it is worth your trouble to copy all your modifications to the new version of his script. If not, you might just refuse to update it. With SVN if you know what you are doing, you can update your cake and eat it too! When svn updates your script it will automatically keep your modifications, producing a blend of your modifications and the author's update. Now I'll tell you how to do this.

  1. Acquire the most recent version using svn update
  2. Open the script's working copy in the project's /svn directory, and make your edits. Always make sure the project in /svn has your changes
  3. Use the command svn sync to push your modifications in the working copy to the local copy in the /scripts or /relay directory
  4. If you ever want to modify your changes or add to them, just repeat steps 2 and 3.

That's it! Now you can update from svn as usual. You can use svn update bale-ocd to update just that script, or svn update to update all your scripts or just check the box in SVN preferences to make it happen automatically once a day. Whenever the script is updated SVN will magically merge your changes into the working copy in the /svn folder and then push those changes into the local copy. This is magic! This will happen every single time you use svn to update the script without requiring your intervention. The CLI will display a "G" for merGing the script instead of a "U" for Updating it when this happens.

Revision Conflicts

If an update to a script changes it so severely that it cannot be merGed with your modifications, it will show "C" for Conflict and produce several files in the working copy to help you solve the problem:

  • myfile - will have some inline markup at the location of the conflict ( look for <<<<<< and >>>>> markup) showing you both what your text was and what the repo's text was.
  • myfile.mine - Your version before the update.
  • myfile.rOld - The pristine repo versions from before the update.
  • myfile.rNew - The pristine repo versions from after the update.

With all of these files, you can pretty easily figure out where the problem line(s) are, and how to fix them. Sometimes you'll just want to use rNew and discard your local changes, sometimes you'll want to do something else. Copy/pasting between the different files is straightforward. You will need to delete the extra files when you're done resolving the conflict, and make sure that the remaining file has the same name as the original file.

Information for Scripters

The SVN repo contains your project. It not only contains the files for your project, but every previous version of those files that's ever existed. Think of old versions like hitting ctrl-z on a Word document — you can revert changes all the way back to the start, or anywhere in between.

It is more than just a place to save files though. There is something called a Working Copy, which is a local version of a remote repository, plus any local changes you may have made. The process of creating this Working Copy is referred to as "checking out" the repo, or "checkout." You have probably also heard the term "commit" which is simply taking some/all local changes in a working copy and syncing them with the repo. Then other users sync their working copies with the repo, and voila!

How to Set Up a Repo

A working copy contains a hidden folder, .svn, that contains all of the metadata needed to know how your local version differs from the repository's version. This is created for you when you checkout the project. You don't really need to know any of these details, really, for the most part using svn does not require knowing how it works under the hood. What you may be interested in is how to create your own repo.

I'll go over the easiest method under Windows - using TortoiseSVN. Under *nix you should probably just be using the command line "svn" client, though I imagine there are a million different graphical alternatives. There are alternatives in windows as well, I just prefer TortoiseSVN for its file system integration.

First, get a sourceforge account. Make a new project there. Download TortoiseSVN and install it. Make a new folder somewhere on your computer. Right-click, and choose SVN Checkout... from the context menu. You will want to give it the address that you see on your new sourceforge project code page - for now just grab the http:// address, it's easier. Ignore the commands in front of the address and after it, those are for command-line svn tools.

The rest of the default options are okay. Click OK and you should get a new working copy of your repo! Cool. Open it up and let's add some stuff. Add a new directory called scripts/, and within scripts/ put a new text file. Now navigate back up to the root of your working copy, right click on the folder, and choose SVN commit... Tick all the files/folders (tick the "show unversioned files" box if it's not ticked), give it a quick commit comment up top. You should have to enter your sourceforge user information, save it if you want. If you've done everything correctly, your new project should have been committed.

Optional: to really play around with this, checkout a second working copy somewhere in another folder on your computer. Try committing changes from one working copy to the repo, then doing right-click SVN Update on the other working copy. Notice how TortoiseSVN helpfully changes the little file/folder icons for you when you make modifications to things. Hopefully you're starting to see how this whole thing works.

What it Can Do

Svn is a very mature tool by now, so there's an absolute ton of stuff that I won't cover. You may for example notice that mafia itself has a "Latest SVN Changes" forum, which has .diffs of all the changes to files within mafia. There's also creating patches, merging repos, yada yada... Won't talk about it.

I'm more interested in talking about how mafia svn integration works. Doing svn checkout <repo> creates a working copy of the repo in your svn/ folder. Then, mafia "pushes" the contents of that working copy to the appropriate subfolders. For example, if a repo has a scripts/dostuff.ash file, that file gets copied to your scripts/ folder.

svn update goes through all your working copies and performs an update. There are other operations that can happen here. With a checkout, you can only be adding ("A") new files to a working copy. With an update you can update ("U"), merge ("G"), delete ("D") or also add ("A") files. Here, we warn the user whenever a file is added, due to security concerns. Note that "U"pdating only happens if the "pushed" local file still exists in the user's directory. I am bolding this because I'm sure it will confuse some people. This feature is a safeguard against svn re-installing scripts over and over that the user just wants to have deleted.

If you installed TortoiseSVN above and browse to the svn/ folder, you may notice something: the working copies checked out with svn checkout are fully-featured working copies, just like you checked out using TortoiseSVN. This means that you can make changes directly to this folder and commit them to the repo using TortoiseSVN - if you have repo commit permissions, of course.


At the base level of the SVN link there are only several legal folders which may contain scripts:

  • ccs/
  • data/
  • images/ (see notes)
  • planting/
  • relay/
  • scripts/

Additionally there is only one legal file:

  • dependencies.txt

If there are any other folders or files at the base level of the SVN repository, KoLmafia will refuse to check out the repository. This is a security feature. Within the stated folders you can nest any additional folders and files you desire.

When the SVN repo is committed, the scripts in the folders will be pushed to local copies in corresponding folders in the KoLmafia directory. If there is a file of the same name in any of those folder, or a sub-folder of those folders, then the file will be copied to that location. This allows the user to move the files to new locations or sub-folders and still know that KoLmafia will keep it up to date.

Note: If your relay override script uses images, place them under images/relayimages/. This is because KoLmafia serves images only if they are under images/[1]. However, the cache clear command will delete all files under images/ except for the images/relayimages/[2].

Declaring Dependencies

The file dependencies.txt contains a list of other SVN repositories that this script will automatically install. This is done so that the script can install other scripts it depends on. If there is a dependencies.txt file at the root directory of the repo, it will not be pushed along with the files in the various folders. It only exists to serve this purpose. Each line in the file provides a url to another SVN project. Here is an example of what a dependencies.txt file may look like:

How to Command SVN

KoLmafia has both ASH and CLI commands to interact with SVN repos.

CLI Commands

SVN Repositories can be checked out, updated or deleted from the CLI with the following commands:

  • svn checkout <svnurl>
This checks out an svn repository and adds the files from the working copy to the appropriate locations. <svnurl> must be a svn://, http://, or https:// link to a valid svn repo.
  • svn list
This lists installed projects.
  • svn update
  • svn update <projectname>
  • svn update <SVNURL>
This updates your installed projects and pushes any changes to the appropriate locations. If the parameter is blank it will update everything.
  • svn delete <projectname>
This deletes an installed project and the corresponding files that it pushed. <projectname> fuzzy matches the script names from svn list.
  • svn increment <projectname>
  • svn decrement <projectname>
These two commands move an installed svn project up/down one revision, respectively.
  • svn inc <projectname>
  • svn dec <projectname>
The same as the previous two commands. Because typing stuff is hard.
  • svn sync
This looks through your working copies for modifications, then checks if that file differs from the local copy. If it differs, the working copy file is copied over the local copy one. Note that this is very different from "svn update" and does not contact the repository server at all.

ASH Commands

There are a few additional functions that ASH possesses to check up on an SVN repo.

  • boolean svn_exists( string )

    Returns true if a valid working copy named projectname exists in the /svn folder.
  • boolean svn_at_head( string )

    Returns true if projectname exists, is a valid working copy, and is currently at the same revision number as the repository.
  • record svn_info( string )

    Returns a record containing additional information about the given projectname: svnurl, last author, last revision, last change date.