monotone-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: RFC: mtn split (Was: [Monotone-devel] Best practice using monotone)


From: Nathaniel Smith
Subject: Re: RFC: mtn split (Was: [Monotone-devel] Best practice using monotone)
Date: Sun, 27 Aug 2006 01:45:11 -0700
User-agent: Mutt/1.5.12-2006-07-14

On Sat, Aug 26, 2006 at 10:45:24PM -0400, Ethan Blanton wrote:
> I find that I very much like the idea of 'monotone split' (after all,
> who hasn't accidentally commited an unrelated change along with a
> coherent changeset at one time or another?), but I'm not sure what I
> would expect monotone to do for me in this case.  The following is the
> best I can come up with, work-flow-wise, but providing a coherent and
> usable UI for it which is comprehensible to most would be difficult.
> 
> Suppose we have:
> 
> A--B--C
> 
> Where B is a revision which contains three logically independent
> changes from A in one commit.  It would be nice to type 'mtn split -r
> B', and have each hunk in B presented, in order, to be applied or not.
> Upon approving only those hunks which contain pieces of logical change
> #1, monotone allows me to make hand-changes with my editor (for
> example, suppose logical change #1 and logical change #1 happen to
> change lines very close to one another, putting them in the same hunk,
> so some small bit of #2 must be removed).  When I'm happy, I 'mtn
> commit', resulting in this graph:
> 
> A---B---C
>  `-B1

Your 'mtn split -r B' here is just 'mtn pluck -r B' (assuming we start
in a checkout of A), with a more interactive UI (which could be
provided by some front-end that wasn't specific to 'split' --
what we're doing is just an interactive 'revert').

> I then type some 'mtn split' incantation (this is the "hard" part to
> get right, as far as UI goes, I think) which provides me each hunk in,
> this time, the diff between B and B1.  Proceed as before, yielding a
> B2 containing all of logical change #2:
> 
> A---B---C
> |`-B1
> `--B2

In this case, it's just 'mtn up -r A; mtn pluck -r B1 -r B'.

> Rinse and repeat, yielding a B3:
> 
> A---B---C
> |`-B1
> `--B2
>  `-B3
> 
> At this point, B1 ∪ B2 ∪ B3 *should* look something like, if not
> identical to, B.  I should then be able to perform some related
> command which yields a graph functionally identical to:

Okay, at this point, there isn't a single pluck command you can run
to get only the changes that haven't "already been taken", because
there isn't a single parent revision you can give.  What you really
want is the merge of B1 and B2... hmm, and we wanted to merge those
anyway, eventually... so maybe we should just merge them now, and then
'mtn up -r A; mtn pluck -r <merge of B1 and B2> -r B'?


Another possible workflow for this task uses a tool that no-one has
written, but I keep saying that someone should :-).  (I think maybe
Ross Cohen did some work along this line at some point?  I forget
now.)  This tool is basically 'split' for _workspaces_ -- the idea is
that you take your workspace, and you clone it into two workspaces,
each of which has some subset of the original workspace's changes.
The originally motivating idea is to use this as a tool for when you
notice that you've made a bunch of disjoint changes -- instead of
doing awkward things with restricted commits, or saving off a patch
file and then reapplying it bit by bit, or whatever, you just hit the
button, click on the diffs that should be separated off, and get a
nice history
fork.

This tool was originally envisioned for before you commit, but it
works nicely for cleaning up an old commit as well.  The use would be
something like
  $ mtn co -r A B-split
  $ mtn pluck -r B
  $ split-tool ../B1
  <select hunks for B1, thus removing them from current workspace>
  $ split-tool ../B2
  <select hunks for B2, thus removing them from current workspace>
Now, without any special VCS support (except 'split-tool' knowing how
to ask the VCS for a diff, and how to clone a worksace), we have 3
workspaces, with disjoint subsets of the changes that were originally
in B, that we can look at, tweak, and commit at will.

If you want to be really hard-line about the DaggyFixes thing, you
could even go into each workspace and 'mtn update -r <the revision
that introduced the bug>', to commit each split-out change against a
different, perfectly chosen, parent.

There are lots of possible slick UIs for a tool like this.  One idea:
show the file being in a 2-way side-by-side view, like xxdiff.
Originally, one side is the pristine version of the file; and the
other is the version with all changes applied -- these changes show up
as highlighted difference hunks.  There is a button that swaps the
contents of two such aligned hunks.  Plus visual feedback so you can
distinguish a swapped and unswapped hunk, some sort of directory tree
view (with similar buttons so you can pick out whole files at once, or
drill down to the view I described above to select individual changes
in each file), and ideally the ability to jump into either side to
edit it (this doesn't notionally cause any difficulty -- it just
creates more differences to display in the two-way view), this would
be quite nice and reasonably straightforward.

Another idea: take emacs's diff-mode, and soup it up a bit.  The idea
would be that you start by generating a pristine tree, then make a
diff between it and your tree-with-changes, which is the diff you load
into diff-mode.  Now add a button that "inverts a hunk" -- where
whenever you invert a hunk in the view, it actually goes and applies
the inverse hunk to one side, and the forward hunk to the other, so
that the diff being displayed continues to accurately reflect the
differences between the two trees.  Throw in some visual feedback on
which hunks have been inverted, a way to jump to each tree in the
editor (diff-mode already has this, but only for one tree at a time),
and Bob's your uncle.

So, like, yeah, someone should do that.

-- Nathaniel

-- 
"On arrival in my ward I was immediately served with lunch. `This is
what you ordered yesterday.' I pointed out that I had just arrived,
only to be told: `This is what your bed ordered.'"
  -- Letter to the Editor, The Times, September 2000




reply via email to

[Prev in Thread] Current Thread [Next in Thread]