Monday, February 6, 2012

Mercurial (as of 2.1) Now Has Phases

In my last post I pondered (ranted?) on the reluctance of Mercurial people to edit repository history, especially as compared to git people. Today I noticed that Mercurial 2.1 has been released, and it has a new feature that makes editing your local repository much safer, phases (more detail here).

To me this looks like a really cool idea. Phases explicitly mark changesets as either public (have been pushed or pulled, and should not be edited) or draft (still local to your repository and can be freely edited). Changesets are given a phase automatically behind the scenes (though you can override this, of course), and history editing tools respect phases so that now it is even harder to shoot yourself in the foot when editing your repository history with tools like rebase or mq.

There is also one more phase, secret, that can be enabled for use with patches in your Mercurial Queues. Secret changesets will not be pushed, pulled, or cloned (or even show up in the output of incoming or outgoing). That's a nice touch too.

I wonder if git will ever pick this idea up? Git users seem to already be pretty comfortable with history editing procedures, but I have also read (old?) debates about when it is a good idea and when it is definitely a bad idea to use rebase with git repositories. It seems like phases could clear up confusion in the git world too.

Monday, January 16, 2012

What Is So Wrong With Mercurial's Named Branches?

I just installed the very latest version of mercurial, 2.0.2. It added a new little feature that warns you when you create a branch. Huh? This is what it looks like:

$ hg branch foo
marked working directory as branch foo
(branches are permanent and global, did you want a bookmark?)

Really? Have we let the git advocates push us this far? Do we really need to start discouraging named branches?

I googled around to see if I could find where the self-hate for mercurial's named branches is coming from and I found things like this, "it is almost never a good idea to use this facility for short-term branching, since branches created this way are inherently 'eternal'." (those quotes around eternal are good, actually, but you didn't explain why they should be there), and this, "you can never really delete branches (since that would mean altering older commits)." (editing history, oh noes!), and others like this. And these were all written by apparent mercurial supporters! I understand when a git developer writes misinformation about mercurial and uses it to try and make git look better (that's only human), but we mercurial users should know not to listen to it!

Here's what I think is going wrong. Git users love flexibility. The love it so much that they even include modifying their local repository history right into their standard workflow. git rebase is a core command. From what I can gather, even though mercurial now (as of years ago, actually) has powerful rebase and patch queue extensions, mercurial users still get the heebie-jeebies when they think about modifying repository history. This is where the git envy comes from. You see, git useres can alter their branch names, or even delete branch names without using scary rebase. Fact is, though, git could adopt mercurial-style named branches and git users would rebase them away or rename them with rebase willy-nilly just like they do with everything else that they deem needs editing in their history. The fact that git users can rename or delete their branches without using rebase is almost completely incidental. If you allow the use of rebase or patch queues, mercurial named branches are not any more permanent than any other changeset in the repository history. Mercurial bookmarks allow mercurial users flexibility around branch names without needing to resort to scary history editing extensions, and that makes us happy, but I don't think that we should talk down mercurial named branches. There are times when you want the branch name associated with a commit to be just as "permanent" as the commit is. Let us do that without dumb warnings that make named branches sound like a bad idea.

The only other argument people may have against mercurial's named branches is the possibility of name collisions. As if that's something that's really hard to deal with. Anyone who has written a fair amount of C code (I'm looking at you, git developers) knows how to prefix a name to get poor-man's namespaces. Alternatively, many projects require an issue tracker number in a feature-branch or bugfix-branch name. Name collision problem solved.

In conclusion, mercurial named branches are fine. Use them more. Use rebase and/or patch queues[1] to rename or delete the branches when necessary. If that really bothers you, you have bookmarks now, but don't go all git-apologetic on named branches. Mercurial is every bit as awesome as git.

1. Before you push to a publicly accesible repository, of course. Ask a git user why that's important.

Tuesday, December 13, 2011

Make Terminal.app Useful for Emacs

Running emacs -nw in Terminal.app on my Mac has been pretty frustrating, until today. To fix the experience, download and install KeyRemap4MacBook (I sure hope it's not malware). Click on "Change Key." Scroll down until you find "For Applications." Expand that to "Enable at only Terminal" and select "Change Command_L to Option_l." Expand "Change Slash(/) Key" and select "Control+Slash(/) to Control+Underscore(_)." You might also want to select "Switch next and prev tab in terminal with shift and arrows (like Gnome term)."

All better.

Tuesday, June 14, 2011

The Dark Cockpit Theory

A co-worker who is annoyed with the verbosity of our verilog simulations just asked me if I subscribed to the Dark Cockpit Theory. I immediately replied, "no." I've had this argument a number of times with other engineers and I have already decided that more information is better than less. I had to google "dark cockpit theory" later because I'd never heard of it referred to that. For me it has always been the UNIX "Rule of Silence". Same idea, I think.

Just to be clear, I do like the Rule of Silence when it's software that I trust isn't going to do weird things or silently hang. There isn't a lot of code that I trust that much, though, and if it's software I don't trust, I want to know what it's doing, or at least that it's doing something.

As I thought about this more, it's the same with people. When a person you trust is doing something for you, they can go do it without giving you any intermediate status reports. That's easier and more efficient for both of you. When someone you don't trust is working for you, you want to hear from them often, so you know they are staying on task and doing things right. Right?

The big argument about overly noisy simulations or software is that you can't find the important messages in all the noise. I just don't understand this argument when it's coming from fellow software engineers. Especially UNIX/Linux users. We read obtuse source code all day long, and we confidently use tools like grep or the search features of vim or emacs to help us. These same tools can search through program output. UNIX shells have built-in ways to redirect program output to files if you don't want to watch it all scroll by. If you really don't like it send it to /dev/null! Use the tools of the trade. Usually what people are complaining about is that the message they want to see isn't the only one being printed. Tough! You are a UNIX user, pipe the output through grep. Take 20 minutes and write a script to filter the output if you need. You write code for a living, you know how to do these things.

Friday, April 29, 2011

Incremental Merge with Mercurial

I just learned how to merge incrementally with Mercurial. I wasn't really even aware of what that means until I learned about it. Most people use a graphical diff/merge tool with Mercurial such as kdiff3, and for a good reason. Resolving merge conflicts any other way is much more difficult. Normally when you run hg merge it merges all the files right then, and pops up your graphical merge tool right when conflicts occur. You can leave the gui window up and sort of ignore it for a while, but then you wonder what happens if your computer loses power or you need to reboot for some reason. Will your working copy be left in some weird state? What if you have already spent a lot of time resolving tricky conflicts on a previous file, you'd hate to lose that work. Or what if you know one particular file is going to be onerous and you'd like to resolve conflicts there first? Wouldn't it be nice if Mercurial could just present you a list of files with conflicts and let you deal with them on your own time and in the order that you choose? It turns out, Mercurial can do just that. Here's how:

hg merge --tool internal:merge

The first command tells mercurial to use its (not so smart) non-interactive merge tool. If it comes across a conflict it inserts markers into your files. As an alternative you can specify the internal:dump merge tool. Instead of putting markers into your files, it creates three new files with a .other, .local, and .base extension, which are a little easier to use if you want to do some manual inspection of the various versions. The cool thing, in either case, is you don't have to do anything manual. First things first though. You can now see which files have merge conflicts by typing:

hg resolve --list

Those with a U in front of them have unresolved conflicts and need some attention. Those with R in front are just fine. Here's the best part. To resolve the conflicts for a given file using your favorite diff/merge tool, and I'll use kdiff3 as an example, type this:

hg resolve --tool kdiff3 filename

The file is merged with kdiff3 (or your tool of choice) just like it would have been with a regular hg merge command. In the case of kdiff3, it's smarter than the internal Mercurial merge tool and it may resolve the conflicts without popping up a window and asking for your help. Be happy when that happens.

You can also just manually edit the files to resolve the conflicts. If you do that, type:

hg resolve -m filename

to let Mercurial know you've taken care of it. Once you see all R files when you type hg resolve --list you're all done. You can run your tests and then commit the merge.

This isn't very useful for simple merges, but for big complicated merges (where, maybe, you have waited too long and two branches have diverged a lot), this is a really nice technique.