views:

803

answers:

9

Background

I work on a lot of small projects (prototypes, demos, one-offs, etc.). They are mostly coded in Visual Studio (WPF or ASP.NET with code written in C#). Usually, I am the only coder. Occasionally, I work with one other person. The projects come and go, usually in a matter of months, but I have a constantly evolving set of common code libraries that I reuse.

The problem

I've tried to use source control software before (SourceGear Vault), but it seemed like a lot of overhead when working on a small project, especially when I was the only programmer. Still, I would like some of the features that version control offers.

Here's a list of features I'd like to have:

  1. Let me look at any file in an older version of my project instantly. Please don't force me through the rigmarole of (1) checking in my current work, (2) reverting my local copy to the old version, and (3) checking the current version back out so I can once again work on it.
  2. In fact, if I'm the only one on the project, I don't ever want to check out. The only thing I want to be able to do is say, "Please save what I have now as version 2.5."
  3. Store my data efficiently. If I have 100 Mb of media in my project, I don't want that to get copied with every new version I release. Only copy what changes.
  4. Let me keep my common library code files in a single location on my hard drive so that all my current projects can benefit from any bug fixes or improvements I make to my library. I don't want to have to keep copying my library to other projects every time I make a change.
  5. However, do let me go back in time to any version of any project and see what the source code (including the library code) looked like at the time that version was released.
  6. Please don't make me store a special database server on my machine that makes my computer take longer to start up and/or uses resources when I'm not even programming.

Does this exist?

If not, how close can I get?

Edit 1: TortoiseSVN impressions

I did some experimenting with Subversion. A couple observations:

  1. Once you check something in to a repository, it does stuff to your files. It puts these hidden .svn folders inside your project folders. It messes with folder icons. I'm still yet to get my project back to "normal". Unversion a working copy got me part of the way there, but I still have folders with blue question mark icons. This makes me grumpy :-/ Update: finally got rid of the folder icons by manually creating new folders and copying the folders over. (Not good.)

  2. I installed the open source plugin for Visual Studio (AnkhSVN). After creating a fresh repository in my hard drive, I attempted to check in a solution from Visual Studio. It did exact what I was afraid it would do. It checked in only the folders and files that are physically (from the POV of the file system) inside my solution folder. In order to accomplish item #5 above, I need all source code used by solution to be check in. I attempted to do this by hand, but it wasn't a user friendly process (for one thing, when I selected multiple library projects at once and attempted to check them in, it only appeared to check in the first one). Then, I started getting error dialogs when I tried to check in subsequent projects.

So, I'm a little frustrated with SVN (and its supporting software) at this point.

Edit 2: TortoiseHG impressions

I'm trying out Mercurial now (TortoiseHG). It was a little bit difficult to figure out at first, no better or worse than TortoiseSVN I'd say. I noticed an RPC Server on startup (relates to item 6). I figure it should be possible to turn this off if I'm not sharing anything with anyone, but it wasn't something I could figure out just by looking at the options (will check out the help later).

I do appreciate having my local repository as just a single .hg folder. And, simply throwing the folder in the Recycle Bin seemed to be all I needed to do to return everything back to normal (i.e., unversion my project). When I check in (commit), it seems to offer a simple comment window only. I thought maybe there would be a place to put version numbers.

My (probably not very clever) attempt to add a Windows shortcut (a folder aliasing my library projects) failed, not that I really thought it would work :) I thought maybe this would be a sneaky way to get my library projects (currently located elsewhere) included in the repository. But no. Maybe I'll try out "subrepos", but that feature is under construction. So, iffy that I'll be able to do items 4 and 5 without some manual syncing.

+3  A: 

I think Fog Creek's new product, Kiln, will get you pretty close. In response to your specific points:

  1. This is easily done through the web interface -- you don't need to touch your local copy or update. Just find the file you want, click the revision you want to see, and your code will be in front of you.
  2. I'm not sure you can do things exactly like "Please save this as version 2.5", but you can add unique tags to changesets that allow you to identify a special revision (where "special" can mean whatever it wants to you).
  3. Mercurial does a great job of this already (which Kiln uses in the back end), so there shouldn't be any problems in this regard.
  4. By creating different repositories, you can easily have one central 'core' section which is consistent across various projects (though I'm not entirely sure if this is what you're talking about).
  5. I think most version control systems allow you to do this...
  6. Kiln is hosted, so there's no hit on performance to your local machine. The code you commit to the system is kept safe and secure.

Best of all, Kiln is free for up to two licenses by way of their Student and Startup Edition (which also gets you a free copy of FogBugz).

Kiln is in public beta right now -- you can request your account at my first link -- and users are being let as more and more problems are already resolved. (For some idea of what current beta users are saying, take a look at the Kiln Knowledge Exchange site that's dedicated to feedback.)

(Full Disclosure: I am an intern currently working at Fog Creek)

Andrew Song
Re: item 4, let me try to explain. Let's say I have a library project called "Lib", a solution "A", and another solution "B". Both "A" and "B" use "Lib", but "Lib" is not physically contained in the solution folder for either "A" or "B". I just add it as a link to "A" and "B". However (this relates to item 5), when I "check in" my code to release a new version of (say) solution "A", I want all the code from "Lib" to be part of that version, so if I go back later, I will "go back in time" and see what "Lib" looked like at the time I released that version. Hope that makese sense :)
DanM
Oh, and BTW, the Kiln support site looks suspiciously familiar :-P
DanM
Yes, you can most definitely do that with Mercurial and Kiln. To be fair, Kiln is (very roughly speaking) a simplification layer on top of Mercurial. It provides a very easy-to-use GUI along with some extra (important) features like bug tracking (via FogBugz) and code reviews. While you probably wont code review your own stuff, if you're working with another person this might come in handy. It's very easy to set up a repository using Kiln as Fog Creek has developed tools extending what TortoiseHg will give you (again, simplification layer).And it's still free. :)
Andrew Song
(Why the random downvote...?)
Andrew Song
Was wondering the same thing...wasn't me!
DanM
At the office we already use FogBugz - but not Kiln - thanks for the TIP, Im in exactly the same situation - but with PHP projects - will give it a go - in fact I just create my account - if it works - thats it...
Ronaldo Junior
+5  A: 

For your requirements I would recommend subversion.

Let me look at any file in an older version of my project instantly. Please don't force me through the rigmarole of (1) checking in my current work, (2) reverting my local copy to the old version, and (3) checking the current version back out so I can once again work on it.

You can use the repository browser of Tortoise Svn to navigate to every existing version easily.

In fact, if I'm the only one on the project, I don't ever want to check out. The only thing I want to be able to do is say, "Please save what I have now as version 2.5."

This is done by svn copy . svn://localhost/tags/2.5.

Store my data efficiently. If I have 100 Mb of media in my project, I don't want that to get copied with every new version I release. Only copy what changes.

Given by subversion.

Let me keep my common library code files in a single location on my hard drive so that all my current projects can benefit from any bug fixes or improvements I make to my library. I don't want to have to keep copying my library to other projects every time I make a change.

However, do let me go back in time to any version of any project and see what the source code (including the library code) looked like at the time that version was released.

Put your libraries into the same svn repository as your remaining code and you'll have global revision numbers to switch back all to a common state.

Please don't make me store a special database server on my machine that makes my computer take longer to start up and/or uses resources when I'm not even programming.

You only have to start svnserve to start a local server. If you only work on one machine you can even do without this and use your repository directly.

tangens
Thanks @tangens, you mention `svn copy . svn://localhost/tags/2.5`. This makes me fear I have to learn a whole set of commands to use it. Are there any good GUI options? Or it that what Tortoise Svn is?
DanM
That is what TortoiseSVN is. Whatever VCS you use, make sure to understand it -- and as simple as a UI tries to make things, this does involve learning the underlying principles. I would recommend using a *remote* VCS server (even for distributed systems) to prevent "oh, soup" scenarios such as a random harddrive failure. I even put my "binary" documents under revision control.
pst
To answer my own question, it looks like the TortoiseSVN client has a contextual menu when you right click a file or folder in Windows Explorer: http://tortoisesvn.tigris.org/ExplorerIntegration.html#contextmenus
DanM
Subversion works very well for a lone developer. If all you want is snapshots of the current state, and reasonable "diff" capabilities, it works great. I think the syntax is a little odd for some things, but Tortoise puts an easy-to-use face on it.
Mark Bessey
I'm trying this out now. Using AnkhSVN with Visual Studio, I noticed that when I added my solution to a fresh repository (local), it didn't add any of my library projects by default, it only added the project that was physically contained in the Solution folder. I'd like to add *all* the projects.
DanM
You should have a look at the svn global ignore patterns. Svn will ignore all files matching these patterns.
tangens
@tangens, my understanding of ignore patterns is they prevent bin and obj folders from being checked into the repository, since you can generate them any time you want. My problem, however, is that it's not checking in my *library* code (code I share among different solutions) because it's not in the solution folder. It's very critical that my library code get backed up and versioned as well.
DanM
@DanThMan, Ideally you'd have a separate repository for your library code (I am in a similar situation). The solution isn't elegant or automatic, but you checkout a working copy of your library to wherever, compile it, reference the assembly in your client app and every time you rebuild the library, subsequent builds of your client code will include the most recent build of your library.
SnOrfus
To building on what @SnOrfus just said take a look at `svn:externals`. This is a property that lets you transparently reference the libraries you put into their own repositories, from *within* the repository of your project. See http://svnbook.red-bean.com/en/1.5/svn.advanced.externals.html
quark
@SnOrfus, I think this is exactly the same solution I was contemplating in my first comment to @Sam's post.
DanM
I'd recommend to put the libraries and code in the same repository. Doing this it's easy to go back to a specific revision and have matching libraries for the code.
tangens
+3  A: 

I'd say that Mercurial along with TortoiseHg will do what you want. Of course, since you don't seem to be requiring much, subversion with TortoiseSvn should serve equally well, if you only ever work alone, though I think mercurial is nicer for collaboration.

Sopoforic
+7  A: 

Any of the distributed source control solutions seem to match your requirements. Take a look at bazaar, git or mercurial (already mentioned above). Personally I have been using bazaar since v0.92 and have no complaints.

Edit: Heck, after looking at it again, I'm pretty sure any of those 3 solutions handles all 6 of your requested features.

jkchong
+1 for distributed vcs. Local copy is itself a repository
Konstantin
Thanks @jkchong, but how is distributed an advantage for my situation?
DanM
For your situation, the distributed aspect isn't a concern. What they offer is a simple, full featured version control system that requires no infrastructure.
JimB
I second @JimB: The advantage of any of those tools isn't the distributed part necessarily, it's ease of use.
quark
@JimB tells it as it is. No need to worry about a database server/process (feature 6) and feature (4) is either supported out of the box, or via a free plugin/extension.
jkchong
+4  A: 

Distributed Version Control Systems (Mercurial, Bazaar, Git) are nice in that they can be completely self-contained in a single directory (.hg, .bzr, .git) in the top of the working copy, where Subversion uses a separate repository directory, in addition to .svn directories in every directory of your working copy.

Mercurial and Subversion are probably the easiest to use on Windows, with TortoiseHG and TortoiseSVN; the Bazaar GUIs have also been improving. Apparently there is also TortoiseGit, though I haven't tried it. If you like the command line, Easy Git seems to be a bit nicer to use than the standard git commands.

I'd like to address point 4, common libraries, in more detail. Unfortunately I don't think any of them will be too easy to use, since I don't think they're directly supported by GUIs (I could be wrong). The only one of these I've actually used in practice is Subversion Externals.

Subversion is reasonably good at this job; you can use Externals (see the chapter in the SVN book), but to associate versions of a project with versions of a library you need to "pin" the library revision in the externals definition (which is itself versioned, as a property of the directory).

Mercurial supports something similar, but both solutions seem a bit immature: subrepository support built-in to the latest version and the "Forest Extension".

Git has "submodule" support.

I haven't seen anything like sub-respositories or sub-modules for Bazaar, unfortunately.

Sam
DanM
If I get your meaning, then yes, if you manually tag the project and the library like that, then you could always get back to that revision.However, the main way that SVN externals (and subrepos, etc.) work is that you would have a copy of the library in a subdirectory of the project, i.e. `C:\MyProject\Libraries`. When you wanted to go to a newer version of Libraries, you update the externals property and update the `MyProject` working copy, and then commit. Then if you switch to or check out an older version of `MyProject`, it would automatically have the correct version of `Libraries`.
Sam
@Sam, sounds good, but I have one concern. Let's say I'm on version 2.5 and I want to revert back to version 2.4. When I do this, will SVN put my library files back where they originally were (in `C:\Libraries`) or will it put them in `C:\MyProject\Libraries`? If it's the latter, my project wouldn't compile in Visual Studio (I'd have to re-add the library projects under their new location). With the (manual) system I outlined above, I get a little added flexibility (I could, say, stick with the latest library but still revert my project to version 2.4) at the cost of a little added work.
DanM
@DanThMan: Yes, you're right about the manual system, and in your case it sounds like that would be a good way to go. As tangens mentioned, this will work best if everything is in one repository. If you always developed with the latest libraries, then, say, revision 53 of any given project corresponds to r53 of the libraries. You can, of course, also tag things in a very flexible way. Basically, SVN lets you do things in many different ways, which gives it advantages and disadvantages compared to the distributed VCSs.
Sam
A: 

Try GIT. Lots of positive comments about it on the Web.

Vijay Patel
A: 

As people have pointed out, nearly any DVCS will probably serve you quite well for this. I thought I would mention Monotone since it hasn't been mentioned already in the thread. It uses a single binary (mtn.exe), and stores everything as a SQLite database file, nothing at all in your actual workspace except a _MTN directory on the top level (and .mtn-ignore, if you want to ignore files). To give you a quick taste I've put the mtn commands showing how one carries out your wishlist:

  1. Let me look at any file in an older version of my project instantly. mtn cat -r t:1.8.0 readme.txt

  2. Please save what I have now as version 2.5 mtn tag $(mtn automate heads) 2.5

  3. Store my data efficiently. Monotone uses xdelta to only save the diffs, and zlib to compress the deltas (and the first version of each file, for which of course there is no delta).

  4. Let me keep my common library code files in a single location on my hard drive so that all my current projects can benefit from any bug fixes or improvements I make to my library. Montone has explicit support for this; quoting the manual "The purpose of merge_into_dir is to permit a project to contain another project in such a way that propagate can be used to keep the contained project up-to-date. It is meant to replace the use of nested checkouts in many circumstances."

  5. However, do let me go back in time to any version of any project and see what the source code (including the library code) looked like at the time that version was released. mtn up -r t:1.8.0

  6. Please don't make me store a special database server on my machine SQLite can be, as far as you're concerned, a single file on your disk that Monotone stores things in. There is no extra process or startup craziness (SQLite is embedded, and runs directly in the same process as the rest of Monotone), and you can feel free to ignore the fact that you can query and manipulate your Monotone repository using standard tools like the sqlite command line program or via Python or Ruby scripts.

Jack Lloyd
+1  A: 

Mercurial:

  1. hg cat --rev 2.5 filename (or "Annotate Files" in TortoiseHg)
  2. hg commit ; hg tag 2.5
  3. Mercurial stores (compressed) diffs (and "keyframes" to avoid having to apply ten thousand diffs in a row to find a version of a file). It's very efficient unless you're working with large binary files.
  4. Symlink the library into all the projects?
  5. OK, now that I read this point I'm thinking Mercurial's Subrepos are closer to what you want. Make your library a repository, then add it as a subrepository in each of your projects. When your library updates you'll need to hg pull in the subrepos to update it, unfortunately. But then when you commit in a project Mercurial will record the state of the library repo, so that when you check out this version later to see what it looked like you'll get the correct version of the library code.
  6. Mercurial doesn't do that, it stores data in files.
Steve Losh
DanM
Or for 1. do: `hg revert -r 2.5 <filename>`.
quark
**@quark:** That will actually change the contents of the file in the working directory which it seemed like he didn't want to do -- he just wanted to view it. But yes, if you actually want to change the file that's the command you'd use.
Steve Losh
**@DanThMan:** Yeah, subrepos are a fairly new feature and they might change in the future, but even if they do it probably won't be *too* much, and will be for the better.As for where the stuff goes: if `project/` is your project repository you would clone the `library/` repo into it (so you've got `project/library/`) and make it a subrepo. That clone is what will get updated when you update to an old revision of the main repo, **not** the main `library/` repo.
Steve Losh
@Steve, either is problematic. I think what I really want to do is Export (that's the command in TortoiseSVN) everything (main project and shared library projects) to a new working directory. I would still probably have to rehook the projects in Visual Studio (unless the relative references remain the same), but that's better than writing over the working directory containing my shared libraries.
DanM
For Bazaar, Feature 4 is supported via a plugin (scm-project) or a shared repository (bzr init-repo)
jkchong
A: 

Take a look on fossil, its single exe file. http://www.fossil-scm.org

Ahavoo