Fossil Forum

RFC: fossil checkin -ui
Login

RFC: fossil checkin -ui

RFC: fossil checkin -ui

(1) By Stephan Beal (stephan) on 2024-01-19 13:53:05 [source]

A couple of days ago Richard proposed a new feature:

fossil checkin -ui [file(s)...]

It would launch a local browser with what amounts to a combination of the /info and /ci_edit pages, with at least the following major UI elements:

  • Edit field for the checkin message.
  • New branch to check in to.
  • Non-branch tag(s) to apply.
  • (Perhaps) other metadata which can be supplied via ci flags, e.g. overriding the timestamp and user name.
  • Diff of the local checkout vs its parent.
  • PREVIEW and SUBMIT buttons.

This would allow, e.g., a preview of the checkin message so that one can verify that any markup will render correctly.

The UI is not fundamentally a problem - we have all of the components somewhere in the tree. Even so, some foreseeable hurdles are being posted here to get feedback, suggestions, and/or proactive solutions for them...

  • The sync-before-checkin step and the associated "would-this-fork?" check would need to be delayed until (or performed a second time) when tapping the SUBMIT button. We do not currently have any code which runs sync/update from the web interface and certain error handling, e.g. a connection timeout, may require special handling in the UI.

  • How to deal with the output generated by update/sync is as-yet unclear. It all goes to fossil_print(), which will send its output to the CGI channel when running in server mode, so the output should not pose any fundamental problems. Any prompts generated by the sync/update process must, however, be translated to errors because we can't prompt the UI user in the middle of the sync/update output.

  • If a user has to back out of the UI, e.g. to deal with a merge conflict introduced in the sync/update step, we should save the checkin message, tags, and branch info in a temporary slot in the checkout db so that they are restored the next time "ci -ui" is run.

  • Certainly other points which a shortage of coffee is keeping me from seeing.

Your ideas for dealing with those points, as well as any additional ones you foresee, would be appreciated.

(2) By Warren Young (wyoung) on 2024-01-19 21:51:38 in reply to 1 [link] [source]

Diff of the local checkout vs its parent.

This is perhaps the most valuable addition for me. Too often I forget to diff before I commit, leading to inadvertent commits of silly changes.

preview of the checkin message so that one can verify that any markup will render correctly.

I may be the most verbose in commit messages among people I know, yet even I rarely use enough Wiki markup to lose track of how it's likely to render.

I say this less to undercut any enthusiasm on developing the feature than to support this observation: the tabbed Editor/Preview UI of the /*edit pages might not be appropriate here. Something more like Stack Exchange's live preview might work better given that the 99th percentile of commit messages is likely to require a few lines lines of fixed-width text editor space at most, rendering to less than that in the proportional-font preview format.

The space required for that will push the diff down, but the feedback of seeing the effect of what you type appearing in real-time will ensure the preview is heeded more often than if you have to remember to hit Shift-Enter before committing.

(Witness the number of badly-formatted /chat messages if you doubt this.)

sync-before-checkin step…delayed

This is mostly done already in the handling of $EDITOR. The browser launch fits into the same hole.

Fossil syncs before the commit to check for inadvertent forks when in autosync mode, and after the commit message is saved, it does another check of the local files against the local repo to make sure they haven't changed before computing the diff and shoving it into the hash tree.

For a consistent mental model, the browser-as-$EDITOR should behave as close to the same way as possible.

Speaking of, I'd like a mode where you can tell Fossil to do this all the time, not just when you pass a --ui flag. Let us not suddenly come down with the Gitness and require flags on every commit.

Any prompts generated by the sync/update process must, however, be translated to errors because we can't prompt the UI user in the middle of the sync/update output.

Is this a good excuse to do the long-desired JSON rework in terms of SQLite's built-in JSON processing? If you had a JSON API to do all this over, it would have multiple side benefits, such as the ability to script commits via shell scripts in a more reliable way.

PUT /api/commit → { "success": true } style of thing, yes?

(3) By Stephan Beal (stephan) on 2024-01-19 23:06:06 in reply to 2 [link] [source]

I say this less to undercut any enthusiasm on developing the feature than to support this observation: the tabbed Editor/Preview UI of the /*edit pages might not be appropriate here.

i was thinking along the lines of /ci_edit - a dumb POSTable form element with a preview button and the diff view below the editor fields. Nothing fancy (though i wouldn't object to fancy if someone else wants to implement it that way ;).

Sidebar: we have the little checkboxes for toggling files in the diff view on and off, and maybe those could be used here to (de)select which files should be included in the checkin.

For a consistent mental model, the browser-as-$EDITOR should behave as close to the same way as possible.

That's a great insight. It wouldn't have occurred to me because i literally never use $EDITOR with fossil and only write checkin messages using -m "...".

Is this a good excuse to do the long-desired JSON rework in terms of SQLite's built-in JSON processing?

Doing the update/sync via an internal-use JSON API has crossed my mind. i hadn't quite taken the idea as far along as an opportunity to re-do the JSON pieces because it would be far more work than i will be able to commit to in any near-term future, but i would certainly like to see that done.

(4) By Warren Young (wyoung) on 2024-01-20 00:05:48 in reply to 3 [link] [source]

The major difference with $EDITOR is that this will be asynchronous, much like server mode, not blocking on the system() call. Thus my idea of using REST calls to coordinate the JS and C halves.

(5) By Thomas Hess (luziferius) on 2024-01-20 10:08:59 in reply to 1 [link] [source]

  • If a user has to back out of the UI, e.g. to deal with a merge conflict introduced in the sync/update step, we should save the checkin message, tags, and branch info in a temporary slot in the checkout db so that they are restored the next time "ci -ui" is run.

(I tend to jump to obscure hypotheticals, so bear with me a bit)

After cancelling a ci --ui, should a successful, plain ci clear any of the temporarily stored data?

There are pros and cons, based on hypothetical scenarios, where either "yes" or "no" is more beneficial:

Pro

  • I assume that a successful ci after an aborted ci --ui will likely be on the same dataset and thus invalidate the stored data or make it stale.
    • When using the --ui flag only sporadically (for example for checkin message formatting), I can envision that this scenario becomes more likely.

Con

  • The conflict that caused cancelling might warrant a separate, clean-up ci with a different checkin message. Then the original should be retained.
  • Assuming somewhat erratic behavior, doing fossil ci --ui, cancelling due to some issue, then running the sequence fossil stash save, fossil update <some other branch>, <do some work>, fossil ci, fossil update <original branch, fossil stash pop, fossil ci --ui. This flow will then (unexpectedly?) drop the stored data, because of an unrelated ci on a different branch.

Since I cannot determine which is more likely to occur, maybe add a "Reset" button that simply resets everything? Or simply ignore it completely, since the potential amount of work re-doing all stale data by hand is sufficiently small that the UI populated with it doesn't pose much of a hurdle?

(6.1) By spindrift on 2024-01-20 10:50:50 edited from 6.0 in reply to 5 [link] [source]

Storing the most recent, but uncommitted, state in the browser local store is pretty easy, and could be offered as a "retrieve last session" button to repopulate all the relevant fields.

It wouldn't sync with the repository or different users or browsers, which would be expected behaviour I believe, and neither would it interfere with the command line functions.

To be clear - the webpage would always open unpopulated but would have a option (which would need to be a small JavaScript function) to retrieve state data if it persisted from an uncommitted session.

This would be stored with a beforeunload handler, for example (if the window hadn't been closed, the state would still exist in the page of course).

(7) By spindrift on 2024-01-20 10:52:27 in reply to 6.1 [link] [source]

In fact, this does also imply some need to synchronise the webpage with changes to the repository that occur after the webpage is first loaded.

(8) By Stephan Beal (stephan) on 2024-01-20 13:38:09 in reply to 6.1 [link] [source]

Storing the most recent, but uncommitted, state in the browser local store is pretty easy, and could be offered as a "retrieve last session" button to repopulate all the relevant fields.

My initial thinking was that we would store the ci state in the config table, keyed to the current ci version so that it does not pollute later checkins, but storing it in the browser's localStorage is even better.

To be clear - the webpage would always open unpopulated but would have a option (which would need to be a small JavaScript function) to retrieve state data if it persisted from an uncommitted session.

If the data exists in localStorage, it could be used as-is, but would be cleared upon a successful SUBMIT. Perhaps there would need to be a button to clear/reset it as well (which only shows up if the (ci -ui) actually sees localStorage data when it starts up).

(9.1) By Stephan Beal (stephan) on 2024-01-20 13:46:59 edited from 9.0 in reply to 5 [link] [source]

Assuming somewhat erratic behavior, doing fossil ci --ui, cancelling due to some issue, then running the sequence fossil stash save, ...

Those are very real possibilities and mimic my own tendency of...

... ready to check in ...
f diff -tk
... make local edits ...
f diff -tk
... repeat any number of times ...
f ci -m ...

The ci -ui feature would need to be able to cope with that, probably via adding a Refresh button which updates the diff view. We can't use a browser's Ctrl-R/F5 reload because tapping the PREVIEW button will1 perform a POST request (to render the ci message) and a browser will warn when trying to reload a POST-requested page.

This flow will then (unexpectedly?) drop the stored data, because of an unrelated ci on a different branch.

If we store the ci state in localStorage, as spendrift proposed, that problem seems to go away. It would give us a single central buffer for the ci info which we can clear when a ci is submitted or explicitly cancelled, but is otherwise persistent. We could alternately keep that stored data on per-current-branch basis, with the caveat that we could end up with storing a small amount of stale state for any length of time.


  1. ^ "will" = will hypothetically, based solely on current thinking and subject to change.

(10) By ronw on 2024-01-21 19:46:35 in reply to 5 [link] [source]

Just an observation from use of other tools, in this case, TortoiseGit, which is used by my employer.

TortoiseGit (and TortoiseSVN) have "Recent Log Messages", which lists the most recent several (don't recall how many) log messages entered, allowing selection.

My coworkers and I frequently use this feature, then edit the recalled message as needed.

So I have no doubt that some kind of recall feature would be appreciated and used. Multiple recall would be even more appreciated.