Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

This branch was abandoned/closed because...

It turns out that trying to use -- to "escape" the - filename alias is not conventional (as i initially believed it to be). That aspect of this change accounts for the vast majority of the code, so a separate branch will be created with a much-simplified form which only provides (more or less) POSIX-conventional handling of --.

Management Summary

The double-dash-flag branch aims to add support for the conventional interpretation of a -- flag: all arguments after the first instance of -- are to be treated as non-flag arguments (e.g. file/wiki/branch/whatever names).

This feature request is from:

The implementation is not 100% compliant with POSIX/Unix conventions because it cannot be without Breaking Stuff, but it "should" be close enough to be useful/conventional for the contexts where using -- makes sense in Fossil. For example, uv add treats a filename of - as stdin by default (and has valid use cases enabled by that), and -- could be used to make uv add treat - as a filename (that's the original use case for which conventional -- support was proposed).

Compatibility vs. Historical Behaviour

Fossil's historical handling of -- is really weird: the first time find_option() encounters --, it removes that flag and stops processing arguments. Subsequent calls to find_option() then never see -- and thus treat all arguments as potential flags (even those after the prior position of --). Since that behaviour was never useful, and potentially confusing, it is unexpected that the changes made in this branch will break any historical usage of the CLI commands.

For example:

fossil foo -- -a -b -c

The current (trunk, as of this writing) interpretation of -a -b -c, because of the "one-time-swallowing" of --, depends on what order those flags are checked for via find_option(). It seems highly unlikely that anyone could have reliably depended on that, and therefore seems unlikely that this change will break anyone's scripts.

Commands which accept a filename as the value of a flag are unaffected by these changes, provided the flag comes before --:

fossil foo -R - -- -a -b -c

Would (both before and after this change) treat - as a repository file name, but this change will cause the subsequent -a -b -c flags to be interpreted as non-flags (it's then up to the foo command to deal with them).

This Implementation's Behaviour

  1. find_option() and its variants always stop looking for flags when they encounter --.
  2. verify_all_options() triggers a fatal error if -- is found in the argument list.
  3. verify_all_options2() consumes the first instance of -- and records the g.argv index where -- was found in g.argDashDashIndex, so that commands which need to can determine whether, e.g., an argument of - should be treated as an alias for stdin/stdout or as a literal filename (the latter only applies if -- precedes the - argument). The utility function get_dash_filename_arg() makes that particular use case trivial to implement.

It seems, after having migrated many of the commands, that it would be harmless/risk-free, and probably desirable, to eliminate verify_all_options2() and have verify_all_options() adopt that function's behaviour. That would make a stray -- flag at the end of a command a harmless no-op for commands which don't/can't make any special use of it, whereas it would "hide" flags (treating them as non-flags) if it's used before the end of such a command (indeed, that's its whole intention).

List of commands/subcommands extended to support --

(Alphabetized by command/subcommand name.)

  • 3-way-merge
  • add
  • annotate
  • artifact
  • branch new: you might recall Johnny Cash's song The Branch Named --Sue.
  • cat
  • changes/status
  • clean
  • clone
  • commit
  • diff/gdiff
  • extras
  • finfo
  • grep
  • ls
  • mv/rename
  • new/init
  • open
  • revert
  • rm/delete/forget
  • stash save | snapshot
  • sqlar
  • tarball
  • uv add | cat | edit | export | rm (noting that export has one pathological(?) corner case which we can't 100% accommodate: double-dashing the UVFILE name without applying double-dash to the output file name).
  • wiki commit | create | export
  • zip

The Obligatory Exceptions

  • diff -tk and stash diff -tk: diff_tk() does not use verify_all_options(), so it has historically silently ignored unknown flags. To avoid breaking existing user behaviour, it was not modified. Ideally it should be updated to call verify_all_options2().
  • stash gdiff|show|gshow|cat|gcat do not currently call verify_all_options(), but probably should.
  • search does not use verify_all_options(), instead treating all unconsumed flag arguments as a search pattern. It can easily be made to treat -- as the other commands, but doing so may break existing expectations, so that command was left unmodified.
  • tag does not use verify_all_options(), instead using strictly positional arguments, thus it supports tags with leading dashes as-is.
12 check-ins related to "double-dash-flag"
Added -- support to (3-way-merge, open, sqlar, stash save|snapshot, tarball, touch, undo/redo, update, zip). ... (Closed-Leaf check-in: 52ae3288 user: stephan tags: double-dash-flag)
Added -- support to (diff, finfo, grep, new). We can now grep for patterns which start with a dash. ... (check-in: 639b2c18 user: stephan tags: double-dash-flag)
Added -- support to (annotate, artifact, cat, clone). ... (check-in: ef763bcf user: stephan tags: double-dash-flag)
Help syntax change to match project conventions: [--] to ?--? ... (check-in: 95ed1894 user: stephan tags: double-dash-flag)
Added -- support to (changes, clean, extras, ls, commit). ... (check-in: 1b649b9d user: stephan tags: double-dash-flag)
Added -- support to (add, rm, mv). ... (check-in: 9a7101d5 user: stephan tags: double-dash-flag)
fossil add: fixed leak of ignore-glob prompt string. ... (check-in: e5e09407 user: stephan tags: trunk)
Added -- support to wiki create/commit/export. Refactored/simplified how fetching of a dash-as-stdin/stdout argument is done from command-side code. ... (check-in: dba4fd9b user: stephan tags: double-dash-flag)
Added -- support to: (branch new) (uv add/cat/edit/export/rm) ... (check-in: 78a30d8d user: stephan tags: double-dash-flag)
Simplified the verify_all_options() porting strategy, such that -- is disallowed by default and routines which should/can support it need to call verify_all_options2() instead of us changing the signature of verify_all_options(). This will result in far fewer changes than the previous approach. ... (check-in: a9b9b5bc user: stephan tags: double-dash-flag)
Initial work on unified "--" flag support, as requested in There's still lots to do here. ... (check-in: d8ebbd76 user: stephan tags: double-dash-flag)
Remove the discussion of the "close" command from the document as the "close" command is not really needed, is rarely used, and serves no purpose in the document but to confuse the reader. ... (check-in: f6e63530 user: drh tags: trunk)