Comparing the working change set against the log

Mar 17, 2011 at 8:23 PM

Suppose you want to dump the list of change sets, and highlight the 'working' set. e.g.

            RevSpec working = repository.Identify();

            foreach (var changeSet in repository.Log()) {
                Console.WriteLine(changeSet.CommitMessage);
                if (changeSet.Revision == working) {
                    Console.WriteLine("*** Working changeset!");
                }
            }

This code doesn't work because Identify() returns the short 12 char hash, while Log() returns the full 40 chars. Since the short one appears to be a prefix of the long one, we can instead write 'if (changeSet.Revision.ToString().StartsWith(working.ToString()))'. This works, but is a bit quirky.

Wondering if there is a cleaner approach. Maybe RevSpec could have a custom comparer that would just make that work?

Coordinator
Mar 17, 2011 at 8:58 PM

There's another way to identify the parent of the working folder, you can use a revset of ".", which there is a RevSpec property for, WorkingDirectoryParent, so you could do this:

    RevSpec working = repository.Log(new LogCommand().WithRevision(RevSpec.WorkingDirectoryParent)).First().Revision;

This will give you the exact same changesets and revision hashes, since you're just using the log command to do it.

As for a custom comparer, perhaps that's a good idea as well.

Coordinator
Mar 17, 2011 at 9:03 PM

The log command revspec support is really far more advanced than I currently have implemented, if you need other patterns for which there are no properties or methods on the RevSpec object I suggest you use the RevSpec.ByBranch method, since this will accept anything, so you can build a full expression through a string, if you need to.

Mar 17, 2011 at 9:18 PM

Thanks, using Log() to get the parent of the working folder makes sense. And it's good to be able to drop to the full power of the cmd line when the API abstraction is not complete.

Very cool project overall, more people should try it!

Coordinator
Apr 26, 2011 at 10:55 AM

There's now several other ways to get hold of the same information.

First and foremost, revision numbers, while untrustworthy across multiple repositories, are usable in the current, local, repository, at least until you start changing the repository contents, for instance by pulling, or whatnot.

To get something that can identify the current working folder revision, you can use:

    RevSpec working = repo.Identify();

or:

    int leftParentRevNo = repo.Summary().ParentRevisionNumbers.First();

I have decided, at least for now, that those 12-character hashes, if I can avoid them, is best avoided, precisely because they create confusion when they can't be directly compared with the 40-character hashes.

If, after getting hold of a revision number, you still want the hash, here's how to get it:

    RevSpec hash = repo.Log(revNo).First().Revision;
Make sure you retrieve the hash directly after getting the revision number. If you keep the revision numbers around for long, and modify the repository, that might invalidate that number without warning (ie. the number now refers to some other changeset instead of the one you originally retrieved.)

Apr 26, 2011 at 8:35 PM

Thanks Lasse! I'll try that when I get back to my little project that was trying to use that.