0

I'm fairly new to Mercurial, but one of the advantages I see using Mercurial is that while writing a feature you can be more free to experiment, check in changes, share them, etc, while still maintaining a "clean" repo for the finished feature.

The issue is one of history. If I tried 6 different ways to get something to work, now I'm stuck with all of the history for all my mistakes. What I'd like to do is go through and clean up my changes and "collapse" them into one changeset that can be pushed into a shared repository. This is complicated by the fact that I might pull in new changesets from the shared repository, and have those changesets intermingled with my own.

The best way I know of to do that is to use hg export to create a patch of my changes since cloning, clone a fresh repository, and apply the patch to the fresh repository.

Those steps seems a little bit cumbersome and easy to mess up, particularly if this methodology is rolled out to the whole dev team, some of whom are a little resistant to change (don't get me started). TortoiseHg makes the process slightly better since you can highlight the changesets you want to be included in an export.

My question is this: Am I making this more complex than it needs to be? Is there a better workflow I can use to ease my troubles? Is it too much to expect a clean history where entire (small-ish) features are included in one changeset?

Or maybe my whole question could be summed up this way:

Is there an equivalent for this in mercurial? Collapsing a git repository's history

Community
  • 1
  • 1
JWman
  • 297
  • 1
  • 14
  • 1
    Is there a reason you aren't using branches? http://mercurial.selenic.com/wiki/Branch – David Brown Apr 20 '11 at 15:17
  • Are you asking how to experiment safely when using Mercurial, for future reference, of are you asking how to take your existing experiments and get rid of them, or are you asking how to take your existing experiments and collapsing their changesets and keep those? I'm a bit unsure since you seemed to be describing quite a few things you'd like to do. Can you narrow it down? – Lasse V. Karlsen Apr 20 '11 at 15:18
  • Sorry about the ambiguity. Basically I view my experimental history as a meandering path towards an end result, but I'd like my final push to the shared repo to ignore all the intermediate steps I took to get there. Basically, I want to push a diff between my working copy and the version in the shared repository, without all of the history of "oops, this didn't work". – JWman Apr 20 '11 at 15:24
  • And I'm not using branches probably due to leftover distaste for subversion branching and the fact that cloning repositories is easier to keep track of (in my opinion). – JWman Apr 20 '11 at 15:27
  • 1
    @JWman you should shake that SVN-based distaste if you are going to continue using Hg. One of the best things about Hg (and one of the most touted things) if that branching and merging "just work". Give these features a shot on your own time and if (or once) you are convinced, you can try to share them with your team. – dls Apr 20 '11 at 17:13
  • @dls I'm curious if you have any experience in transitioning to mercurial. We've been using SVN forever and recently made a switch to mercurial, mostly to make branching easier, but the team is already having enough mind-bending to get used to the new work flow of pull-update-commit-push (and variations) instead of just update-commit. I think that adding a new dimension of branches within the repo might do more harm than good, though I do see some value in it. – JWman Apr 20 '11 at 18:50
  • @JWman Believe me, I understand the concern. A co-worker and I have just finished transitioning an embedded SW team of 50+ developers to Mercurial and TortoiseHg, complete with named branches, sub-repos, the whole deal. Any team being asked to change VCS will reject the new technology to some degree, but it's important to separate that from the merit of the technology. That's all! – dls Apr 20 '11 at 19:05
  • @dls Thanks for your comments. Haha, I bet that was a fun transition. Mostly when I say "do more harm than good" I'm talking about my sanity since I've somehow become the go-to guy for Mercurial questions, but I feel like I just know enough to be dangerous. Our team just has 4 developers, but with more coming soon, we're hoping to lay a solid foundation of processes/tools to minimize headaches in the future. I'll have to look more into branching and toy with it. – JWman Apr 20 '11 at 19:25

2 Answers2

3

Although I think you should reconsider your use of branches in Mercurial (as per my comment on your post), using named branches doesn't really help with your concern of maintaining useless or unnecessary history - it just organizes them a bit.

I would recommend a combination of these tools:

  1. mercurial queues
  2. histedit (not distributed with Hg)
  3. the mq changeset strip feature

to rework a messy history before pushing to a blessed or master repo. The easiest thing would be to use strip to permanently remove any changeset with no children. Once you've done that you can use mq or histedit to combine, relocate, or modify existing commits. Histedit will even let you redo the comment associated with a changeset.

Some pitfalls:

In your opening paragraph you mention sharing changesets during feature development. Please understand that once you've shared a changeset it's not a good idea to modify using mq or histedit, or strip. Using these extensions can result in a change to the revision hash, which will make them look like a new changeset to everyone else.

Also, I agree with Paul Nathan's comment that mq (and histedit) are power features and can easily destroy a history. It's a good idea to make a safety clone before using these extensions.

dls
  • 4,146
  • 2
  • 24
  • 26
1

Named branches are the simplest solution. Each experimental approach gets its own branch.This retains the history of the experiments.

The next solution is to have a fresh clone for each experiment. The working one gets pushed back to the main repo.

The next solution - and probably what you are really looking for - is the mq extension, which can "squash" a series of patches into a single commit. I consider mq to be "advanced", and "subject to accidently shooting yourself in the foot". I also don't care to squash my commits - I like having my version history present for reference.

Paul Nathan
  • 39,638
  • 28
  • 112
  • 212