[Outreachy] Proposal draft v1: Improve how command arguments and options are scanned and parsed

Started by Cynthia Uche on Nov 1, 2026 · 7 messages from 3 authors · Last reply Nov 8, 2026

open the first message on its own page

Message details and related content
Hi team,

This is the first draft of my proposal for "Improve how command
arguments and options are scanned and parsed" for the December 2026
Outreachy round. I would appreciate feedback, especially on the
candidate inventory (section 4) and the timeline (section 5).

1. About me and logistics
-------------------------
Name:     Cynthia Uche. I'm also called Priestess.
Pronouns: she/her
Email:    herroyalpriestess@gmail.com
GitHub:   https://github.com/herrpriestess
Blog:     https://medium.com/@thegirlSynth
Location: Abia, Nigeria (WAT, UTC+1)

I have read the Outreachy eligibility rules and I meet all the
requirements.

I am a software engineer, mostly working on Python and backend
projects. C was the first language I learned, so I am comfortable
reading and writing it, although I have not used it much day to day
until now.

I have a merged patch in OpenStack Shared File Systems Service (Manila)
(https://review.opendev.org/c/openstack/manila/+/982431), which went
through Gerrit review, so reworking a change after review comments
is not new to me.

Availability: 30 hours per week

2. My Git work
--------------
Microproject: t2104: avoid suppressing git's exit code
  Thread: https://lore.kernel.org/git/20261021033723.5265-1-herroyalpriestess@gmail.com/
  Topic:  cu/t2104-avoid-pipes
  Status: merged to master (merge commit 84bea4324a)
  Patrick reviewed it and found it good, so it needed no second
  version.

316 more lines

[Outreachy] Proposal draft v2: Improve how command arguments and options are scanned and parsed

Message details and related content
Hi team,

This is the second draft of my proposal for "Improve how command
arguments and options are scanned and parsed" for the December 2026
Outreachy round. v1 is here: [11]. I would appreciate
feedback, especially on the candidate inventory (section 4) and the
timeline (section 5).

Changes since v1
================
 - Section 2: Christian replied to my review of 4/4 and v4 of the
   early-scan series includes my suggestion; I also added my other
   two reviews.
 - Sections 3.2 to 3.5: v4 of the early-scan series and where it
   stands now.
 - Section 4: Fien Dora's t1402 tests are in 'next'; the status of
   rerere; the build the observations were made on.
 - Steps I have taken: updated.
 - About me: updated.
 - Communication: updated.

1. About me and logistics
-------------------------
Name:     Cynthia Uche. I'm also called Priestess.
Pronouns: she/her
Email:    herroyalpriestess@gmail.com
IRC:      Priestess
GitHub:   https://github.com/herr-priestess
Blog:     https://herr-priestess.github.io/
LinkedIn: https://linkedin.com/in/thecynthiauche
Location: Nigeria (WAT, UTC+1)

I have read the Outreachy eligibility rules and I meet all the
requirements.

I am a software engineer, mostly working on Python and backend
projects. C was the first language I learned, so I am comfortable
reading and writing it, although I have not used it much day to day
until now.

411 more lines

Re: [Outreachy] Proposal draft v2: Improve how command arguments and options are scanned and parsed

Message details and related content
Hi Cynthia,

On Wed, Nov 4, 2026 at 3:53 AM Cynthia Uche [off-list ref] wrote:
Hi team,

This is the second draft of my proposal for "Improve how command
arguments and options are scanned and parsed" for the December 2026
Outreachy round. v1 is here: [11]. I would appreciate
feedback, especially on the candidate inventory (section 4) and the
timeline (section 5).
Thank you for your interest in Git and this project.

[...]
Why not make parse_options() do a dry run? Because it would be a much
larger refactoring. According to the 3/4 commit message, a dry run
would have to avoid writing through opt->value, calling callbacks,
dying on invalid values, handling --help and tracking command mode
conflicts. Junio has said he would prefer this in the long term [2].
The scan is simpler, and it keeps the option array and the
PARSE_OPT_EARLY marks, so it does not block a dry run later.
Yeah, improving the early scan can result in refactorings like the one
in patch 2/4, which could make it easier to implement a dry run in
parse_options().

[...]
Why bisect and rev-parse were dropped: Junio said he saw little
practical value in them, since he doubted users would name a bisect
term or a --default value "--", unlike fast-import, where the bug
affects a safety check. Christian removed both patches in v2 and said
that bisect_start() could use the early scan once it has been converted
to parse-options [2], [3].
In https://lore.kernel.org/git/xmqqmrt7c1zf.fsf@gitster.g/ Junio also
said detection of "--" could eventually come for free as a side effect
of using parse_options(). So not sure an early scan will be needed at
all.

[...]
 - git column (builtin/column.c, cmd_column())
   It already uses parse_options(). Only the early step is by hand:
   if argv[1] starts with "--command=", config is read with that
   name before parse_options() runs, and a die() follows if the
   parsed and scanned values differ. Observed:
     git column --command=foo               works (exit 0)
     git column --command foo               dies (exit 128)
     git column --width=40 --command=foo    dies (exit 128)
     git column --com=foo                   dies (exit 128)
   The three failures all print "fatal: --command must be the
   first argument", even when "--command foo" really is first. I found
   this rule only in the die() message: searching Documentation/ and
   t/ for "must be the first" finds nothing related, and t9002 does not
   test --command.
   Fits: replacing the scan with early_scan_options() and
   PARSE_OPT_EARLY on --command, once the series is in next. I have not
   yet checked whether any option in column's table would
   make the scan stop.
   Risk: user-visible change (errors become success). Question for
   the list: is the "must be first" rule intentional? The callback
   receives pos, so it could be kept (pos == 0) or dropped.
`git column` is "used internally by other git commands to format
output into columns", but `git tag`, the only internal user, doesn't
use `--command`. So I guess not much effort has been made to make it
user friendly (which include allowing --command to not be first and
allowing `--command foo`) because it's not supposed to be used a lot,
nor by regular users.

The "must be first" rule also looks deliberate rather than an
oversight. "builtin/column.c" has the comment "This one is special and
must be the first one" above the scan.
 - bisect (builtin/bisect.c)
   bisect_start() has two hand-written loops: one looks for "--"
   (the bug of the dropped v1 patch) and one parses --no-checkout,
   --first-parent, --reset-when-found[=...] and the four --term-*
   options, each in a "--opt value" and a "--opt=value" branch.
   bisect_run() checks only argv[0] for --reset-when-found, and
   bisect_terms() compares one string with --term-good/old/bad/new.
   Fits: convert to parse-options first, order: bisect_terms(),
   bisect_run(), then bisect_start() as a stretch.
   Risk: bisect_start() is called from "bisect start", from
   bisect_autostart() and from "bisect replay"; the original
   arguments are written to BISECT_LOG and replayed, so they must be
   kept. Abbreviations and "--no-" forms would start to be accepted.
It looks like bisect already uses parse_options() but only to dispatch
sub-commands (OPT_SUBCOMMAND() with PARSE_OPT_SUBCOMMAND_OPTIONAL).
The sub-command functions indeed don't call it
 - check-ref-format (builtin/check-ref-format.c)
   One loop over leading dash arguments handles --normalize/--print,
   --allow-onelevel, --no-allow-onelevel and --refspec-pattern;
   --branch is special-cased as exactly argc == 3; anything else
   calls usage(). git.c lists it as NO_PARSEOPT.
   Tests: t1402 covers --normalize, --allow-onelevel and
   --refspec-pattern, alone and combined, and --branch (also from
   outside a repository, and with the name -nain). It does not test
   --print, abbreviations or "--". Fien Dora's patch adding tests for
   the precedence of --allow-onelevel and --no-allow-onelevel [10]
   was merged to 'next' on 1 Nov and is marked "Will merge to
   'master'" in What's cooking #01 [6b]. Her commit message says she
   plans to explore converting this parser in a separate series [10].
   Observed on origin/master (v2.56.0-307-g50fe5cc63f):
     --norm refs/heads/x           usage text, exit=129
     -- refs/heads/x               usage text, exit=129
     --normalize -- refs/heads/x   usage text, exit=129
     refs/heads/x --normalize      usage text, exit=129
     --branch -nain                "fatal: '-nain' is not a valid
                                   branch name", exit=128
   Fits: parse-options: OPT_BIT for the flags (--no-allow-onelevel
   then comes for free), OPT_ALIAS for --print, and dropping
   NO_PARSEOPT in git.c.
   Risks: commands that fail today would succeed: abbreviations, "--"
   and negated forms such as --no-normalize would be accepted, and
   so would options after <refname> unless I pass
   PARSE_OPT_STOP_AT_NON_OPTION. --branch needs an explicit check
   that it is not combined with other options, and "--branch -nain"
   must keep failing with the invalid branch name error (exit 128),
   not become a usage error from short option parsing.
   Question for the list: is accepting "--" and abbreviations
   welcome, should options after <refname> keep being rejected?
I haven't taken a look at this, but I saw that Hussain Sitamouwala
sent "check-ref-format: use parse-options API" patches.

Thanks.

Re: [Outreachy] Proposal draft v2: Improve how command

Message details and related content
Hi Christian,

Thank you for going through the candidates one by one. Here is what
I will change in v3 and what I plan to keep.
In https://lore.kernel.org/git/xmqqmrt7c1zf.fsf@gitster.g/ Junio also
said detection of "--" could eventually come for free as a side effect
of using parse_options(). So not sure an early scan will be needed at
all.
Thanks for the link. My [3] cites your answer in that thread but not
Junio's follow-up to it. I will add it, and I will change the sentence
in 3.4 so that it no longer says bisect_start() would use the early
scan. Whether it is needed at all becomes part of the question for
bisect.
Yeah, improving the early scan can result in refactorings like the one
in patch 2/4, which could make it easier to implement a dry run in
parse_options().
Noted, nothing to change there.
The "must be first" rule also looks deliberate rather than an
oversight. "builtin/column.c" has the comment "This one is special and
must be the first one" above the scan.
That answers the question I planned to ask the list. I had only
searched Documentation/ and t/ for the rule, so I missed the comment in
column.c. In v3 I will cite it and remove the question. Since git tag,
the only internal user, doesn't use --command, I will take column out
of my targets and keep my four runs as a note.
It looks like bisect already uses parse_options() but only to dispatch
sub-commands (OPT_SUBCOMMAND() with PARSE_OPT_SUBCOMMAND_OPTIONAL).
The sub-command functions indeed don't call it
That matches what I see in cmd_bisect(). I will describe it that way:
the dispatcher uses parse_options(), and bisect_start(), bisect_run()
and bisect_terms() parse their own arguments by hand. A conversion
would give each of them its own parse_options() call, one at a time.
I haven't taken a look at this, but I saw that Hussain Sitamouwala
sent "check-ref-format: use parse-options API" patches.
I had not seen them. I have now read v1, Junio's review and v2. The
points that v2's commit message addresses (abbreviations such as
--norm, "--" before <refname>, options after <refname> still rejected)
are among the risks I listed for this command, so I will not start a
parallel conversion. I will leave check-ref-format to Hussain and the
reviewers, and keep my observations from master in section 4 as a
reference. If useful, I can test his next version against the cases I
observed on master and report the results in his thread.

For v3, unless you prefer something else, my plan is: the bisect
sub-commands as my main target, starting with tests for their current
behaviour, then bisect_terms() and bisect_run(), and bisect_start()
after that. If that turns out smaller than expected, I would go back
to the inventory in section 4 and pick the next candidate with the
mentors, after checking that nobody else is working on it. Is bisect
the right main target, or is there a command you would rather see
converted?

Thanks,
Cynthia

[Outreachy] Proposal draft v3: Improve how command arguments and options are scanned and parsed

Message details and related content
Hi team,

This is the third draft of my proposal for "Improve how command
arguments and options are scanned and parsed" for the December 2026
Outreachy round. v1 and v2 are here: [11]. I would appreciate
feedback, especially on the candidate inventory (section 4) and the
timeline (section 5).

Changes since v2
================
 - A short summary at the top and a new "How I work" section.
 - Section 1: updated, including how I have been preparing.
 - Section 2: the outcomes of my reviews so far (including
   Shashank's v3), my review of Karthik's patch and a doc fix.
 - Sections 3.4 to 3.6: v4 of the early-scan series, and a
   corrected account of what needs a decision in a conversion.
 - Sections 4 and 5: updated after Christian's review of v2 [18].
   column is deliberate and is no longer a target, check-ref-format
   is already being converted, and bisect is described correctly and
   becomes the main target.

In short
--------
Some commands read a few options before parse_options() runs, and the
two can disagree: fast-import's hand-written scan could allow unsafe
features on a command line that parse_options() reads differently.
Christian's early-scan series fixes that, and this project extends the
same idea to the other places that parse arguments by hand. When I
counted on origin/master, 29 entries of the command table in git.c
were still marked NO_PARSEOPT. I would start with the sub-commands of
git bisect: cmd_bisect() uses parse_options() only to dispatch them,
and bisect_start(), bisect_run() and bisect_terms() parse their
arguments by hand. I studied other candidates too; column turned out
to be deliberate and check-ref-format is already being converted, so
section 4 explains why I left them. So far: a merged microproject,
four reviews and a doc fix.


1. About me and logistics
-------------------------

523 more lines

Keyboard shortcuts
hback out one level
jnext message in thread / next series-diff position
kprevious message in thread / previous series-diff position
ldrill in
Escclose help / fold thread tree
?toggle this help