Commit Graph

79006 Commits

Author SHA1 Message Date
Junio C Hamano
1da2a42c78 Merge branch 'ps/object-read-stream' into jc/object-read-stream-fix
* ps/object-read-stream: (32 commits)
  streaming: drop redundant type and size pointers
  streaming: move into object database subsystem
  streaming: refactor interface to be object-database-centric
  streaming: move logic to read packed objects streams into backend
  streaming: move logic to read loose objects streams into backend
  streaming: make the `odb_read_stream` definition public
  streaming: get rid of `the_repository`
  streaming: rely on object sources to create object stream
  packfile: introduce function to read object info from a store
  streaming: move zlib stream into backends
  streaming: create structure for filtered object streams
  streaming: create structure for packed object streams
  streaming: create structure for loose object streams
  streaming: create structure for in-core object streams
  streaming: allocate stream inside the backend-specific logic
  streaming: explicitly pass packfile info when streaming a packed object
  streaming: propagate final object type via the stream
  streaming: drop the `open()` callback function
  streaming: rename `git_istream` into `odb_read_stream`
  object-file: refactor writing objects via a stream
  ...
2025-12-18 12:21:21 +09:00
Patrick Steinhardt
7b94028652 streaming: drop redundant type and size pointers
In the preceding commits we have turned `struct odb_read_stream` into a
publicly visible structure. Furthermore, this structure now contains the
type and size of the object that we are about to stream. Consequently,
the out-pointers that we used before to propagate the type and size of
the streamed object are now somewhat redundant with the data contained
in the structure itself.

Drop these out-pointers and adapt callers accordingly.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-11-23 12:56:46 -08:00
Patrick Steinhardt
1599b68d5e streaming: move into object database subsystem
The "streaming" terminology is somewhat generic, so it may not be
immediately obvious that "streaming.{c,h}" is specific to the object
database. Rectify this by moving it into the "odb/" directory so that it
can be immediately attributed to the object subsystem.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-11-23 12:56:46 -08:00
Patrick Steinhardt
378ec56beb streaming: refactor interface to be object-database-centric
Refactor the streaming interface to be centered around object databases
instead of centered around the repository. Rename the functions
accordingly.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-11-23 12:56:45 -08:00
Patrick Steinhardt
8c1b84bc97 streaming: move logic to read packed objects streams into backend
Move the logic to read packed object streams into the respective
subsystem.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-11-23 12:56:45 -08:00
Patrick Steinhardt
bc30a2f5df streaming: move logic to read loose objects streams into backend
Move the logic to read loose object streams into the respective
subsystem. This allows us to make a couple of function declarations
private.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-11-23 12:56:45 -08:00
Patrick Steinhardt
ffc9a34485 streaming: make the odb_read_stream definition public
Subsequent commits will move the backend-specific logic of setting up an
object read stream into the specific subsystems. As the backends are now
the ones that are responsible for allocating the stream they'll need to
have the stream definition available to them.

Make the stream definition public to prepare for this.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-11-23 12:56:45 -08:00
Patrick Steinhardt
c26da3446e streaming: get rid of the_repository
Subsequent commits will move the backend-specific logic of object
streaming into their respective subsystems. These subsystems have gotten
rid of `the_repository` already, but we still use it in two locations in
the streaming subsystem.

Prepare for the move by fixing those two cases. Converting the logic in
`open_istream_pack_non_delta()` is trivial as we already got the object
database as input.

But for `stream_blob_to_fd()` we have to add a new parameter to make it
accessible. So, as we already have to adjust all callers anyway, rename
the function to `odb_stream_blob_to_fd()` to indicate it's part of the
object subsystem.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-11-23 12:56:45 -08:00
Patrick Steinhardt
4c89d31494 streaming: rely on object sources to create object stream
When creating an object stream we first look up the object info and, if
it's present, we call into the respective backend that contains the
object to create a new stream for it.

This has the consequence that, for loose object source, we basically
iterate through the object sources twice: we first discover that the
file exists as a loose object in the first place by iterating through
all sources. And, once we have discovered it, we again walk through all
sources to try and map the object. The same issue will eventually also
surface once the packfile store becomes per-object-source.

Furthermore, it feels rather pointless to first look up the object only
to then try and read it.

Refactor the logic to be centered around sources instead. Instead of
first reading the object, we immediately ask the source to create the
object stream for us. If the object exists we get stream, otherwise
we'll try the next source.

Like this we only have to iterate through sources once. But even more
importantly, this change also helps us to make the whole logic
pluggable. The object read stream subsystem does not need to be aware of
the different source backends anymore, but eventually it'll only have to
call the source's callback function.

Note that at the current point in time we aren't fully there yet:

  - The packfile store still sits on the object database level and is
    thus agnostic of the sources.

  - We still have to call into both the packfile store and the loose
    object source.

But both of these issues will soon be addressed.

This refactoring results in a slight change to semantics: previously, it
was `odb_read_object_info_extended()` that picked the source for us, and
it would have favored packed (non-deltified) objects over loose objects.
And while we still favor packed over loose objects for a single source
with the new logic, we'll now favor a loose object from an earlier
source over a packed object from a later source.

Ultimately this shouldn't matter though: the stream doesn't indicate to
the caller which source it is from and whether it was created from a
packed or loose object, so such details are opaque to the caller. And
other than that we should be able to assume that two objects with the
same object ID should refer to the same content, so the streamed data
would be the same, too.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-11-23 12:56:45 -08:00
Patrick Steinhardt
385e18810f packfile: introduce function to read object info from a store
Extract the logic to read object info for a packed object from
`do_oid_object_into_extended()` into a standalone function that operates
on the packfile store. This function will be used in a subsequent
commit.

Note that this change allows us to make `find_pack_entry()` an internal
implementation detail. As a consequence though we have to move around
`packfile_store_freshen_object()` so that it is defined after that
function.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-11-23 12:56:45 -08:00
Patrick Steinhardt
eb5abbb4e6 streaming: move zlib stream into backends
While all backend-specific data is now contained in a backend-specific
structure, we still share the zlib stream across the loose and packed
objects.

Refactor the code and move it into the specific structures so that we
fully detangle the different backends from one another.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-11-23 12:56:45 -08:00
Patrick Steinhardt
1154b2d2e5 streaming: create structure for filtered object streams
As explained in a preceding commit, we want to get rid of the union of
stream-type specific data in `struct odb_read_stream`. Create a new
structure for filtered object streams to move towards this design.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-11-23 12:56:45 -08:00
Patrick Steinhardt
5f0d8d2e8d streaming: create structure for packed object streams
As explained in a preceding commit, we want to get rid of the union of
stream-type specific data in `struct odb_read_stream`. Create a new
structure for packed object streams to move towards this design.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-11-23 12:56:45 -08:00
Patrick Steinhardt
b7774c0f0d streaming: create structure for loose object streams
As explained in a preceding commit, we want to get rid of the union of
stream-type specific data in `struct odb_read_stream`. Create a new
structure for loose object streams to move towards this design.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-11-23 12:56:45 -08:00
Patrick Steinhardt
e030d0aeb5 streaming: create structure for in-core object streams
As explained in a preceding commit, we want to get rid of the union of
stream-type specific data in `struct odb_read_stream`. Create a new
structure for in-core object streams to move towards this design.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-11-23 12:56:44 -08:00
Patrick Steinhardt
595296e124 streaming: allocate stream inside the backend-specific logic
When creating a new stream we first allocate it and then call into
backend-specific logic to populate the stream. This design requires that
the stream itself contains a `union` with backend-specific members that
then ultimately get populated by the backend-specific logic.

This works, but it's awkward in the context of pluggable object
databases. Each backend will need its own member in that union, and as
the structure itself is completely opaque (it's only defined in
"streaming.c") it also has the consequence that we must have the logic
that is specific to backends in "streaming.c".

Ideally though, the infrastructure would be reversed: we have a generic
`struct odb_read_stream` and some helper functions in "streaming.c",
whereas the backend-specific logic sits in the backend's subsystem
itself.

This can be realized by using a design that is similar to how we handle
reference databases: instead of having a union of members, we instead
have backend-specific structures with a `struct odb_read_stream base`
as its first member. The backends would thus hand out the pointer to the
base, but internally they know to cast back to the backend-specific
type.

This means though that we need to allocate different structures
depending on the backend. To prepare for this, move allocation of the
structure into the backend-specific functions that open a new stream.
Subsequent commits will then create those new backend-specific structs.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-11-23 12:56:44 -08:00
Patrick Steinhardt
3c7722dd4d streaming: explicitly pass packfile info when streaming a packed object
When streaming a packed object we first populate the stream with
information about the pack that contains the object before calling
`open_istream_pack_non_delta()`. This is done because we have already
looked up both the pack and the object's offset, so it would be a waste
of time to look up this information again.

But the way this is done makes for a somewhat awkward calling interface,
as the caller now needs to be aware of how exactly the function itself
behaves.

Refactor the code so that we instead explicitly pass the packfile info
into `open_istream_pack_non_delta()`. This makes the calling convention
explicit, but more importantly this allows us to refactor the function
so that it becomes its responsibility to allocate the stream itself in a
subsequent patch.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-11-23 12:56:44 -08:00
Patrick Steinhardt
3f64deabdf streaming: propagate final object type via the stream
When opening the read stream for a specific object the caller is also
expected to pass in a pointer to the object type. This type is passed
down via multiple levels and will eventually be populated with the type
of the looked-up object.

The way we propagate down the pointer though is somewhat non-obvious.
While `istream_source()` still expects the pointer and looks it up via
`odb_read_object_info_extended()`, we also pass it down even further
into the format-specific callbacks that perform another lookup. This is
quite confusing overall.

Refactor the code so that the responsibility to populate the object type
rests solely with the format-specific callbacks. This will allow us to
drop the call to `odb_read_object_info_extended()` in `istream_source()`
entirely in a subsequent patch.

Furthermore, instead of propagating the type via an in-pointer, we now
propagate the type via a new field in the object stream. It already has
a `size` field, so it's only natural to have a second field that
contains the object type.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-11-23 12:56:44 -08:00
Patrick Steinhardt
70c8b5f545 streaming: drop the open() callback function
When creating a read stream we first populate the structure with the
open callback function and then subsequently call the function. This
layout is somewhat weird though:

  - The structure needs to be allocated and partially populated with the
    open function before we can properly initialize it.

  - We only ever call the `open()` callback function right after having
    populated the `struct odb_read_stream::open` member, and it's never
    called thereafter again. So it is somewhat pointless to store the
    callback in the first place.

Especially the first point creates a problem for us. In subsequent
commits we'll want to fully move construction of the read source into
the respective object sources. E.g., the loose object source will be the
one that is responsible for creating the structure. But this creates a
problem: if we first need to create the structure so that we can call
the source-specific callback we cannot fully handle creation of the
structure in the source itself.

We could of course work around that and have the loose object source
create the structure and populate its `open()` callback, only. But
this doesn't really buy us anything due to the second bullet point
above.

Instead, drop the callback entirely and refactor `istream_source()` so
that we open the streams immediately. This unblocks a subsequent step,
where we'll also start to allocate the structure in the source-specific
logic.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-11-23 12:56:44 -08:00
Patrick Steinhardt
6bdda3a3b0 streaming: rename git_istream into odb_read_stream
In the following patches we are about to make the `git_istream` more
generic so that it becomes fully controlled by the specific object
source that wants to create it. As part of these refactorings we'll
fully move the structure into the object database subsystem.

Prepare for this change by renaming the structure from `git_istream`
to `odb_read_stream`. This mirrors the `odb_write_stream` structure that
we already have.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-11-23 12:56:44 -08:00
Junio C Hamano
01f9010cc7 Merge branch 'ps/object-source-loose' into ps/object-read-stream
A part of code paths that deals with loose objects has been cleaned
up.

* ps/object-source-loose:
  object-file: refactor writing objects via a stream
  object-file: rename `write_object_file()`
  object-file: refactor freshening of objects
  object-file: rename `has_loose_object()`
  object-file: read objects via the loose object source
  object-file: move loose object map into loose source
  object-file: hide internals when we need to reprepare loose sources
  object-file: move loose object cache into loose source
  object-file: introduce `struct odb_source_loose`
  object-file: move `fetch_if_missing`
  odb: adjust naming to free object sources
  odb: introduce `odb_source_new()`
  odb: fix subtle logic to check whether an alternate is usable
2025-11-19 17:39:12 -08:00
Junio C Hamano
9a2fb147f2 Git 2.52
Signed-off-by: Junio C Hamano <gitster@pobox.com>
v2.52.0
2025-11-17 07:35:33 -08:00
Junio C Hamano
7f79dc3562 Merge branch 'jc/ci-use-arm64-p4-on-macos'
We replaced deprecated macos-13 with macos-14 image in GitHub
Actions CI, but we forgot that the image is for arm64.  We have
been seeing a lot of test failures ever since.  Switch to arm64
binary for Perforce tests.

* jc/ci-use-arm64-p4-on-macos:
  Use Perforce arm64 binary on macOS CI jobs
2025-11-17 07:00:12 -08:00
Junio C Hamano
ffff0bb0da Use Perforce arm64 binary on macOS CI jobs
The previous step replaced deprecated macos-13 image with macos-14
image on GitHub Actions CI.  While x86-64 binaries can work there,
because macos-14 images are arm64 based (we could replace it with
macos-14-large that is x86-64), it makes more sense to use arm64
binary there.  Without this change, we have been getting unusually
higher rate of failures from random macOS CI jobs railing to run
t98xx series of tests.

Helped-by: Koji Nakamaru <koji.nakamaru@gree.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-11-16 15:11:41 -08:00
Junio C Hamano
c93f1a0fa3 Merge tag 'l10n-2.52.0-v1' of https://github.com/git-l10n/git-po
l10n-2.52.0-v1

* tag 'l10n-2.52.0-v1' of https://github.com/git-l10n/git-po:
  l10n: zh_CN: updated translation for 2.52
  l10n: uk: add 2.52 translation
  l10n: zh_TW.po: update Git 2.52 translation
  l10n: Updated translation for vi-2.52
  l10n: tr: Update Turkish translations
  l10n: po-id for 2.52
  l10n: ga.po: Update Irish translation for Git 2.52
  l10n: bg.po: Updated Bulgarian translation (6065t)
  l10n: fr: version 2.52
  l10n: sv.po: Update Swedish translation
2025-11-16 10:36:50 -08:00
Teng Long
ad892a61d6 l10n: zh_CN: updated translation for 2.52
Reviewed-by: 依云 <lilydjwg@gmail.com>
Signed-off-by: Teng Long <dyroneteng@gmail.com>
Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
2025-11-16 17:27:10 +08:00
Jiang Xin
900094616b Merge branch '2.52-uk' of github.com:arkid15r/git-ukrainian-l10n
* '2.52-uk' of github.com:arkid15r/git-ukrainian-l10n:
  l10n: uk: add 2.52 translation
2025-11-16 10:16:45 +08:00
Arkadii Yakovets
1480c3907b l10n: uk: add 2.52 translation
Co-authored-by: Kate Golovanova <kate@kgthreads.com>
Signed-off-by: Arkadii Yakovets <ark@cho.red>
Signed-off-by: Kate Golovanova <kate@kgthreads.com>
2025-11-15 10:02:21 -08:00
Jiang Xin
d3849c4a55 Merge branch 'vi-2.52' of github.com:Nekosha/git-po
* 'vi-2.52' of github.com:Nekosha/git-po:
  l10n: Updated translation for vi-2.52
2025-11-15 22:16:10 +08:00
Jiang Xin
4adfdf39e7 Merge branch 'l10n/zh-TW/git-2-52' of github.com:l10n-tw/git-po
* 'l10n/zh-TW/git-2-52' of github.com:l10n-tw/git-po:
  l10n: zh_TW.po: update Git 2.52 translation
2025-11-15 22:14:55 +08:00
Jiang Xin
b8fee03310 Merge branch 'po-id' of github.com:bagasme/git-po
* 'po-id' of github.com:bagasme/git-po:
  l10n: po-id for 2.52
2025-11-15 22:10:16 +08:00
Jiang Xin
4ef1a07de7 Merge branch 'master' of github.com:alshopov/git-po
* 'master' of github.com:alshopov/git-po:
  l10n: bg.po: Updated Bulgarian translation (6065t)
2025-11-15 22:08:47 +08:00
Jiang Xin
5eab3a7a11 Merge branch 'fr_v2.52' of github.com:jnavila/git
* 'fr_v2.52' of github.com:jnavila/git:
  l10n: fr: version 2.52
2025-11-15 22:07:53 +08:00
Jiang Xin
fc2961a95d Merge branch 'l10n-ga-2.52' of github.com:aindriu80/git-po
* 'l10n-ga-2.52' of github.com:aindriu80/git-po:
  l10n: ga.po: Update Irish translation for Git 2.52
2025-11-15 22:06:01 +08:00
Jiang Xin
466b4c0bf3 Merge branch 'master' of github.com:nafmo/git-l10n-sv
* 'master' of github.com:nafmo/git-l10n-sv:
  l10n: sv.po: Update Swedish translation
2025-11-15 22:03:30 +08:00
Yi-Jyun Pan
c35d202dcd l10n: zh_TW.po: update Git 2.52 translation
Reviewed-by: hms5232 <hms5232@hhming.moe>
Co-authored-by: Lumynous <lumynou5.tw@gmail.com>
Signed-off-by: Yi-Jyun Pan <pan93412@gmail.com>
2025-11-15 19:10:36 +08:00
Vũ Tiến Hưng
c7b5e0e58e l10n: Updated translation for vi-2.52
Signed-off-by: Vũ Tiến Hưng <newcomerminecraft@gmail.com>
2025-11-15 12:56:31 +07:00
Emir SARI
8b26798b42 l10n: tr: Update Turkish translations
Signed-off-by: Emir SARI <emir_sari@icloud.com>
2025-11-15 02:31:02 +03:00
Taylor Blau
fd372d9b1a RelNotes: fix typo in release notes for 2.52.0
Introduced via aea86cf00f (The nineteenth batch, 2025-10-14).

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-11-13 09:34:53 -08:00
Bagas Sanjaya
773b840da1 l10n: po-id for 2.52
Update following components:

  - add-patch.c
  - builtin/bisect.c
  - builtin/describe.c
  - builtin/fast-export.c
  - builtin/fast-import.c
  - builtin/fetch.c
  - builtin/for-each-ref.c
  - builtin/gc.c
  - builtin/log.c
  - builtin/pack-refs.c
  - builtin/range-diff.c
  - builtin/reflog.c
  - builtin/refs.c
  - builtin/remote.c
  - builtin/repo.c
  - builtin/sparse-checkout.c
  - command-list.h
  - config.c
  - diff-lib.c
  - diff.c
  - gpg-interface.c
  - midx-write.c
  - promisor-remote.c
  - range-diff.c
  - refs.c
  - refs/files-backend.c
  - refs/reftable-backend.c
  - remote.c
  - usage.c
  - git-send-email.perl

Translate following new components:

  - builtin/last-modified.c
  - http.h

Signed-off-by: Bagas Sanjaya <bagasdotme@gmail.com>
2025-11-13 09:00:02 +07:00
Junio C Hamano
99bd5a5c9f Merge branch 'tc/last-modified-active-paths-optimization'
"git last-modified" was optimized by narrowing the set of paths to
follow as it dug deeper in the history.

* tc/last-modified-active-paths-optimization:
  last-modified: implement faster algorithm
2025-11-12 11:45:24 -08:00
Junio C Hamano
621415c8b5 Git 2.52-rc2
Signed-off-by: Junio C Hamano <gitster@pobox.com>
v2.52.0-rc2
2025-11-12 08:17:31 -08:00
Junio C Hamano
e65e955c03 Merge branch 'dk/make-git-contacts-executable'
Building "git contacts" script (in contrib/) left the resulting
file unexecutable, which has been corrected.

* dk/make-git-contacts-executable:
  perl: also mark git-contacts executable
2025-11-12 08:17:31 -08:00
Junio C Hamano
da5841b45c Merge branch 'dk/meson-html-dir'
The build procedure based on meson learned to allow builders to
specify the directory to install HTML documents.

* dk/meson-html-dir:
  meson: make GIT_HTML_PATH configurable
2025-11-12 08:17:31 -08:00
Junio C Hamano
cb9036aca1 Merge branch 'tu/credential-wincred-makefile-update'
Build procedure for Wincred credential helper has been updated.

* tu/credential-wincred-makefile-update:
  wincred: align Makefile with other Makefiles in contrib
2025-11-12 08:17:31 -08:00
Aindriú Mac Giolla Eoin
2c8999027c l10n: ga.po: Update Irish translation for Git 2.52
Refreshes the Irish translation for Git 2.52, including new strings and
consistency improvements. Verified with `git-po-helper check`.

Signed-off-by: Aindriú Mac Giolla Eoin <aindriu80@gmail.com>
2025-11-10 10:39:35 +00:00
Alexander Shopov
44030a90b2 l10n: bg.po: Updated Bulgarian translation (6065t)
Signed-off-by: Alexander Shopov <ash@kambanaria.org>
2025-11-09 18:28:21 +01:00
Jean-Noël Avila
95bc4ee7c3 l10n: fr: version 2.52
Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
2025-11-09 14:58:27 +01:00
Peter Krefting
b095b7d159 l10n: sv.po: Update Swedish translation
Signed-off-by: Peter Krefting <peter@softwolves.pp.se>
2025-11-07 15:54:20 +01:00
Junio C Hamano
4badef0c35 Merge branch 'dk/parseopt-optional-filename-fixes'
A recently added configuration variable and command line option
syntax ":(optional)" for values that are of filename type
inconsistently behaved on an empty file (configuration took it
happily, while the command line option pretended as if it did not
exist), which has been corrected.

* dk/parseopt-optional-filename-fixes:
  parseopt: remove unreachable code
  parseopt: restore const qualifier to parsed filename
  config: use boolean type for a simple flag
  parseopt: use boolean type for a simple flag
  doc: clarify command equivalence comment
  parseopt: fix :(optional) at command line to only ignore missing files
2025-11-06 15:17:01 -08:00