| Age | Commit message (Collapse) | Author | Files | Lines |
|
The `manpage_target` variable isn't used at all, and the `manpage_path`
variable is only used in a single location. Remove the former variable
and inline the latter.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
The summary of auto-detected features prints a boolean for every option
to tell the user whether or not the feature has been auto-enabled or
not. This summary can be improved though, as in some cases this boolean
is derived from a dependency. So if we pass in the dependency directly,
then Meson knows to both print a boolean and, if the dependency was
found, it also prints a version number.
Adapt the code accordingly and enable `bool_yn` so that actual booleans
are formatted similarly to dependencies. Before this change:
Auto-detected features
benchmarks : true
curl : true
expat : true
gettext : true
gitweb : true
iconv : true
pcre2 : true
perl : true
python : true
And after this change, we now see the version numbers as expected:
Auto-detected features
benchmarks : YES
curl : YES 8.14.1
expat : YES 2.7.1
gettext : YES
gitweb : YES
iconv : YES
pcre2 : YES 10.44
perl : YES
python : YES
Note that this change also enables colorization of the boolean options,
green for "YES" and red for "NO".
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
The value for the 'https' backend option is printed twice: once via the
summary of auto-detected features and once via our summary of backends.
Drop it from the former summary.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
When Python features are enabled we search both for a native and
non-native version of Python. This is wrong though: we don't use Python
in our build process, so there is no need to search for it in the first
place.
There is one location where we use the native version of Python, namely
when deciding whether or not we want to wire up git-p4(1). This check is
invalid though, as we shouldn't check for the build host to have Python,
but for the target host.
Fix this invalid check to use the non-native version of Python and stop
searching for a native version of Python altogether.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
When two remotes collide in the destinations of their fetch refspecs,
the results can be confusing. For example, in this silly example:
git config remote.one.url [...]
git config remote.one.fetch +refs/heads/*:refs/remotes/collide/*
git config remote.two.url [...]
git config remote.two.fetch +refs/heads/*:refs/remotes/collide/*
git fetch --all
we may try to write to the same ref twice (once for each remote we're
fetching). There's also a more subtle version of this. If you have
remotes "outer/inner" and "outer", then the ref "inner/branch" on the
second remote will conflict with just "branch" on the former (they both
want to write to "refs/remotes/outer/inner/branch").
We probably don't want to forbid this kind of overlap completely. While
the results can be confusing, there are legitimate reasons to have
multiple refs write into the same namespace (e.g., if one is a "backup"
of the other that is rarely fetched from).
But it may be worth limiting the porcelain "git remote" command to avoid
this confusion. The example above cannot be done with "git remote",
because it always[1] matches the refspecs to the remote name, and you
can only have one instance of each remote name. But you can still
trigger the more subtle variant like this:
git remote add outer [...]
git remote add outer/inner [...]
So let's detect that kind of name collision (in both directions) and
forbid it. You can still do whatever you like by manipulating the config
directly, but this should prevent the most obvious foot-gun.
[1] Almost always. With the --mirror option, the resulting refspec will
just write into "refs/*"; the remote name does not appear in the ref
namespace at all.
Our new "names must not overlap" rule is not necessary for that
case, but it seems reasonable to enforce it consistently. We already
require all remote names to be valid in the ref namespace, even
though we won't ever use them in that context for --mirror remotes.
Likewise, our new rule doesn't help with overlap here. Any two
mirror remotes will always overlap (in fact, any mirror remote along
with any other single one, since refs/remotes/ is a subset of the
mirrored refs). I'm not sure this is worth worrying about, but if it
is, we'd want an additional rule like "mirror remotes must be the
only remote".
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
"git push" and "git fetch" are taught to update refs in batches to
gain performance.
* kn/fetch-push-bulk-ref-update:
receive-pack: handle reference deletions separately
refs/files: skip updates with errors in batched updates
receive-pack: use batched reference updates
send-pack: fix memory leak around duplicate refs
fetch: use batched reference updates
refs: add function to translate errors to strings
|
|
* maint-2.50:
t: avoid git config syntax from newer releases
Documentation/RelNotes: use .adoc extension for new security releases
|
|
* maint-2.49:
t: avoid git config syntax from newer releases
|
|
* maint-2.48:
t: avoid git config syntax from newer releases
|
|
* maint-2.47:
t: avoid git config syntax from newer releases
|
|
* maint-2.46:
t: avoid git config syntax from newer releases
|
|
This turns into a no-op merge, since more recent versions of Git
newer than 2.46 track do support the newer "git config" syntax.
* maint-2.45:
t: avoid git config syntax from newer releases
|
|
* maint-2.44:
t: avoid git config syntax from newer releases
|
|
* maint-2.43:
t: avoid git config syntax from newer releases
|
|
maint-2.43
* tz/avoid-newer-config-syntax-in-older-maint-tracks:
t: avoid git config syntax from newer releases
|
|
In a recent security release, 05e9cd64ee (config: quote values
containing CR character, 2025-05-19) added calls to `git config get`,
`git config set`, and `git config unset` which are not present on the
maint-2.43 branch.
These subcommands were added in the following commits, released in
git-2.46.0:
4e51389000 (builtin/config: introduce "get" subcommand, 2024-05-06),
00bbdde141 (builtin/config: introduce "set" subcommand, 2024-05-06),
95ea69c67b (builtin/config: introduce "unset" subcommand, 2024-05-06)
Revert to the previous `git config` syntax for older maintenance
branches.
Signed-off-by: Todd Zullinger <tmz@pobox.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
When running t1006 via Meson we receive an error about invalid TAP
format:
$ meson test t1006-cat-file
1/1 t1006-cat-file OK 3.86s 420 subtests passed
stdout: 147: UNKNOWN: c308ae01840d8e620ad554ee5d77fe114dc2d912:path with spaces
stdout: 159: UNKNOWN: 3625298bf5e7c464a7d0e38ea80c2a5b5904d9a3e5b2b025b67f360e09b68dc7:path with spaces
ERROR: Unknown TAP output lines for a supported TAP version.
This is probably a bug in the test; if they are not TAP syntax, prefix them with a #
Ok: 1
Fail: 0
While Meson copes with it alright, it's still annoying to see these
errors on every test run.
The root cause of the broken format is a call to grep(1) that gets
executed outside of a test case, which has been added recently via
9fd38038b9c (t1006: update 'run_tests' to test generic object
specifiers, 2025-06-02). This call is done to determine whether a
subsequent test case is expected to succeed or fail, so it makes sense
to have it execute outside of a test case. But whenever we do that, we
must be extra careful to not generate any output that breaks the TAP
format.
Fix the issue by adding '-q' to the command so that it doesn't print
any matching lines.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
When creating a new reference in the "files" backend we first create the
directory hierarchy for that reference, then create the lockfile for
that reference, and finally rename the lockfile into place. When the
transaction gets aborted we prune the lockfile, but we don't clean up
the directory hierarchy that we may have created for the lockfile.
In some egde cases this can lead to lots of empty directories being
cluttered in the ".git/refs" directory that really serve no purpose at
all. We know to prune such empty directories when packing refs, but that
only patches over the issue.
Improve this by removing empty parents when cleaning up still-locked
references in `files_transaction_cleanup()`. This function is also
called when preparing or committing the transaction, so this change also
helps when not explicitly aborting the transaction.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
The `git pack-refs --auto` flag asks the ref backend to decide for
itself whether or not references need to be repacked. This is done to
ensure that we don't repack in cases where the backend is already in a
good-enough state, which is typically the case for the "reftable"
backend that performs auto-compaction on writes.
As such, we initially only had heuristics in place for the "reftable"
backend. The "files" backend didn't have any heuristics, so we'd repack
loose references every time `git pack-refs --auto` was executed. This
caused excessive repacking with that backend though, which is why we
eventually implemented a heuristic via c3459ae9ef2 (refs/files: use
heuristic to decide whether to repack with `--auto`, 2024-09-04).
The documentation for the `--auto` flag hasn't been updated accordingly
and still claims that we don't have any metrics for the "files" backend.
Update it to reflect the new reality.
Reported-by: Karthik Nayak <karthik.188@gmail.com>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
* maint-2.49:
Documentation/RelNotes: use .adoc extension for new security releases
|
|
When preparing the latest round of security fixes, we wrote release
notes in v2.43.7, and then successively merged those up through to the
various 'maint' branches.
However, the 2.49 release series is the first to have commit 1f010d6bdf
(doc: use .adoc extension for AsciiDoc files, 2025-01-20). This means
that we should have renamed the new-but-historical release notes from
*.txt to *.adoc during the merge into the 'maint-2.49' branch, but
neglected to do so.
Rename them accordingly to match the convention introduced by
1f010d6bdf. Since the release materials in question here were prepared
before v2.50.0 was tagged, the 'maint' track for that release series is
OK as is.
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
This addresses CVE-2025-46835, Git GUI can create and overwrite a
user's files:
When a user clones an untrusted repository and is tricked into editing
a file located in a maliciously named directory in the repository, then
Git GUI can create and overwrite files for which the user has write
permission.
* js/fix-open-exec-git:
git-gui: sanitize 'exec' arguments: convert new 'cygpath' calls
git-gui: do not mistake command arguments as redirection operators
git-gui: introduce function git_redir for git calls with redirections
git-gui: pass redirections as separate argument to git_read
git-gui: pass redirections as separate argument to _open_stdout_stderr
git-gui: convert git_read*, git_write to be non-variadic
git-gui: use git_read in githook_read
git-gui: break out a separate function git_read_nice
git-gui: remove option --stderr from git_read
git-gui: sanitize 'exec' arguments: background
git-gui: sanitize 'exec' arguments: simple cases
git-gui: treat file names beginning with "|" as relative paths
git-gui: remove git config --list handling for git < 1.5.3
git-gui: remove HEAD detachment implementation for git < 1.5.3
git-gui: remove Tcl 8.4 workaround on 2>@1 redirection
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
|
|
This addresses CVE-2025-46334, Git GUI malicious command injection on
Windows.
A malicious repository can ship versions of sh.exe or typical textconv
filter programs such as astextplain. Due to the unfortunate design of
Tcl on Windows, the search path when looking for an executable always
includes the current directory. The mentioned programs are invoked when
the user selects "Git Bash" or "Browse Files" from the menu.
* ml/replace-auto-execok:
git-gui: override exec and open only on Windows
git-gui: sanitize $PATH on all platforms
git-gui: assure PATH has only absolute elements.
git-gui: cleanup git-bash menu item
git-gui: avoid auto_execok in do_windows_shortcut
git-gui: avoid auto_execok for git-bash menu item
git-gui: remove unused proc is_shellscript
git-gui: remove special treatment of Windows from open_cmd_pipe
git-gui: use only the configured shell
git-gui: make _shellpath usable on startup
git-gui: use [is_Windows], not bad _shellpath
git-gui: _which, only add .exe suffix if not present
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
|
|
This addresses CVE-2025-27613, Gitk can create and truncate a user's
files:
When a user clones an untrusted repository and runs gitk without
additional command arguments, files for which the user has write
permission can be created and truncated. The option "Support per-file
encoding" must have been enabled before in Gitk's Preferences. This
option is disabled by default.
The same happens when "Show origin of this line" is used in the main
window (regardless of whether "Support per-file encoding" is enabled or
not).
* js/fix-open-exec:
gitk: sanitize 'open' arguments: revisit recently updated 'open' calls
gitk: sanitize 'open' arguments: command pipeline
gitk: collect construction of blameargs into a single conditional
gitk: sanitize 'open' arguments: simple commands, readable and writable
gitk: sanitize 'open' arguments: simple commands with redirections
gitk: sanitize 'open' arguments: simple commands
gitk: sanitize 'exec' arguments: redirect to process
gitk: sanitize 'exec' arguments: redirections and background
gitk: sanitize 'exec' arguments: redirections
gitk: sanitize 'exec' arguments: 'eval exec'
gitk: sanitize 'exec' arguments: simple cases
gitk: have callers of diffcmd supply pipe symbol when necessary
gitk: treat file names beginning with "|" as relative paths
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
|
|
This addresses CVE-2025-27614, Arbitrary command execution with Gitk:
A Git repository can be crafted in such a way that with some social
engineering a user who has cloned the repository can be tricked into
running any script (e.g., Bourne shell, Perl, Python, ...) supplied by
the attacker by invoking `gitk filename`, where `filename` has a
particular structure. The script is run with the privileges of the user.
* ah/fix-open-with-stdin:
gitk: encode arguments correctly with "open"
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
|
|
|
|
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
CI updates.
* cb/ci-freebsd-update-to-14.3:
ci: update FreeBSD image to 14.3
|
|
Doc markup fix.
* jj/doc-branch-markup-fix:
doc: improve formatting in branch section
|
|
When "git daemon" sees a signal while attempting to accept() a new
client, instead of retrying, it skipped it by mistake, which has
been corrected.
* cb/daemon-retry-interrupted-accept:
daemon: correctly handle soft accept() errors in service_loop
|
|
Leakfix.
* jk/fix-leak-send-pack:
send-pack: clean-up even when taking an early exit
send-pack: clean up extra_have oid array
|
|
Remove unnecessary check from "git daemon" code.
* cb/daemon-fd-check-fix:
daemon: remove unnecesary restriction for listener fd
|
|
Updating submodules from the upstream did not work well when
submodule's HEAD is detached, which has been improved.
* jk/submodule-remote-lookup-cleanup:
submodule: look up remotes by URL first
submodule: move get_default_remote_submodule()
submodule--helper: improve logic for fallback remote name
remote: remove the_repository from some functions
dir: move starts_with_dot(_dot)_slash to dir.h
remote: fix tear down of struct remote
remote: remove branch->merge_name and fix branch_release()
|
|
- Use `backticks` for keywords and more complex option
descriptions. The new rendering engine will apply synopsis rules to
these spans.
- Explain possible options in description list instead of in a paragraph.
Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
- Use `backticks` for keywords and more complex option
descriptions. The new rendering engine will apply synopsis rules to
these spans.
- In description lists, put each option on its own line, to make them more
searchable and enable automatic translation of the options.
Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
- Use _<placeholder>_ instead of <placeholder> in the description
- Use `backticks` for keywords and more complex option
descriptions. The new rendering engine will apply synopsis rules to
these spans.
For all the formats in the form of %(foo), the formatting needs to be
heavier because we not want the parentheses to be rendered as syntax
elements,but as keywords, i.e. we need to circumvent the syntax highlighting
of synopsis. In this particular case, this requires the heavy escaping of
the parts that contain parentheses with ++.
Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
- Use _<placeholder>_ instead of <placeholder> in the description
- Use `backticks` for keywords and more complex option
descriptions. The new rendering engine will apply synopsis rules to
these spans.
Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
- Fix some malformed synopis of options
- Use _<placeholder>_ instead of <placeholder> in the description
- Use `backticks` for keywords and more complex option
descriptions. The new rendering engine will apply synopsis rules to
these spans.
- Add the '%' sign to the characters of keywords.
Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
- Use _<placeholder>_ instead of <placeholder> in the description
- Use `backticks` for keywords and more complex option
descriptions. The new rendering engine will apply synopsis rules to
these spans.
Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
format placeholders in italics and keywords in monospace
- Use _<placeholder>_ instead of <placeholder> in the description
- Use `backticks` for keywords and more complex option
descriptions. The new rendering engine will apply synopsis rules to
these spans.
Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
Use `backticks` for commit ranges. The new rendering engine will apply
synopsis rules to these spans.
Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
- Switch the synopsis to a synopsis block which will automatically
format placeholders in italics and keywords in monospace
- Use _<placeholder>_ instead of <placeholder> in the description
- Use `backticks` for keywords and more complex option
descriptions. The new rendering engine will apply synopsis rules to
these spans.
We also transform inline descriptions of possible values of option
--decorate into a list, which is more readable and extensible.
Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
Detaching the filename string from the tempfile structure used to cause
delete_tempfile() to fail and the temporary file was not cleaned up.
While it's possible to get rid of the allocation and copy from
xstrdup(), it keeps the code symetric with the other branch since
interpolate_path() also allocates and ssh_signing_key_file is freed
in both cases.
The exisiting test was updated to check if the temporary files are
properly deleted. To prevent TMPDIR from leaking into the other tests, a
new subshell is created, however this prevents test_config from working.
The cleanup of the config changed in the subshell is done by
test_unconfig in a call to test_when_finished outside of it.
Helped-by: brian m. carlson <sandals@crustytoothpaste.net>
Helped-by: Patrick Steinhardt <ps@pks.im>
Helped-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: redoste <redoste@redoste.xyz>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
The calls to sysctl() assume a 64-bit memory size for the variable
holding the value, but the actual size depends on the key name and
platform, at least for HW_PHYSMEM.
Detect any mismatched reads, and retry with a shorter variable
when needed.
Signed-off-by: Carlo Marcelo Arenas Belón <carenas@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
In 6aec8d38fdd (t: refactor tests depending on Perl to print data,
2025-04-03) we have changed some of the tests in t4150 to use sed(1)
instead of Perl. One of the conversions is broken though:
sed: -e expression #1, char 41: unterminated `s' command
Curiously enough, the test itself still passes. This is caused by a
sequence of failures:
1. The output of sed(1) is piped into git-update-ref(1), and because
sed(1) is the upstream command we don't notice that it fails.
2. git-update-ref(1) does not receive any input and thus won't create
any references.
3. We then repack the repository with the configured pseudo merges
pattern, but as we didn't create any references the pattern doesn't
match anything.
4. We use `test_pseudo_merges()` to compute the list of pseudo-merges
and write it into a file. This file is empty as there are none.
5. The loop over the pseudo-merges becomes a no-op.
6. The final test succeeds as well because the number of lines in an
empty file is obviously the same as the number of unique lines,
namely zero.
Fix the issue by adding the terminating '|' to the sed(1) command.
Furthermore, make the test a tiny bit more robust by not using it as
part of a pipe.
Reported-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
In 6aec8d38fdd (t: refactor tests depending on Perl to print data,
2025-04-03) we have changed one of the tests in t4150 to use awk(1)
instead of Perl. The test works, but at least gawk(1) prints a warning
now:
awk: cmd. line:3: warning: escape sequence `\@' treated as plain `@'
Fix this by removing the backslash.
Reported-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
Documentation for git-merge incorrectly notes that
tip of the current branch on ascii diagram is C,
while it is actually G (current branch is master,
HEAD on diagram is G).
Additionally diagrams on the page are adjusted
to use spaces instead of tabs, so that they align
regardless of tab size. This is in line with
diagrams on other git documentation pages.
Signed-off-by: Timur Sultanaev <str.write@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
Commit 50dec7c566 ("config.mak.uname: add sysinfo() configuration for
cygwin", 2025-04-17) and later commit 187ce0222f ("configure.ac: upgrade
to a compilation check for sysinfo", 2025-05-19) added a 'sysinfo()'
check to the autoconf build.
The FreeBSD system has an optional sysinfo compatibility library, used
to assist in porting software, which causes the build to fail when it
is installed. The reason for the failure is the lack of '-lsysinfo'
during the linking step.
Several solutions were considered:
- add a 'linking' check to configure.ac in order to determine the
need to link a separate library (-lsysinfo). (This would require
a similar change to meson.build).
- change the order of the preprocessor conditionals in the total_ram()
function in 'builtin/gc.c', so that the *BSD sysctl() function
(in the HAVE_BSD_SYSCTL block) takes priority over the sysinfo()
function (in the HAVE_SYSINFO block).
- suppress the setting of HAVE_SYSINFO when HAVE_BSD_SYSCTL has been
defined (in both configure.ac and meson.build).
The first solution above, while simple, adds unnecessary code (the
sysinfo compat function is likely implemented using sysctl() anyway)
when git is happy to use sysctl() on *BSD systems.
The second solution would only be required by the autoconf and meson
build systems, the Makefile already sets the build variables to the
required values (since they are not 'auto-detected').
Here we opt for the final solution above, since it only requires that
we prioritise the 'auto-detected' build variables in the autoconf and
meson builds.
In order to fix the FreeBSD build, move the sysinfo() check after the
determination of the HAVE_BSD_SYSCTL build variable, suppressing the
setting of HAVE_SYSINFO if HAVE_BSD_SYSCTL is defined. Apply this logic
to both the configure.ac and meson.build file.
[Thanks go to Renato Botelho <garga@FreeBSD.org> for testing this patch
on FreeBSD.]
Tested-by: Renato Botelho <garga@FreeBSD.org>
Signed-off-by: Ramsay Jones <ramsay@ramsayjones.plus.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
Refactor builtin/prune.c to remove the dependency on the global
'the_repository'. Replace all the occurrences of 'the_repository' with
repo and thus remove the definition '#define
USE_THE_REPOSITORY_VARIABLE'. Also, add a test to make sure that 'git
prune -h' can be called when the repository is `NULL`.
Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Ghanshyam Thakkar <shyamthakkar001@gmail.com>
Signed-off-by: Ayush Chandekar <ayu.chandekar@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|