[RFC] How various commands display revisions

Vincent Ladeuil v.ladeuil+lp at free.fr
Wed Sep 17 17:18:37 BST 2008

Hi all, 

By adding an '--include-merges' option to missing, I
closed bug #233817.

Yet, there was many valuable comments in the bug report and my
fix didn't address them. I dig a bit and this is a summary of the
issues that still need to be addressed.

There are some inconsistencies/gaps between various commands when
it comes to display revisions.

In the following I simplified things by considering only branches
(things are quite similar for checkouts here) and talking about a
local branch and a remote branch (I could have used 'mine' for
local and 'other' for remote).

* log

'log' shows any revision range on a single branch.

* missing

'missing' shows the revision range missing locally and the
revision range missing remotely.

* pull -v

'pull' shows the revision range missing locally

* push -v

'push' shows the revision range missing remotely

* status

'status' shows the pending merge revisions.

* uncommit

'uncommit' shows the uncommitted revisions

All of the commands above display revisions.

Selecting what revisions to show is controlled either implicitly
or explicitly depending on the command, some selecting options
are specific to some commands:

- arbitrary revision range specified by the user (log),

- only the revisions missing locally or remotely (missing),

The revisions can then be filtered:

- only the mainline revisions (excluding the merged revisions)

- only the revisions that modify a file or a list of files

- only the revisions whose message contains a specified regexp

- only a specified number of revisions

The revisions can be displayed either in chronological or
anti-chronological order (but always in merge topological order).

When it comes to show a revision, various pieces of information
under various formats are implemented by various commands:

- line: a compact format displaying on a single line (implies
  mainline revisions only):

  * revno
  * commiter
  * date
  * first line of commit message

- short: roughly the same infos as 'line' but on several lines,

- long: the default format with each piece on its own line
  (the commit message can take several lines).

- custom: whatever the custom log formatter implements

- delta related:

  * files add/deleted/renamed/modified à la 'status'

'log' and 'missing' also provides '--show-ids' that additionally
display revids for the revision and its parents

Several inconsistencies have been raised in the
https://bugs.launchpad.net/bzr/+bug/233817 comments and I find
some more:

- the --log-format option should be available for pull, push,
  missing and uncommit,

- '--reverse' is used by missing and '--forward' by log, I find
  '--reverse' a bit obscure and would prefer --forward
  (presenting revisions "backward" (aka from newest to oldest)
  being a reasonable default). Whether or not we allow --backward
  as an alias for --no-forward may be worth it if it can be
  hidden in the Option implementation.

- 'update' doesn't show the merged revisions

- 'merge --preview' doesn't show what 'status --pending' will.

Most of these concerns can be addressed by modifying log.show_log
(log, uncommit) and log.show_changed_revisions (pull/push),
rewriting the later to use the former. 'missing' needs to be
modified to use log.show_log too. That will make the code base
more coherent.

UI wise now, except for missing now accepting a --include-merges
option, there is no option available to the user to decide if the
revisions displayed should be only the mainline ones or not and
to display the delta or not (well, sometimes -v do that).

The code itself delegates that to the LogFormatter/log_adapters
objects and log.py ends with a comment suggesting that someone at
some point had some ideas on how to provide parameters to each
factory method. Feedback welcome :)

Going back to each command now it may worth deciding if we can
find ways to add some options without having to provides all log
options to every command:

- log: the revision range is explicit, missing options: --delta
  (currently available as -v), --include-merges (implicitly tied
  to formats)

- merge[1]: the revisions range is implicit, missing options:
  --log-format, --delta, --include-merges[2], --forward, --show-ids

- missing: the revisions range is implicit, missing options:
  --forward (currently --reverse), --delta (currently available as

- pull: the revisions range is implicit, missing options:
  --log-format, --delta, --forward, --include-merges (currently on
  by default when using -v), --show-ids

- push: the revisions range is implicit, missing options:
  --log-format, --forward,--delta, --include-merges (currently on
  by default when using -v), --show-ids

- status[3]: the revision range is implicit, missing options:
  --log-format, --forward,--delta, --include-merges (-v do nothing

- uncommit: the revision range is explicit, missing options:
  --log-format, --forward (really ?), --delta (currently available
  as -v), --include-merges, --show-ids

- update: the revisions range is implicit, missing options:
  --log-format, --delta, --forward, --include-merges (currently on
  by default when using -v), --show-ids

Note that --show-ids, --delta and --include-merges can also be
seen as format attributes as long we provide the suitable formats
(or a mechanism to parameterize formats).

Also note that I'm not proposing to change the actual *default*
behaviors, but more trying to find if we need to add options
(possibly by making --log-format richer) or make verbose a bit
more progressive (-v, -vv, -vvv, etc).


[1]: I'd be prefer to leave 'merge' as it is, considering that
  'missing' is responsible for showing the revisions, but I
  included it for completeness.

[2]: Urgh, bzr merge --include-merges 8-/

[3]: For the pending merge part.

More information about the bazaar mailing list