79299 Commits

Author SHA1 Message Date
Christian Couder
c01bcb5d00 fetch-pack: wire up and enable auto filter logic
Previous commits have set up an infrastructure for `--filter=auto` to
automatically prepare a partial clone filter based on what the server
advertised and the client accepted.

Using that infrastructure, let's now enable the `--filter=auto` option
in `git clone` and `git fetch` by setting `allow_auto_filter` to 1.

Note that these small changes mean that when `git clone --filter=auto`
or `git fetch --filter=auto` are used, "auto" is automatically saved
as the partial clone filter for the server on the client. Therefore
subsequent calls to `git fetch` on the client will automatically use
this "auto" mode even without `--filter=auto`.

Let's also set `allow_auto_filter` to 1 in `transport.c`, as the
transport layer must be able to accept the "auto" filter spec even if
the invoking command hasn't fully parsed it yet.

When an "auto" filter is requested, let's have the "fetch-pack.c" code
in `do_fetch_pack_v2()` compute a filter and send it to the server.

In `do_fetch_pack_v2()` the logic also needs to check for the
"promisor-remote" capability and call `promisor_remote_reply()` to
parse advertised remotes and populate the list of those accepted (and
their filters).

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-23 22:43:06 +09:00
Christian Couder
d92ba46d5a promisor-remote: keep advertised filter in memory
Currently, advertised filters are only kept in memory temporarily
during parsing, or persisted to disk if `promisor.storeFields`
contains 'partialCloneFilter'.

In a following commit though, we will add a `--filter=auto` option.
This option will enable the client to use the filters that the server
is suggesting for the promisor remotes the client accepts.

To use them even if `promisor.storeFields` is not configured, these
filters should be stored somewhere for the current session.

Let's add an `advertised_filter` field to `struct promisor_remote`
for that purpose.

To ensure that the filters are available in all cases,
filter_promisor_remote() captures them into a temporary list and
applies them to the `promisor_remote` structs after the potential
configuration reload.

Then the accepted remotes are marked as `accepted` in the repository
state. This ensures that subsequent calls to look up accepted remotes
(like in the filter construction below) actually find them.

In a following commit, we will add a `--filter=auto` option that will
enable a client to use the filters suggested by the server for the
promisor remotes the client accepted.

To enable the client to construct a filter spec based on these filters,
let's add a `promisor_remote_construct_filter(repo)` function.

This function:

- iterates over all accepted promisor remotes in the repository,
- collects the filters advertised for them (using `advertised_filter`
  which a previous commit added to `struct promisor_remote`), and
- generates a single filter spec for them (using the
  `list_objects_filter_combine()` function added by a previous commit).

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-23 22:43:06 +09:00
Christian Couder
c8c941181a list-objects-filter-options: implement auto filter resolution
In a following commit, we will need to aggregate filters from multiple
accepted promisor remotes into a single filter.

For that purpose, let's add a `list_objects_filter_combine()` helper
function that takes a list of filter specifications and combines them
into a single string. If multiple filters are provided, it constructs a
"combine:..." filter, ensuring that sub-filters are properly
URL-encoded using the existing `allow_unencoded` logic.

In a following commit, we will add a `--filter=auto` option that will
enable a client to use the filters suggested by the server for the
promisor remotes the client accepted.

To simplify the filter processing related to this new feature, let's
also add a small `list_objects_filter_resolve_auto()` function.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-23 22:43:06 +09:00
Christian Couder
13bf8f5bcb list-objects-filter-options: support 'auto' mode for --filter
In a following commit, we are going to allow passing "auto" as a
<filterspec> to the `--filter=<filterspec>` option, but only for some
commands. Other commands that support the `--filter=<filterspec>`
option should still die() when 'auto' is passed.

Let's set up the "list-objects-filter-options.{c,h}" infrastructure to
support that:

- Add a new `unsigned int allow_auto_filter : 1;` flag to
  `struct list_objects_filter_options` which specifies if "auto" is
  accepted or not.
- Change gently_parse_list_objects_filter() to parse "auto" if it's
  accepted.
- Make sure we die() if "auto" is combined with another filter.
- Update list_objects_filter_release() to preserve the
  allow_auto_filter flag, as this function is often called (via
  opt_parse_list_objects_filter) to reset the struct before parsing a
  new value.

Let's also update `list-objects-filter.c` to recognize the new
`LOFC_AUTO` choice. Since "auto" must be resolved to a concrete filter
before filtering actually begins, initializing a filter with
`LOFC_AUTO` is invalid and will trigger a BUG().

Note that ideally combining "auto" with "auto" could be allowed, but in
practice, it's probably not worth the added code complexity. And if we
really want it, nothing prevents us to allow it in future work.

If we ever want to give a meaning to combining "auto" with a different
filter too, nothing prevents us to do that in future work either.

While at it, let's add a new "u-list-objects-filter-options.c" file for
`struct list_objects_filter_options` related unit tests. For now it
only tests gently_parse_list_objects_filter() though.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-23 22:43:05 +09:00
Christian Couder
0d76d0c600 doc: fetch: document --filter=<filter-spec> option
The `--filter=<filter-spec>` option is documented in most commands that
support it except `git fetch`.

Let's fix that and document that option properly in the same way as it
is already documented for `git clone`.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-23 22:43:05 +09:00
Christian Couder
6ac467fdbd fetch: make filter_options local to cmd_fetch()
The `struct list_objects_filter_options filter_options` variable used
in "builtin/fetch.c" to store the parsed filters specified by
`--filter=<filterspec>` is currently a static variable global to the
file.

As we are going to use it more in a following commit, it could become a
bit less easy to understand how it's managed.

To avoid that, let's make it clear that it's owned by cmd_fetch() by
moving its definition into that function and making it non-static.

This requires passing a pointer to it through the prepare_transport(),
do_fetch(), backfill_tags(), fetch_one_setup_partial(), and fetch_one()
functions, but it's quite straightforward.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-23 22:43:05 +09:00
Christian Couder
50cedfdf94 clone: make filter_options local to cmd_clone()
The `struct list_objects_filter_options filter_options` variable used
in "builtin/clone.c" to store the parsed filters specified by
`--filter=<filterspec>` is currently a static variable global to the
file.

As we are going to use it more in a following commit, it could become
a bit less easy to understand how it's managed.

To avoid that, let's make it clear that it's owned by cmd_clone() by
moving its definition into that function and making it non-static.

The only additional change to make this work is to pass it as an
argument to checkout(). So it's a small quite cheap cleanup anyway.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-23 22:43:05 +09:00
Christian Couder
09b0cefcd8 promisor-remote: allow a client to store fields
A previous commit allowed a server to pass additional fields through
the "promisor-remote" protocol capability after the "name" and "url"
fields, specifically the "partialCloneFilter" and "token" fields.

Another previous commit, c213820c51 (promisor-remote: allow a client
to check fields, 2025-09-08), has made it possible for a client to
decide if it accepts a promisor remote advertised by a server based
on these additional fields.

Often though, it would be interesting for the client to just store in
its configuration files these additional fields passed by the server,
so that it can use them when needed.

For example if a token is necessary to access a promisor remote, that
token could be updated frequently only on the server side and then
passed to all the clients through the "promisor-remote" capability,
avoiding the need to update it on all the clients manually.

Storing the token on the client side makes sure that the token is
available when the client needs to access the promisor remotes for a
lazy fetch.

In the same way, if it appears that it's better to use a different
filter to access a promisor remote, it could be helpful if the client
could automatically use it.

To allow this, let's introduce a new "promisor.storeFields"
configuration variable.

Like "promisor.checkFields" and "promisor.sendFields", it should
contain a comma or space separated list of field names. Only the
"partialCloneFilter" and "token" field names are supported for now.

When a server advertises a promisor remote, for example "foo", along
with for example "token=XXXXX" to a client, and on the client side
"promisor.storeFields" contains "token", then the client will store
XXXXX for the "remote.foo.token" variable in its configuration file
and reload its configuration so it can immediately use this new
configuration variable.

A message is emitted on stderr to warn users when the config is
changed.

Note that even if "promisor.acceptFromServer" is set to "all", a
promisor remote has to be already configured on the client side for
some of its config to be changed. In any case no new remote is
configured and no new URL is stored.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-23 22:43:05 +09:00
Christian Couder
81dae58f91 promisor-remote: refactor initialising field lists
In "promisor-remote.c", the fields_sent() and fields_checked()
functions serve similar purposes and contain a small amount of
duplicated code.

As we are going to add a similar function in a following commit,
let's refactor this common code into a new initialize_fields_list()
function.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-23 22:43:05 +09:00
Junio C Hamano
66ce5f8e88 The 12th batch
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-23 11:33:17 +09:00
Junio C Hamano
d8000781eb Merge branch 'kn/fix-fetch-backfill-tag-with-batched-ref-updates'
"git fetch" that involves fetching tags, when a tag being fetched
needs to overwrite existing one, failed to fetch other tags, which
has been corrected.

* kn/fix-fetch-backfill-tag-with-batched-ref-updates:
  fetch: fix failed batched updates skipping operations
  fetch: fix non-conflicting tags not being committed
  fetch: extract out reference committing logic
2025-12-23 11:33:17 +09:00
Junio C Hamano
5d2be7425c Merge branch 'rs/diff-files-r-find-copies-fix'
"git diff-files -R --find-copies-harder" has been taught to use
the potential copy sources from the index correctly.

* rs/diff-files-r-find-copies-fix:
  diff-files: fix copy detection
2025-12-23 11:33:16 +09:00
Junio C Hamano
86ebd83e6a Merge branch 'jc/memzero-array'
Further application of MEMZERO_ARRAY() macro to the rest of the
code base.

* jc/memzero-array:
  cocci: use MEMZERO_ARRAY() a bit more
  coccicheck: emit the contents of cocci patch
2025-12-23 11:33:16 +09:00
Junio C Hamano
396df67739 Merge branch 'tc/memzero-array'
MEMZERO_ARRAY() helper is introduced to avoid clearing only the
first N bytes of an N-element array whose elements are larger than
a byte.

* tc/memzero-array:
  contrib/coccinelle: pass include paths to spatch(1)
  git-compat-util: introduce MEMZERO_ARRAY() macro
2025-12-23 11:33:16 +09:00
Junio C Hamano
c77ba76807 Merge branch 'jc/completion-no-single-letter-options'
In-code comment update to clarify that single-letter options are
outside of the scope of command line completion script.

* jc/completion-no-single-letter-options:
  completion: clarify support for short options and arguments
2025-12-23 11:33:15 +09:00
Junio C Hamano
00bf98b16e Merge branch 'jc/submodule-add'
"git submodule add" to add a submodule under <name> segfaulted,
when a submodule.<name>.something is already in .gitmodules file
without defining where its submodule.<name>.path is, which has been
corrected.

* jc/submodule-add:
  submodule add: sanity check existing .gitmodules
2025-12-23 11:33:15 +09:00
Junio C Hamano
f0c063b67c Merge branch 'ds/doc-scalar-config'
Documentation updates.

* ds/doc-scalar-config:
  scalar: document config settings
  scalar: alphabetize and simplify config
  scalar: remove stale config values
  scalar: use index.skipHash=true for performance
  scalar: annotate config file with "set by scalar"
2025-12-23 11:33:15 +09:00
Junio C Hamano
c8d76f7325 The 11th batch
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-22 14:57:49 +09:00
Junio C Hamano
e72259073d Merge branch 'rs/t4014-git-version-string-fix'
Test fix.

* rs/t4014-git-version-string-fix:
  t4014: support Git version strings with spaces
2025-12-22 14:57:49 +09:00
Junio C Hamano
bcc20b8304 Merge branch 'kj/pull-options-decl-cleanup'
Code clean-up.

* kj/pull-options-decl-cleanup:
  pull: move options[] array into function scope
2025-12-22 14:57:49 +09:00
Junio C Hamano
448673412d Merge branch 'jc/macports-darwinports'
Makefile in-comment doc update.

* jc/macports-darwinports:
  Makefile: help macOS novices by mentioning MacPorts
2025-12-22 14:57:48 +09:00
Junio C Hamano
24a51fef5b Merge branch 'rs/replay-wrong-onto-fix'
"git replay --onto=<commit> ...", when <commit> is mistyped,
started to segfault with recent change, which has been corrected.

* rs/replay-wrong-onto-fix:
  replay: move onto NULL check before first use
2025-12-22 14:57:48 +09:00
Junio C Hamano
6a3051d3c2 Merge branch 'kh/doc-replay-updates'
"git replay" documentation updates.

* kh/doc-replay-updates:
  doc: replay: link section using markup
  replay: improve --contained and add to doc
  doc: replay: mention no output on conflicts
2025-12-22 14:57:48 +09:00
Junio C Hamano
5a8046ab33 Merge branch 'ps/odb-alternates-object-sources'
Code refactoring around alternate object store.

* ps/odb-alternates-object-sources:
  odb: write alternates via sources
  odb: read alternates via sources
  odb: drop forward declaration of `read_info_alternates()`
  odb: remove mutual recursion when parsing alternates
  odb: stop splitting alternate in `odb_add_to_alternates_file()`
  odb: move computation of normalized objdir into `alt_odb_usable()`
  odb: resolve relative alternative paths when parsing
  odb: refactor parsing of alternates to be self-contained
2025-12-22 14:57:48 +09:00
Junio C Hamano
c4a0c8845e The 10th batch
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-17 14:11:53 +09:00
Junio C Hamano
f3951e3230 Merge branch 'kh/doc-send-email-paragraph-fix'
Docfix.

* kh/doc-send-email-paragraph-fix:
  doc: send-email: fix broken list continuation
2025-12-17 14:11:53 +09:00
Junio C Hamano
1c8a1b7bf9 Merge branch 'mh/doc-config-gui-gcwarning'
Docfix.

* mh/doc-config-gui-gcwarning:
  config: document 'gui.GCWarning'
2025-12-17 14:11:53 +09:00
Junio C Hamano
85964265a3 Merge branch 'kh/doc-pre-commit-fix'
Docfix.

* kh/doc-pre-commit-fix:
  doc: join default pre-commit paragraphs
2025-12-17 14:11:53 +09:00
Junio C Hamano
1c22dfde18 Merge branch 'jc/capability-leak'
Leakfix.

* jc/capability-leak:
  connect: plug protocol capability leak
2025-12-17 14:11:52 +09:00
Junio C Hamano
e7ef0ca622 The ninth batch
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-16 11:08:35 +09:00
Junio C Hamano
91bfbf49b6 Merge branch 'rs/ban-mktemp'
Rewrite the only use of "mktemp()" that is subject to TOCTOU race
and Stop using the insecure "mktemp()" function.

* rs/ban-mktemp:
  compat: remove gitmkdtemp()
  banned.h: ban mktemp(3)
  compat: remove mingw_mktemp()
  compat: use git_mkdtemp()
  wrapper: add git_mkdtemp()
2025-12-16 11:08:35 +09:00
Junio C Hamano
72154ce414 Merge branch 'gf/win32-pthread-cond-init'
Emulation code clean-up.

* gf/win32-pthread-cond-init:
  win32: pthread_cond_init should return a value
2025-12-16 11:08:34 +09:00
Junio C Hamano
dbe54273a7 Merge branch 'ps/object-read-stream'
The "git_istream" abstraction has been revamped to make it easier
to interface with pluggable object database design.

* ps/object-read-stream:
  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`
2025-12-16 11:08:34 +09:00
René Scharfe
f293bdcc29 diff-files: fix copy detection
Copy detection cannot work when comparing the index to the working tree
because Git ignores files that it is not explicitly told to track.  It
should work in the other direction, though, i.e. for a reverse diff of
the deletion of a copy from the index.

d1f2d7e8ca (Make run_diff_index() use unpack_trees(), not read_tree(),
2008-01-19) broke it with a seemingly stray change to run_diff_files().

We didn't notice because there's no test for that.  But even if we had
one, it might have gone unnoticed because the breakage only happens
with index preloading, which requires at least 1000 entries (more than
most test repos have) and is racy because it runs in parallel with the
actual command.

Fix copy detection by queuing up-to-date and skip-worktree entries using
diff_same().

While at it, use diff_same() also for queuing unchanged files not
flagged as up-to-date, i.e. clean submodules and entries where
preloading was not done at all or not quickly enough.  It uses less
memory than diff_change() and doesn't unnecessarily set the diff flag
has_changes.

Add two tests to cover running both without and with preloading.  The
first one passes reliably with the original code.  The second one
enables preloading and thus is racy.  It has a good chance to pass even
without the fix, but fails within seconds when running the test script
with --stress.  With the fix it runs fine for several minutes, until
my patience runs out.

Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-16 10:23:26 +09:00
Junio C Hamano
c0c4dc0b70 Merge branch 'rs/diff-index-find-copies-harder-optim' into rs/diff-files-r-find-copies-fix
* rs/diff-index-find-copies-harder-optim:
  diff-index: don't queue unchanged filepairs with diff_change()
2025-12-16 10:22:56 +09:00
Derrick Stolee
4ce170c522 scalar: document config settings
Add user-facing documentation that justifies the values being set by
'scalar clone', 'scalar register', and 'scalar reconfigure'.

Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Derrick Stolee <stolee@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-16 09:42:44 +09:00
Junio C Hamano
d8af7cadaa The eighth batch
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-14 17:04:38 +09:00
Junio C Hamano
f29e98755d Merge branch 'je/doc-data-model'
Docfix.

* je/doc-data-model:
  doc: remove stray text in Git data model
2025-12-14 17:04:38 +09:00
Junio C Hamano
affdbe41bd Merge branch 'lo/repo-struct-z'
"git repo struct" learned to take "-z" as a synonym to "--format=nul".

* lo/repo-struct-z:
  repo: add -z as an alias for --format=nul to git-repo-structure
  repo: use [--format=... | -z] instead of [-z] in git-repo-info synopsis
  repo: remove blank line from Documentation/git-repo.adoc
2025-12-14 17:04:37 +09:00
Junio C Hamano
2378ebcb58 Merge branch 'kh/advise-w-git-help-in-branch'
A help message from "git branch" now mentions "git help" instead of
"man" when suggesting to read some documentation.

* kh/advise-w-git-help-in-branch:
  branch: advice using git-help(1) instead of man(1)
2025-12-14 17:04:37 +09:00
Junio C Hamano
c382988d7b Merge branch 'je/doc-pull'
Doc fixup.

* je/doc-pull:
  doc: git-pull: fix 'git --rebase abort' typo
2025-12-14 17:04:37 +09:00
Junio C Hamano
25ce0883fe Merge branch 'tc/meson-cross-compile-fix'
Build fix.

* tc/meson-cross-compile-fix:
  meson: use is_cross_build() where possible
  meson: only detect ICONV_OMITS_BOM if possible
  meson: ignore subprojects/.wraplock
2025-12-14 17:04:37 +09:00
Junio C Hamano
21787077bf Merge branch 'js/last-modified-with-sparse-checkouts'
"git last-modified" used to mishandle "--" to mark the beginning of
pathspec, which has been corrected.

* js/last-modified-with-sparse-checkouts:
  last-modified: support sparse checkouts
2025-12-14 17:04:37 +09:00
Junio C Hamano
84ca5a2457 Merge branch 'rs/diff-index-find-copies-harder-optim'
Halve the memory consumed by artificial filepairs created during
"git diff --find-copioes-harder", also making the operation run
faster.

* rs/diff-index-find-copies-harder-optim:
  diff-index: don't queue unchanged filepairs with diff_change()
2025-12-14 17:04:36 +09:00
Junio C Hamano
794c979889 Merge branch 'tc/last-modified-active-paths-optimization'
Recent optimization to "last-modified" command introduced use of
uninitialized block of memory, which has been corrected.

* tc/last-modified-active-paths-optimization:
  last-modified: fix use of uninitialized memory
2025-12-14 17:04:36 +09:00
Kristoffer Haugsbakk
9ba08b30a1 doc: replay: link section using markup
Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-14 15:56:02 +09:00
Kristoffer Haugsbakk
03d7c9c457 replay: improve --contained and add to doc
There is no documentation for `--contained`.

Start by copying the text from `replay_options` in `builtin/
replay.c`. But some people think that the existing text is a
bit unclear; what does it mean for a branch to be contained
in a revision range? Let’s include the implied commits here:
the branches that point at commits in the range.

Also use “update” instead of “advance”. “Update” is the verb
commonly used in this context.

Helped-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-14 15:56:02 +09:00
Kristoffer Haugsbakk
8467c95419 doc: replay: mention no output on conflicts
Some commands will produce output on stderr if there are conflicts, but
git-replay(1) is completely silent. Explicitly spell that out.

Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-14 15:56:01 +09:00
René Scharfe
007b8994d4 t4014: support Git version strings with spaces
git --version reports its version with the prefix "git version ".
Remove precisely this string instead of everything up to and including
the rightmost space to avoid butchering version strings that contain
spaces.  This helps Apple's release of Git, which reports its version
like this: "git version 2.50.1 (Apple Git-155)".

Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-14 15:50:44 +09:00
Junio C Hamano
8ea9492cf3 cocci: use MEMZERO_ARRAY() a bit more
Existing code in files that have been fairly stable trigger the
"make coccicheck" suggestions due to the new check.

Rewrite them to use MEMZERO_ARRAY()

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-13 10:47:59 +09:00