[qbzr/bzr-gtk] Save commit message and other metadata when commit GUI dialog is cancelled or in uncommit hook
Alexander Belchenko
bialix at ukr.net
Sat Jun 13 19:23:15 BST 2009
I send the copy of my thoughts to main bzr list because Vincent pointed me that this topic could be
interested not only for qbzr. I'm trying to explain how I'd like to implement it for qbzr, so maybe
my approach will be interesting for bzr-gtk, and in far far future will be move it in the core (who
knows?).
Background
----------
When user trying to commit from command-line and commit fails because of some blockers it's possible
to remove blockers and then invoke the same commit again using shell history. Therefore user can
reuse commit parameters such as commit message, --fixes, --author. When user working with GUI commit
dialogs these data should be saved by GUI itself, otherwise user will have to enter these data again
by hands.
When user uncommit it's may be because he/she want to improve either the code committed or committed
message of other metadata. VCS don't know intent of the user so it make sense to save messages and
other metadata in uncommit hook and then reuse it on subsequent commit. The data should be saved in
similar way as for ordinal commit in GUI, so commit dialog will use any saved data.
Command-line bzr can save and reuse uncommitted revisions too, but there is no UI for this right
now. If there will be UI to reuse saved data, then command-line bzr users even can rely on saved
data when previous commit fails.
So, discussed approach is more interesting for GUI tools, but because some users have installed both
qbzr and bzr-gtk in the same time then there will be big overlap in implementation and duplication
in uncommit hooks. So maybe it make sense to have this code actually in bzr core, including uncommit
hook.
Existing implementations
------------------------
bzr-gtk
*******
Stores commit message in branch.conf as gtk_global_commit_message and gtk_file_commit_messages
variables. The former used for usual commit messages, the latter used for per-file commit messages
(used by MySQL team only AFAIK). Global commit message saved as string, per-file commit messages
saved as bencoded dict of messages.
When there is uncommitted more than 1 revision messages of all uncommitted revisions joined as one
big text with '***********' as separator between chunks.
qbzr
****
Stores commit message in branch.conf as qbzr_commit_message variable. Message saved as string.
Uncommit hook saves only message for the old tip revision, if there is uncommitted more than 1
revisions all other messages are lost.
As one could see both GUI tools used similar approach, but bzr-gtk also supports per-file messages.
QBzr don't have support for them mostly because there is no documentation on this feature, and
de-facto bzr-gtk is the only one tool that supports them and therefore should be used as reference
implementation. I'd like to hear how support of per-file messages actually works in viz and
gannotate, if this possible.
Both tools does not save --fixes or --author metadata today, but qbzr want to implement support for
--fixes (at least) so corresponding discussion have started in qbzr ML and and this e-mail is the
result of this discussion.
Problems or is there possible to have ideal solution?
-----------------------------------------------------
Although both tools using similar approaches but there is several problems in each implementation.
When user uncommit several revisions it's not clear what is user intent. Should we save all messages
or only latest one? There is no simple answer because it depends on context.
QBzr users want to have more data saved, e.g. ids of fixed bugs. This is really should be handy.
Thinking further we need to save --author option as well, although it used very rare.
bzr-gtk does not have support in gcommit for --fixes and --author AFAIK, but maybe one day will have.
Saving different data as multiple variables in branch.conf leads to non-atomic behavior, even more
manipulating with branch.conf requires branch locking, so operation of saving the data should be
atomic and implemented as single shot.
Therefore it's make sense to use bencoded dict to save many different data in one variable: global
message, per-file messages dict, fixed bugs, authors.
Using branch.conf is only one existing option in bzr core today, but if one starts thinking about
lightweight checkouts then it becomes obvious that saved commit metadata should be saved in the
checkout itself, not in master branch, especially because it could be remote and even more read-only
location.
So, I think there should be new config for tree object, e.g. as .bzr/checkout/tree.conf file.
And saved commit metadata should live there.
Plans for new QBzr implementation
---------------------------------
To have easily extendable solution and to address lightweight checkouts problem I think we need to
implement for QBzr following:
1) Save the data in tree.conf as commit_data variable
2) Save the data as bencoded dict, with keys/values as following: message (list of texts),
per-file-message (also dict, values should be lists of texts), fixes (list of ids), authors (list of
names). If some tool does not understand some metadata it will ignore them.
3) For messages should be used lists of strings, so we can support uncommit of several revisions, if
qbzr will wish this in the future.
Of course this approach may have some weakness, but it's the best I have in mind today taking into
account all problems listed above.
So, I'm planning to implement in near future support for qbzr as described above.
If bzr-gtk developers think this approach could be interested for their tool, we can discuss how to
share the code. If other parties interesting to talk about different variants or knows another
problems I've not listed there, I'm open for constructive discussion.
But in the end I'm planning to implement described above as good enough support for qbzr, even if it
will be no ideal solution for everyone.
Alexander.
More information about the bazaar
mailing list