[RFC] Trying to get something better that revno:N:branch to deal with remote revs
Matthieu Moy
Matthieu.Moy at imag.fr
Sun Aug 13 11:46:41 BST 2006
Hi,
In the past, I've brought this topic several times in this mailing
list. The basic problem is that the revision specifiers do not allow
one to deal with a remote revision. The typical problem is: take two
arbitrary remote revisions. bzrlib knows how to diff them, but up to
recently, it was not exported in the UI at all.
There are roughly 3 ways to deal with it:
1) Extend the revisionspec to deal with remote locations. That's what
I implemented allowing one to do "diff -r revno:42:http://branch.com/"
2) Extend URL to deal with revisions. There used to be a syntax for
this which has been pulled out (http://location.com/path/@3 IIRC)
3) Keep URL and revision spec distinct, and ask both to be provided on
the command line.
Indeed, I think 1) and 2) are quite the same. In both cases, the
syntax is like <URL><separator><revspec> or <revspec><separator><URL>.
Today, 1) is implemented and is in bzr.dev. I'll try to summarize the
advantages and drawbacks:
Pros:
- It keeps the revno and the URL grouped on the command line, it's
clear which URL the number refers to. In particular, it allows to
build the command line easily from a script or programm calling bzr
as an external process (I've played a bit with DVC and this too,
it's really convenient).
- The revision spec is regexp-matchable. In a natural language
sentence like "It's implemented in revno:3:http://some-site.com/", a
human and an automatic tool immediately notice that this is a remote
revision spec (in DVC, we had something about that for Arch revision
identifiers, a Gnus user would just click the
"foo at bar.com/cat--br--1.0--patch-12" to get the log and the diff).
It's also easily cut-and-past-able.
- UI similar to "branch:http://site.com/" revision specifier which is
already here.
Cons:
- It allows only revno to be specified.
* For completeness, revid should be allowed. I thought the syntax
would naturally extend to "revid:<revid>:<path>", but revid can
contain a ':'.
* For conveinience, any other revision spec should be allowed. There
should be a direct encoding of "First revision commited yesterday
in branch <foo>", or "last but one revision in <bar>" for example.
- It introduces some branch-related stuff in the revision spec (both
in the UI and in the code).
I can see two ways to try to solve this problem:
- Have a syntax to specify both /any/ revision specifier (not just
revno) and a branch URL in a single string. I like the concept, but
I didn't come up with a satisfactory syntax. Here's a brain-dump of
what I envisaged:
<revspec>(<url>):
Example: "date:yesterday(http://site.com/branch)"
Drawback: shell metacharacter.
<revspec>[URL], <revspec>{URL}, ...:
Drawback: same
<revspec>:URL
That'd be a generalization of revno:N:path
Drawback: Ambiguous, at least "revid:some:id:URL" would be
problematic.
<revspec>@URL
Same problem, @ can be in the revspec.
URL;<revspec>
This has been proposed by someone else a long time ago. I don't
remember if it was only URL;revno=N, URL;revid=id or any revision
spec like URL;date:yesterday though.
Drawback: Shell metacharacter
Ambiguous in some cases, URL can contain a ';'.
URL at revspec
Drawback: Ambiguous too. For example,
http://site.com/branch/@revid:foo@1
remote:URL:<revspec>
The idea would be a recursive revision specifier, like "before".
Drawback: Once more, ambiguous.
Well, the conclusion is that it's hard to get something easy to type
(no shell metacharacters) and unambiguous. Indeed, with branch:, there
are already ambiguities: I can have a branch whose name is
"foo..revid:bar", it's a valid directory name!
- Remove any reference to branches in revision specifiers (this means
deprecating "branch:" also. It didn't raise the same problems in the
code because it did a local fetch, but a) this local fetch is not
always necessary/possible/good and b) in the UI, the fact that it
does a local fetch should not be visible), and move to 3) above.
That's not simple to do right. For commands taking one branch, it's
trivial, just
$ bzr command [-r revspec] [branch]
We loose regexp-matchability, cut-and-past-ability and the
possibility to have a complete revision spec in a single string
(better for scripts).
But for commands taking two branches, I find
$ bzr command -r rev1..rev2 branch1 branch2
really bad from all points of view (user-friendliness and script
friendliness).
So, IMHO, this kind of syntax should come in bzr.dev only if we have
a way to group revision and branch together on the command-line.
Once more, here's a brain-dump:
--from REVSPEC BRANCH; --to REVSPEC BRANCH
Example:
$ bzr diff --from revno:12 ../otherbranch --to revid:foo ../yet-another
Multiple '-r' options, forcing the branch to come right after the
revision specifier.
Example:
$ bzr diff -r revno:12 ../otherbranch -r revid:foo ../yet-another
Drawback:
- It raises the question of whether mutliple -r should cumulate or
override each other.
- It's not that easy to implement with the current code for option
handling.
- It means -r can take either one or two arguments. Hard to give a
meaning to "bzr diff -r foo bar", since it'd depend on wether bar
is a filename or a branch.
--fully-qualified-revision REVSPEC BRANCH
with a shortcut -R REVSPEC BRANCH
Example:
$ bzr merge -R date:yesterday http://site.com/ \
-R revid:foo http://other-site.com
Drawback: Same as multiple -r above except the last.
At the moment, I'd think the last proposal is the least bad. It's not
ambiguous, it's easy to type, it provides maximal expressivity. It
could be used with -r too:
$ bzr diff -r 3 -R 4 http://remote/branch
I'm willing to spend some time on an implementation if the team agrees
on a specification.
Any comments/flames/better proposals are welcome.
--
Matthieu
More information about the bazaar
mailing list