views:

217

answers:

6

My workflow usually involves me making multiple changes to a file, each of which belongs to it's own conceptual unit of change across the project (= commit).

What I would like to be able to do is to add certain diffs (either a whole file, or only certain lines of a file) to a pending commit (which would probably have to be named) and to have multiple pending commits 'active' at the same time.

Then when all changes related to a particular pending commit are complete across all files, I can commit the named commit!

Any ideas of which VCS would be a good candidate for this?

+7  A: 

In svn, you can define changelists and then commit only the files in a particular changelist.

Git goes a bit further, and allows you to record patches by interactively selecting changed chunks from a file with git add -p.

Though popular, these features are contrary to best practices. You cannot test your changes properly in this way. Everything may work in your working copy, yet a commit of only part of the changes may break the build. Using feature branches is much safer, and any modern version control system supports this.

There are also the Mercurial ShelveExtension and git-stash, which allow you to shelve selected changes at the granularity of patch hunks for later commits. This way of working does allow you to test properly before committing.

Wim Coenen
This is fine for me, the concept of 'breaking the build' does not apply.I wish svn changelists worked on a sub file basis though. Looks like a switch to git is on the cards, unless this feature is also available in e.g. mercurial or bazaar?
EoghanM
No, I don't think Mercurial or bazaar directly support this. You'd have to alter your work-flow to get the same effect.
Wim Coenen
You certainly can test changes when you do them like this. You just have to test them after you commit them. I have a tool that ensures every individual commit in a range passes all tests and use that before pushing a series.
Dustin
@Dustin: interesting. What do you do when one of the commits turns out to have a failing test?
Wim Coenen
Mercurial definitely supports this type of workflow using the mq (mercurial queues) extension that's built in now (https://developer.mozilla.org/en/Mercurial_Queues)
Ted Naleid
I don't really grok mercurial queues, but while looking at mercurial I stumbled on the ShelveExtension which seems to be the simplest way to do this sort of thing. I've added a note about it.
Wim Coenen
The shelve extension is a good place to start. It's sort of a poor mans patch queue as it only has a single patch file that it saves off to. I started using that and then moved to using mercurial queues when I got more comfortable.
Ted Naleid
Git equivalent of Shelve Extension from Mercurial would be git-stash; git equivalent of Mercurial Queues would be Guilt, StGit or TopGit (although the last one isn't patch management interface, but a tool to manage multiple topic branches)
Jakub Narębski
A: 

The Subversion client (>=1.5) contains the notion of a changelist: a group of files which are associated with a chosen name.

This becomes especially useful when working on several different set of files within the same working copy. Instead of having to remember each file in each set, Subversion will allow you to associate a changelist with each set of files. Most commands which take a set of files as targets will now also accept the --changelist option, which filters those targets based upon the members of the changelist. Changelist membership can be edited using the new changelist subcommand.

dfa
+1  A: 

It would be very hard to ensure that the commit of each separate change results in a buildable system.

I strongly recommend doing one thing at a time and commit each issue separately.

idstam
The concept of a buildable system may not enter the picture, e.g. a CSS file may have multiple independent modifications which affect different pages on a site. Or a changelog text file with multiple entries for different changes.
EoghanM
A: 

Content warning: my impression, based on only passing acquaintance:

If you need to micro-manage simultaneous but in some sense unrelated changes, then you may care to investigate darcs, which has a reversed emphasis when compared to systems like svn, git, or mercurial.

In darcs, the patch is the key element, and the state of a given branch is really just a summation of a set of patches. This model may suit what you are trying to do, but clearly @wcoenen's warning about best practice holds. For each set of patches, you'll need to ensure the build (whatever it might consist of) isn't broken.

BTW, are you the Eoghan M...r i think you are?

Brent.Longborough
No, don't think I'm the EoghanM you are thinking of!
EoghanM
+1  A: 

in bzr you can use shelve/unshelve commands to get some changes out of your files and then back, or use loom plugin to easily manage set of related patches. But neither of these will solve your original request, and I'm doubt any VCS can do it this way.

bialix
+1  A: 

The original request sounds a lot like "cherry picking": manually selecting fragments of a "diff" to include in a new commit. At least Git and Darcs support that. For emacs + git there is gitsum, which I like a lot.

zut
Thanks - that's exactly the kind of tool I'm looking for
EoghanM