A new document, gitsecurityboundary(7), has been added to clarify
the security boundaries Git guarantees and the responsibilities of
the user, aiming to provide a clear reference for what constitutes a
security vulnerability in Git.
* tc/security-boundary-doc:
Documentation: clarify Git's security boundary
Like so many other open source projects, the Git project has seen an
ever-increasing flood of security reports. Many of those reports
describe valid bugs yet are redirected from the git-security mailing
list because they are deemed "not vulnerabilities". While some Git
contributors seem to have a very concrete idea how to discern between
bugs that constitute vulnerabilities (and hence must be fixed in secret,
to keep Git users safe) from bugs that can be fixed in the open, most
reporters must be quite puzzled because the Git project provides no
clear document to help define the security boundaries Git tries to
guarantee.
Of course, there _are_ hints and bits and pieces of documentation: Git's
security guidance has accumulated across individual fixes. Some might be
tempted to describe the boundary as "before clone" versus "after clone",
but history establishes a more precise distinction. e69ac42fcc (docs:
document security issues around untrusted .git dirs, 2024-04-16)
explains why cloned content can generally be inspected with `git log`:
repository-local hooks and configuration are not copied, whereas an
untrusted `.git` directory remains unsafe. 779ea9303a (Documentation:
define protected configuration, 2022-07-14) likewise ties trust to
configuration scope rather than timing alone.
State the governing principle in one place: Git's security boundary
concerns unexpected or implicit execution of attacker-controlled code. A
theoretical opportunity to inspect repository contents is not consent to
execute them. Conversely, explicitly choosing an execution-capable
mechanism is materially different. Execution after clone is therefore
not inherently a vulnerability.
This distinction underlies 4cd1cf31ef (Git 2.20.2, 2019-12-04), which
describes CVE-2019-19604 as code running during recursive clone plus a
submodule update "without the user explicitly having asked for that".
a1d4f67c12 (transport: make protocol.file.allow be user by default,
2022-07-29) likewise contrasts direct user action with recursion lacking
user input. e4930e86c0 (t5510: verify that D/F confusion cannot lead to
an RCE, 2024-03-24) similarly frames remote code execution as code run
by an operation not expected to run it.
Timing remains relevant when it removes any meaningful choice.
873a466ea3 (clone: drop the protections where hooks aren't run,
2024-05-20) notes that clone-time hook execution leaves no chance to
inspect first. Conversely, 8d1a744820 (setup.c: create
safe.bareRepository, 2022-07-14) addresses post-clone use of embedded
bare repositories. Together these cases show why timing alone cannot
define the boundary.
Assisted-by: GPT-5.6 Sol
Helped-by: Patrick Steinhardt <ps@pks.im>
Helped-by: Junio C Hamano <gitster@pobox.com>
Co-authored-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Toon Claes <toon@iotcl.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The object storage format has been made configurable via the
'extensions.objectStorage' configuration variable, allowing users
to specify the storage backend and an optional payload, mirroring
the design of 'extensions.refStorage'.
* ps/odb-object-storage-extension:
builtin/submodule: propagate "--object-storage-format="
builtin/clone: introduce "--object-storage-format="
builtin/init: introduce handling of object storage format
builtin: expose the object storage format
setup: allow overriding object storage format via environment
setup: introduce object storage extension
loose: drop unused `repo_write_loose_object_map()`
While the object storage format extension can already be configured
manually via git-config(1), this isn't exactly an ergonomic way of doing
so. For the reference storage format extension, users have a host of
options available to them.
Introduce the equivalent options for the object storage format.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The ref storage format configured via "extensions.refStorage" can be
overridden with the GIT_REF_STORAGE_FORMAT environment variable.
Introduce the GIT_OBJECT_STORAGE_FORMAT environment variable that
overrides "extensions.objectStorage" in the same way.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Redirect folks to `gitdatamodel` instead, since every time it's
referenced the intent is to explain objects, references, blobs, etc.
The update to `gittutorial` isn't very carefully thought through since
we're planning to delete that entire document anyway. It's just there to
maintain some internal consistency.
Signed-off-by: Julia Evans <julia@jvns.ca>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The earliest part of 'man git' has been rewritten to explain various
ways to use 'git help' to get help.
* je/doc-promote-git-help:
doc: use `man git` to teach users how to navigate the docs
A new 'uploadpack.lazyFetchTrusted' configuration variable has been
introduced to allow 'upload-pack' to lazily fetch missing objects from
configured promisor remotes when serving trusted repositories.
* cc/lazy-fetch-trusted-bit:
builtin/upload-pack: don't disable lazy fetching on trusted repo
promisor-remote: prevent infinite recursion when lazy fetching
upload-pack: read uploadpack.lazyFetchTrusted
setup: extract path_allowlist_apply()
promisor-remote: factor out lazy_fetch_objects()
Rewrite `man git` to give a more realistic view of what the
documentation actually provides.
Explain how Git's help system works in `man git`
(`git push -h` gives a short help, `git push --help` is the full docs),
since it's a slightly unusual approach.
Remove the direct references to all the guides, for the following
reasons:
* gittutorial and giteveryday are unlikely to help new users learn
Git. Currently they feel very aspirational (it would be nice to have
a tutorial and a guide to everyday Git commands!), but we should give
users a realistic view of what the documentation actually provides.
The goal is to mention the tutorial again when when we have a tutorial
we're happy with.
* gitcli is not very useful for users. A lot of it is about scripting
and internal details about the option parser.
* the user manual is outdated. The chapter on "Sharing development with
others" explains how to use `git format-patch` which is not how most
Git users collaborate with git.
* mentioning the data model feels out of place once everything else is
removed
Mention `git help` instead of `giteveryday` for now, which does a better
job of giving an overview of everyday commands.
Mention `git help --guides` and `git help --user-interfaces`,
since there are some important guides in there (like `submodules`) that
are hard to discover.
Do not mention `git help --developer-interfaces` since it's not relevant
to users.
Remove https://git.github.io/htmldocs/git.html since it points to the
`master` version of the documentation. https://git-scm.com/ has the
version from the latest release which is more likely to be useful.
Signed-off-by: Julia Evans <julia@jvns.ca>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
A previous commit added a new "uploadpack.lazyFetchTrusted" protected
config variable that can contain an allowlist of repos, as well as
functions to check if the current repo is in that list. But when the
current repo is in that list, we currently do nothing.
Since 7b70e9efb1 (upload-pack: disable lazy-fetching by default,
2024-04-16), `upload-pack` sets `GIT_NO_LAZY_FETCH` to 1 itself,
unconditionally, because by default it shouldn't trust the repositories
it serves. Lazily fetching runs `git fetch`, which may execute
arbitrary commands specified in the configuration and hooks of the
served repo.
The new "uploadpack.lazyFetchTrusted" protected config variable is not
about overriding an environment variable. It's rather about teaching
the code that automatically sets `GIT_NO_LAZY_FETCH` (because it had no
way to know if the served repo could be trusted) to look at the new
config variable to find out if a server operator actually vouched for
that repo.
Let's implement that, so we now have the following cases:
- if `GIT_NO_LAZY_FETCH` is already set, we honor it and leave it
alone, as it comes from the server operator,
- otherwise, if the served repo is in the
"uploadpack.lazyFetchTrusted" allowlist, we don't disable lazy
fetching,
- otherwise, we disable lazy fetching, as we used to.
This allows `upload-pack` and its `pack-objects` child process to
lazily fetch the objects they need to serve a client, for example when
the filter used by the client and the one used by the server don't
match.
Note that what a server operator vouches for by listing a repo there
is that the promisor remotes this repo is configured to lazily fetch
from, as well as its configuration and hooks, are trustworthy. Whether
a client trusts the repo it fetches from is a separate matter, and up
to the client.
As `pack-objects`, which performs the lazy fetch when serving a
client, is a child process of `upload-pack`, not setting
`GIT_NO_LAZY_FETCH` in `upload-pack` is enough for it to be allowed to
lazily fetch, without any further plumbing.
On the other hand, as we leave `GIT_NO_LAZY_FETCH` unset for a trusted
repo instead of setting it to 0, the trust doesn't propagate: if a
trusted repo lazily fetches from a promisor remote that is itself
served by `upload-pack` on the same machine, that nested `upload-pack`
decides for its own repo. This is unlike when a server operator sets
`GIT_NO_LAZY_FETCH` to 0, as that is inherited by all child processes.
Now that "uploadpack.lazyFetchTrusted" is actually doing something,
let's document it (including this difference with `GIT_NO_LAZY_FETCH`),
let's reference it from `GIT_NO_LAZY_FETCH`'s docs, and let's add tests
for it.
Signed-off-by: Christian Couder <christian.couder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The terminology regarding reference storage formats has been unified
across command-line options, environment variables, configuration
variables, and source code, standardizing on the phrase "ref storage
format" (e.g., `--ref-storage-format`, `'GIT_REF_STORAGE_FORMAT'`).
Additionally, the `--ref-storage-format` option has been updated to
accept payloads in the form `<format>://<payload>`.
* ps/ref-storage-format:
setup: allow "--ref-storage-format=" to specify a payload
setup: rename "init.defaultRefFormat" to "init.defaultRefStorageFormat"
t: rename GIT_TEST_DEFAULT_REF_FORMAT
setup: rename ref storage format environment variables
setup: refactor how we configure the ref storage format
refs: expose function to parse reference URIs
help: rename "default-ref-format" to "default-ref-storage-format"
builtin/rev-parse: rename "--show-ref-format" to "--show-ref-storage-format"
builtin/submodule: rename "--ref-format=" to "--ref-storage-format="
builtin/refs: rename "--ref-format=" to "--ref-storage-format="
builtin/clone: rename "--ref-format=" to "--ref-storage-format="
builtin/init: rename "--ref-format=" to "--ref-storage-format="
parse-options: allow for hidden aliases
With the same reasoning as for git-init(1), rename the environment
variables GIT_REFERENCE_BACKEND and GIT_DEFAULT_REF_FORMAT to
GIT_REF_STORAGE_FORMAT and GIT_DEFAULT_REF_STORAGE_FORMAT, respectively.
The old names are kept as an alias to retain compatibility.
While at it, fix indentation for `GIT_REF_STORAGE_FORMAT` docs to use
tabs instead of spaces.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Back when we gained support for reftables we of course introduced the
ability to control the reference storage format that is used by newly
created repositories. This infrastructure has grown over time, and
unfortunately without consistency:
- The command line parameter to specify the ref storage format is
called "--ref-format=", while the corresponding repository extension
is called "refStorage".
- In most cases we refer to the "ref storage format" in our docs, so
calling it "--ref-format=" is being inconsistent with them.
- It is possible to override the ref storage format via an environment
variable that is called "GIT_REFERENCE_BACKEND", which is not even
remotely consistent with anything else.
- There is also an "object format", but that format does not control
how we store objects but rather whether we use SHA1 or SHA256.
So in summary, it's a huge mess.
This problem is about to become even worse though, as we're soon going
to introduce an object storage extension. This extension is the
equivalent to the ref storage extension, and of course we also want
users to be able to control which object storage format new repositories
are using. But we cannot properly name that parameter without creating
even more inconsistencies:
- "--object-format=" would match "--ref-format=", but that parameter
name is already taken to specify the hash function.
- "--object-storage=" would be a good fit, but be inconsistent with
"--ref-format=". Asking the user to execute `git init --ref-format=
--object-storage=` just feels extremely awkward.
Instead, this and subsequent patches will fix the mess by consistently
referring to the ref storage format as such throughout all options,
environment variables and config settings. This new name much more
closely indicates that it is about how we store data and finally brings
consistency into this area. We will keep the old names working of course
for the sake of backwards compatibility.
Start with git-init(1).
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The previous commit added the first mention of gitdatamodel(7) here,
under Guides. But there are also other sections where a mention is
relevant.
Let’s mention it:
• under Description, since it is as useful as the other tutorials
already mentioned there for those who are interested;
• under Terminology, since it complements gitglossary(7) as a
pedagogical rather than reference source for the core terms;[1] and
• under See Also, since the other tutorials (plus the user manual) are
mentioned there.
We don’t need to mention it under Further Documentation since we now
mention it under Description.
† 1: See dee80940 (doc: add an explanation of Git's data model,
2025-11-12):
`gitglossary`. This makes a good effort, but it's an
alphabetically ordered dictionary and a dictionary is not a
good way to learn concepts. You have to jump around too much
and it's not possible to present the concepts in the order
that they should be explained.
Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The way end-users can add their own "git <cmd>" subcommand by
storing "git-<cmd>" in a directory on their $PATH has not been
documented clearly, which has been corrected.
* os/doc-custom-subcommand-on-path:
doc: add information regarding external commands
Git supports creating additional commands through aliases, and through
placement of executables with a "git-" prefix in the PATH.
This information was not easy enough to find - users will look for this
information around the command description, but the documentation
exists in other locations.
Update the "GIT COMMANDS" section to reference the relevant sections,
making it easier for to find this information.
Signed-off-by: Omri Sarig <omri.sarig13@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Git supports running external commands in the user's PATH as if they
were built-in commands (see execv_dashed_external in git.c).
This feature was not fully documented in Git's user-facing
documentation.
Add a short documentation to describe how PATH is used to find a custom
subcommand.
Signed-off-by: Omri Sarig <omri.sarig13@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Git allows setting a different object directory via
'GIT_OBJECT_DIRECTORY', but provides no equivalent for references. In
the previous commit we extended the 'extensions.refStorage' config to
also support an URI input for reference backend with location.
Let's also add a new environment variable 'GIT_REFERENCE_BACKEND' that
takes in the same input as the config variable. Having an environment
variable allows us to modify the reference backend and location on the
fly for individual Git commands.
The environment variable also allows usage of alternate reference
directories during 'git-clone(1)' and 'git-init(1)'. Add the config to
the repository when created with the environment variable set.
When initializing the repository with an alternate reference folder,
create the required stubs in the repositories $GIT_DIR. The inverse,
i.e. removal of the ref store doesn't clean up the stubs in the $GIT_DIR
since that would render it unusable. Removal of ref store is only used
when migrating between ref formats and cleanup of the $GIT_DIR doesn't
make sense in such a situation.
Helped-by: Jean-Noël Avila <jn.avila@free.fr>
Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The "do you still use it?" message given by a command that is
deeply deprecated and allow us to suggest alternatives has been
updated.
* kh/you-still-use-whatchanged-fix:
BreakingChanges: remove claim about whatchanged reports
whatchanged: remove not-even-shorter clause
whatchanged: hint about git-log(1) and aliasing
you-still-use-that??: help the user help themselves
t0014: test shadowing of aliases for a sample of builtins
git: allow alias-shadowing deprecated builtins
git: move seen-alias bookkeeping into handle_alias(...)
git: add `deprecated` category to --list-cmds
Makefile: don’t add whatchanged after it has been removed
With 145 builtin commands (according to `git --list-cmds=builtins`),
users are probably not keeping on top of which ones (if any) are
deprecated.
Let’s expand the experimental `--list-cmds`[1] to allow users and
programs to query for this information. We will also use this in an
upcoming commit to implement `is_deprecated_command`.
[1]: Using something which is experimental to query for deprecations is
perhaps not the most ideal approach, but it is simple to implement
and better than having to scan the documentation
Acked-by: Patrick Steinhardt <ps@pks.im>
Helped-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Using one of the start_delayed_*() functions, clients of the progress
API can request that a progress meter is only shown after some time.
To do that, the implementation intends to count down the number of
seconds stored in struct progress by observing flag progress_update,
which the timer interrupt handler sets when a second has elapsed. This
works during the first second of the delay. But the code forgets to
reset the flag to zero, so that subsequent calls of display_progress()
think that another second has elapsed and decrease the count again
until zero is reached. Due to the frequency of the calls, this happens
without an observable delay in practice, so that the effective delay is
always just one second.
This bug has been with us since the inception of the feature. Despite
having been touched on various occasions, such as 8aade107dd
(progress: simplify "delayed" progress API), 9c5951cacf (progress:
drop delay-threshold code), and 44a4693bfc (progress: create
GIT_PROGRESS_DELAY), the short delay went unnoticed.
Copy the flag state into a local variable and reset the global flag
right away so that we can detect the next clock tick correctly.
Since we have not had any complaints that the delay of one second is
too short nor that GIT_PROGRESS_DELAY is ignored, people seem to be
comfortable with the status quo. Therefore, set the default to 1 to
keep the current behavior.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
We presently use the ".txt" extension for our AsciiDoc files. While not
wrong, most editors do not associate this extension with AsciiDoc,
meaning that contributors don't get automatic editor functionality that
could be useful, such as syntax highlighting and prose linting.
It is much more common to use the ".adoc" extension for AsciiDoc files,
since this helps editors automatically detect files and also allows
various forges to provide rich (HTML-like) rendering. Let's do that
here, renaming all of the files and updating the includes where
relevant. Adjust the various build scripts and makefiles to use the new
extension as well.
Note that this should not result in any user-visible changes to the
documentation.
Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>