Go to file
Jeff King b92387cd55 http: handle absolute-path alternates from server root
When a dumb http server reports alternates with an absolute path, we try
to paste that onto the root of the URL we're trying to fetch from. So if
we go to "http://example.com/path/to/child.git" and it tells us about an
alternate at "/parent.git", we'll hit "http://example.com/parent.git".

But there's a bug in computing the base when the URL does not have any
path component at all, like "http://example.com". When looking for the
first slash after the host, strchr() returns NULL, and we compute a
nonsense value for the length of the host portion. And then when we use
that length to copy the base of the URL into a strbuf, we're likely to
fail.

The security implications are minimal here. We store the nonsense length
("serverlen") as an int, so on a 64-bit system it may effectively be
anything (it is zero minus a 64-bit heap pointer, then truncated to
32-bits and stuffed into a signed value). When we feed that length to
strbuf_add(), it is cast into a size_t and one of four things will
happen:

  1. If serverlen was negative, it will turn into a very large positive
     value and strbuf_add() will fail to allocate, ending the program.
     Ditto if serverlen was positive but just very large.

     This doesn't really get an attacker anything; the victim will just
     fail to clone their evil repo.

  2. If serverlen was small enough, we'll successfully extend the target
     strbuf, and then copy an arbitrary set of bytes from "base". And
     then one of these is true:

       a. That set of bytes is much larger than the length of the "base"
          string. This is an out-of-bounds read, but there's no
          out-of-bounds write, since the strbuf code both allocates and
          copies using the same size_t. This is likely to cause a
          segfault as we try to read unmapped pages of memory.

       b. Like (2a), but if the set of bytes is small enough we might
          not segfault. We might read random memory from the process and
          copy it into the "target" strbuf.

          What happens then? We know that "base" ends with a NUL
          terminator, which will be copied into "target" as well. So
          even though target.len might be 1000 bytes (or whatever), when
          interpreted as a NUL-terminated string, target.buf is still
          the exact same string as "base".

          And that's all we ever do with target: pass it around as a C
          string, and then eventually strbuf_detach() it to become a C
          string. So even though there was arbitrary memory copied into
          the strbuf, we never access it.

       c. The other interesting case is when serverlen is actually
          _shorter_ than the length of base. And there we truncate the
          string. Probably in a way that makes it totally invalid, but
          if you were very unlucky you could turn something like:

             http://victim.com.evil.domain:8000

          into:

            http://victim.com

	  Which looks like the start of a redirect attack, except that
	  the attacker could just have written "http://victim.com" in
	  the first place! Either way we feed it to
	  is_alternate_allowed(), which is where we check redirect and
	  protocol rules.

I think we can just treat this like a regular bug.

And it's quite a weird setup in the first place, as it implies that the
root of the web server is serving a repository (i.e., that you can get
something useful from "http://example.com/info/refs"). The bug has been
there since b3661567cf ([PATCH] Add support for alternates in HTTP,
2005-09-14) without anybody noticing.

I kind of doubt anybody really cares about making this work, but it's
easy enough to do so: the host-portion of the URL ends at either the
first slash or the end-of-string. So we can just replace strchr() with
strchrnul().

The test setup is a little gross, as we take over the httpd document
root by shoving our bare-repo components into it. But it demonstrates
the problem and shows that our solution actually allows the alternate to
function, if the server is configured to allow it.

Reported-by: slonkazoid <slonkazoid@slonk.ing>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-13 09:47:50 +09:00
.github Merge branch 'js/ci-show-breakage-in-dockerized-jobs' 2025-12-05 14:49:58 +09:00
Documentation RelNotes: fully spell negation 2026-02-01 18:07:39 -08:00
bin-wrappers
block-sha1
builtin Merge branch 'rs/tree-wo-the-repository' 2026-01-21 16:16:28 -08:00
ci Merge branch 'js/ci-leak-skip-svn' 2026-01-23 13:34:36 -08:00
compat Merge branch 'js/symlink-windows' 2026-01-23 13:34:37 -08:00
compiler-tricks
contrib Revert "Merge branch 'cs/rebased-subtree-split'" 2026-01-25 22:37:35 -08:00
ewah git-compat-util: introduce MEMZERO_ARRAY() macro 2025-12-11 14:44:43 +09:00
git-gui Merge branch 'master' of https://github.com/j6t/git-gui 2026-01-25 09:08:06 -08:00
gitk-git
gitweb
mergetools
negotiator
odb packfile: move packfile store into object source 2026-01-09 06:40:07 -08:00
oss-fuzz
perl
po Merge branch 'jx/zh_CN' of github.com:jiangxin/git 2026-01-31 21:32:54 +08:00
refs refs/reftable: introduce generic checks for refs 2026-01-12 06:55:41 -08:00
reftable
sha1
sha1collisiondetection@855827c583
sha1dc
sha256
src rust: build correctly without GNU sed 2025-12-19 17:57:26 +09:00
subprojects meson: ignore subprojects/.wraplock 2025-12-05 11:11:00 +09:00
t http: handle absolute-path alternates from server root 2026-05-13 09:47:50 +09:00
templates
trace2
xdiff Merge branch 'yc/xdiff-patience-optim' 2025-12-09 07:54:55 +09:00
.cirrus.yml
.clang-format
.editorconfig
.gitattributes git-gui: mark *.po files at any directory level as UTF-8 2026-01-25 10:53:08 +01:00
.gitignore
.gitlab-ci.yml
.gitmodules
.mailmap Merge branch 'pw/mailmap-self' 2026-01-23 13:34:36 -08:00
.tsan-suppressions
CODE_OF_CONDUCT.md
COPYING
Cargo.toml
GIT-BUILD-OPTIONS.in
GIT-VERSION-FILE.in
GIT-VERSION-GEN Git 2.53 2026-02-01 18:15:01 -08:00
INSTALL
LGPL-2.1
Makefile utf8.c: enable workaround for iconv under macOS 14/15 2026-01-12 12:00:39 -08:00
README.md
RelNotes
SECURITY.md
abspath.c
abspath.h
aclocal.m4
add-interactive.c add-interactive: use repo_parse_tree_indirect() 2026-01-09 18:36:16 -08:00
add-interactive.h
add-patch.c
advice.c
advice.h
alias.c
alias.h
alloc.c
alloc.h
apply.c Merge branch 'js/test-symlink-windows' 2025-12-30 12:58:19 +09:00
apply.h
archive-tar.c
archive-zip.c
archive.c cocci: convert parse_tree functions to repo_ variants 2026-01-09 18:36:18 -08:00
archive.h
attr.c
attr.h
banned.h banned.h: ban mktemp(3) 2025-12-07 07:28:13 +09:00
base85.c
base85.h
bisect.c
bisect.h
blame.c
blame.h
blob.c
blob.h
bloom.c bloom: use repo_parse_tree() 2026-01-09 18:36:16 -08:00
bloom.h
branch.c branch: advice using git-help(1) instead of man(1) 2025-12-03 00:16:05 -08:00
branch.h
builtin.h builtin.h: update documentation 2026-01-09 06:37:02 -08:00
bundle-uri.c bundle-uri: validate that bundle entries have a uri 2025-12-20 14:45:27 +09:00
bundle-uri.h
bundle.c
bundle.h
cache-tree.c cocci: convert parse_tree functions to repo_ variants 2026-01-09 18:36:18 -08:00
cache-tree.h
cbtree.c
cbtree.h
chdir-notify.c
chdir-notify.h
check-builtins.sh
checkout.c
checkout.h
chunk-format.c
chunk-format.h
color.c
color.h
column.c
column.h
combine-diff.c
command-list.txt
commit-graph.c Merge branch 'ps/read-object-info-improvements' 2026-01-21 08:29:00 -08:00
commit-graph.h
commit-reach.c commit-reach: use commit_stack 2025-12-25 08:29:29 +09:00
commit-reach.h
commit-slab-decl.h
commit-slab-impl.h
commit-slab.h
commit.c Revert "Merge branch 'ar/run-command-hook'" 2026-01-15 13:02:38 -08:00
commit.h commit: add commit_stack_grow() 2025-12-25 08:29:28 +09:00
common-exit.c
common-init.c
common-init.h
common-main.c
config.c Merge branch 'rs/parse-config-expiry-simplify' 2026-01-06 16:33:53 +09:00
config.h
config.mak.dev
config.mak.in
config.mak.uname utf8.c: enable workaround for iconv under macOS 14/15 2026-01-12 12:00:39 -08:00
configure.ac
connect.c connect: plug protocol capability leak 2025-12-09 07:11:42 +09:00
connect.h
connected.c
connected.h
convert.c
convert.h
copy.c
copy.h
credential.c
credential.h
csum-file.c
csum-file.h
ctype.c
daemon.c
date.c
date.h
decorate.c
decorate.h
delta-islands.c delta-islands: use repo_parse_tree() 2026-01-09 18:36:17 -08:00
delta-islands.h
delta.h
detect-compiler
diagnose.c
diagnose.h
diff-delta.c git-compat-util: introduce MEMZERO_ARRAY() macro 2025-12-11 14:44:43 +09:00
diff-lib.c cocci: convert parse_tree functions to repo_ variants 2026-01-09 18:36:18 -08:00
diff-merges.c
diff-merges.h
diff-no-index.c
diff.c diff: avoid segfault with freed entries 2025-12-30 10:53:47 +09:00
diff.h Merge branch 'rs/diff-index-find-copies-harder-optim' 2025-12-14 17:04:36 +09:00
diffcore-break.c
diffcore-delta.c cocci: use MEMZERO_ARRAY() a bit more 2025-12-13 10:47:59 +09:00
diffcore-order.c
diffcore-pickaxe.c
diffcore-rename.c
diffcore-rotate.c
diffcore.h
dir-iterator.c
dir-iterator.h
dir.c
dir.h
editor.c
editor.h
entry.c
entry.h
environment.c Merge branch 'rs/tree-wo-the-repository' 2026-01-21 16:16:28 -08:00
environment.h Merge branch 'rs/tree-wo-the-repository' 2026-01-21 16:16:28 -08:00
exec-cmd.c
exec-cmd.h
fetch-negotiator.c
fetch-negotiator.h
fetch-pack.c Merge branch 'jc/optional-path' 2025-12-05 14:49:56 +09:00
fetch-pack.h
fmt-merge-msg.c
fmt-merge-msg.h
for-each-ref.h
fsck.c Merge branch 'rs/tree-wo-the-repository' 2026-01-21 16:16:28 -08:00
fsck.h builtin/fsck: move generic HEAD check into `refs_fsck()` 2026-01-12 06:55:41 -08:00
fsmonitor--daemon.h
fsmonitor-ipc.c
fsmonitor-ipc.h
fsmonitor-ll.h
fsmonitor-path-utils.h
fsmonitor-settings.c
fsmonitor-settings.h
fsmonitor.c
fsmonitor.h
generate-cmdlist.sh
generate-configlist.sh
generate-hooklist.sh
generate-perl.sh
generate-python.sh
generate-script.sh
gettext.c
gettext.h
git-archimport.perl
git-compat-util.h environment: move access to core.maxTreeDepth into repo settings 2026-01-09 18:36:16 -08:00
git-curl-compat.h
git-cvsexportcommit.perl
git-cvsimport.perl
git-cvsserver.perl
git-difftool--helper.sh
git-filter-branch.sh
git-instaweb.sh
git-merge-octopus.sh
git-merge-one-file.sh
git-merge-resolve.sh
git-mergetool--lib.sh
git-mergetool.sh
git-p4.py
git-quiltimport.sh
git-request-pull.sh
git-send-email.perl
git-sh-i18n.sh
git-sh-setup.sh
git-submodule.sh
git-svn.perl
git-web--browse.sh
git-zlib.c
git-zlib.h
git.c
git.rc.in
gpg-interface.c Merge branch 'cc/fast-import-strip-if-invalid' 2025-12-05 14:49:58 +09:00
gpg-interface.h Merge branch 'cc/fast-import-strip-if-invalid' 2025-12-05 14:49:58 +09:00
graph.c
graph.h
grep.c
grep.h
hash-lookup.c
hash-lookup.h
hash.c
hash.h
hashmap.c git-compat-util: introduce MEMZERO_ARRAY() macro 2025-12-11 14:44:43 +09:00
hashmap.h
help.c Merge branch 'jx/build-options-gettext' 2026-01-23 13:34:36 -08:00
help.h
hex-ll.c
hex-ll.h
hex.c
hex.h
hook.c Revert "Merge branch 'ar/run-command-hook'" 2026-01-15 13:02:38 -08:00
hook.h Revert "Merge branch 'ar/run-command-hook'" 2026-01-15 13:02:38 -08:00
http-backend.c Merge branch 'kt/http-backend-errors' 2026-01-21 08:28:58 -08:00
http-fetch.c
http-push.c cocci: convert parse_tree functions to repo_ variants 2026-01-09 18:36:18 -08:00
http-walker.c http: handle absolute-path alternates from server root 2026-05-13 09:47:50 +09:00
http.c packfile: move packfile store into object source 2026-01-09 06:40:07 -08:00
http.h
ident.c
ident.h
imap-send.c
iterator.h
json-writer.c
json-writer.h
khash.h
kwset.c
kwset.h
levenshtein.c
levenshtein.h
line-log.c
line-log.h
line-range.c
line-range.h
linear-assignment.c cocci: use MEMZERO_ARRAY() a bit more 2025-12-13 10:47:59 +09:00
linear-assignment.h
list-objects-filter-options.c
list-objects-filter-options.h
list-objects-filter.c
list-objects-filter.h
list-objects.c cocci: convert parse_tree functions to repo_ variants 2026-01-09 18:36:18 -08:00
list-objects.h
list.h
lockfile.c trim_last_path_component(): avoid hard-coding the directory separator 2026-01-09 18:28:37 -08:00
lockfile.h
log-tree.c
log-tree.h
loose.c
loose.h
ls-refs.c
ls-refs.h
mailinfo.c
mailinfo.h
mailmap.c
mailmap.h
match-trees.c
match-trees.h
mem-pool.c
mem-pool.h
merge-blobs.c
merge-blobs.h
merge-ll.c
merge-ll.h
merge-ort-wrappers.c
merge-ort-wrappers.h
merge-ort.c cocci: convert parse_tree functions to repo_ variants 2026-01-09 18:36:18 -08:00
merge-ort.h
merge.c cocci: convert parse_tree functions to repo_ variants 2026-01-09 18:36:18 -08:00
merge.h
mergesort.h
meson.build Merge branch 'rs/ban-mktemp' 2025-12-16 11:08:35 +09:00
meson_options.txt
midx-write.c Merge branch 'tb/midx-write-corrupt-checksum-fix' 2026-01-21 16:16:27 -08:00
midx.c Merge branch 'ps/packfile-store-in-odb-source' 2026-01-21 08:28:59 -08:00
midx.h
name-hash.c
name-hash.h
notes-cache.c
notes-cache.h
notes-merge.c
notes-merge.h
notes-utils.c
notes-utils.h
notes.c
notes.h
object-file-convert.c
object-file-convert.h
object-file.c object-file: always set OI_LOOSE when reading object info 2026-01-12 06:51:14 -08:00
object-file.h
object-name.c tag: support arbitrary repositories in parse_tag() 2025-12-29 22:02:54 +09:00
object-name.h
object.c object: apply skip_hash and discard_tree optimizations to unknown blobs too 2025-12-09 18:12:24 +09:00
object.h
odb.c Merge branch 'ps/packfile-store-in-odb-source' 2026-01-21 08:28:59 -08:00
odb.h Merge branch 'ps/read-object-info-improvements' 2026-01-21 08:29:00 -08:00
oid-array.c
oid-array.h
oidmap.c
oidmap.h
oidset.c
oidset.h
oidtree.c
oidtree.h
pack-bitmap-write.c Merge branch 'rs/tree-wo-the-repository' 2026-01-21 16:16:28 -08:00
pack-bitmap.c packfile: drop repository parameter from `packed_object_info()` 2026-01-12 06:51:15 -08:00
pack-bitmap.h
pack-check.c
pack-mtimes.c
pack-mtimes.h
pack-objects.c
pack-objects.h
pack-refs.c
pack-refs.h
pack-revindex.c git-compat-util: introduce MEMZERO_ARRAY() macro 2025-12-11 14:44:43 +09:00
pack-revindex.h midx: fix `BUG()` when getting preferred pack without a reverse index 2025-12-11 12:09:58 +09:00
pack-write.c
pack.h
packfile.c Merge branch 'ps/read-object-info-improvements' 2026-01-21 08:29:00 -08:00
packfile.h Merge branch 'ps/read-object-info-improvements' 2026-01-21 08:29:00 -08:00
pager.c
pager.h
parallel-checkout.c
parallel-checkout.h
parse-options-cb.c
parse-options.c
parse-options.h
parse.c
parse.h
patch-delta.c
patch-ids.c
patch-ids.h
path-walk.c path-walk: use repo_parse_tree_gently() 2026-01-09 18:36:17 -08:00
path-walk.h
path.c
path.h
pathspec.c
pathspec.h
pkt-line.c
pkt-line.h
preload-index.c
preload-index.h
pretty.c
pretty.h
prio-queue.c
prio-queue.h
progress.c
progress.h
promisor-remote.c
promisor-remote.h
prompt.c
prompt.h
protocol-caps.c
protocol-caps.h
protocol.c
protocol.h
prune-packed.c
prune-packed.h
pseudo-merge.c
pseudo-merge.h
quote.c
quote.h
range-diff.c
range-diff.h
reachable.c packfile: refactor kept-pack cache to work with packfile stores 2026-01-09 06:40:06 -08:00
reachable.h
read-cache-ll.h
read-cache.c Merge branch 'js/symlink-windows' 2026-01-23 13:34:37 -08:00
read-cache.h
rebase-interactive.c
rebase-interactive.h
rebase.c
rebase.h
ref-filter.c tag: support arbitrary repositories in parse_tag() 2025-12-29 22:02:54 +09:00
ref-filter.h
reflog-walk.c
reflog-walk.h
reflog.c
reflog.h
refs.c Merge branch 'ps/ref-consistency-checks' 2026-01-21 08:28:58 -08:00
refs.h refs/files: introduce function to perform normal ref checks 2026-01-12 06:55:41 -08:00
refspec.c
refspec.h
remote-curl.c
remote.c remote: use commit_stack for src_commits 2025-12-25 08:29:28 +09:00
remote.h
repack-cruft.c
repack-filtered.c
repack-geometry.c builtin/repack: handle promisor packs with geometric repacking 2026-01-14 06:29:24 -08:00
repack-midx.c
repack-promisor.c builtin/repack: handle promisor packs with geometric repacking 2026-01-14 06:29:24 -08:00
repack.c
repack.h builtin/repack: handle promisor packs with geometric repacking 2026-01-14 06:29:24 -08:00
replace-object.c
replace-object.h
repo-settings.c environment: move access to core.maxTreeDepth into repo settings 2026-01-09 18:36:16 -08:00
repo-settings.h environment: move access to core.maxTreeDepth into repo settings 2026-01-09 18:36:16 -08:00
repository.c Merge branch 'gf/clear-path-cache-cleanup' 2025-12-30 12:58:21 +09:00
repository.h
rerere.c
rerere.h
reset.c cocci: convert parse_tree functions to repo_ variants 2026-01-09 18:36:18 -08:00
reset.h
resolve-undo.c
resolve-undo.h
revision.c Merge branch 'rs/tree-wo-the-repository' 2026-01-21 16:16:28 -08:00
revision.h
run-command.c Revert "Merge branch 'ar/run-command-hook'" 2026-01-15 13:02:38 -08:00
run-command.h Revert "Merge branch 'ar/run-command-hook'" 2026-01-15 13:02:38 -08:00
sane-ctype.h
scalar.c Merge branch 'ds/doc-scalar-config' 2025-12-23 11:33:15 +09:00
send-pack.c
send-pack.h
sequencer.c Merge branch 'rs/tree-wo-the-repository' 2026-01-21 16:16:28 -08:00
sequencer.h
serve.c
serve.h
server-info.c
server-info.h
setup.c init: do parse _all_ core.* settings early 2026-01-09 18:28:36 -08:00
setup.h
sh-i18n--envsubst.c
sha1dc_git.c
sha1dc_git.h
shallow.c shallow: use commit_stack 2025-12-25 08:29:28 +09:00
shallow.h shallow: use commit_stack 2025-12-25 08:29:28 +09:00
shared.mak
shell.c
shortlog.h
sideband.c
sideband.h
sigchain.c
sigchain.h
simple-ipc.h
sparse-index.c
sparse-index.h
split-index.c
split-index.h
stable-qsort.c
statinfo.c
statinfo.h
strbuf.c Merge branch 'js/prep-symlink-windows' 2026-01-21 08:29:00 -08:00
strbuf.h builtin/repo: add inflated object info to structure table 2025-12-18 09:02:31 +09:00
string-list.c
string-list.h
strmap.c
strmap.h
strvec.c
strvec.h
sub-process.c
sub-process.h
submodule-config.c
submodule-config.h
submodule.c
submodule.h
symlinks.c
symlinks.h
tag.c tag: stop using the_repository 2025-12-29 22:02:54 +09:00
tag.h tag: support arbitrary repositories in parse_tag() 2025-12-29 22:02:54 +09:00
tar.h
tempfile.c
tempfile.h
thread-utils.c
thread-utils.h
tmp-objdir.c
tmp-objdir.h
trace.c
trace.h
trace2.c
trace2.h
trailer.c
trailer.h
transport-helper.c
transport-internal.h
transport.c Revert "Merge branch 'ar/run-command-hook'" 2026-01-15 13:02:38 -08:00
transport.h
tree-diff.c environment: move access to core.maxTreeDepth into repo settings 2026-01-09 18:36:16 -08:00
tree-walk.c environment: move access to core.maxTreeDepth into repo settings 2026-01-09 18:36:16 -08:00
tree-walk.h
tree.c tree: stop using the_repository 2026-01-09 18:36:17 -08:00
tree.h tree: stop using the_repository 2026-01-09 18:36:17 -08:00
unicode-width.h
unimplemented.sh
unix-socket.c
unix-socket.h
unix-stream-server.c
unix-stream-server.h
unpack-trees.c
unpack-trees.h
upload-pack.c
upload-pack.h
url.c
url.h
urlmatch.c
urlmatch.h
usage.c
userdiff.c
userdiff.h
utf8.c utf8.c: prepare workaround for iconv under macOS 14/15 2026-01-12 12:00:04 -08:00
utf8.h
varint.c
varint.h
version-def.h.in
version.c
version.h
versioncmp.c
versioncmp.h
walker.c cocci: convert parse_tree functions to repo_ variants 2026-01-09 18:36:18 -08:00
walker.h
wildmatch.c
wildmatch.h
worktree.c
worktree.h
wrapper.c Merge branch 'rs/ban-mktemp' 2025-12-16 11:08:35 +09:00
wrapper.h wrapper: add git_mkdtemp() 2025-12-07 07:28:11 +09:00
write-or-die.c
write-or-die.h
ws.c
ws.h
wt-status.c
wt-status.h
xdiff-interface.c
xdiff-interface.h

README.md

Build status

Git - fast, scalable, distributed revision control system

Git is a fast, scalable, distributed revision control system with an unusually rich command set that provides both high-level operations and full access to internals.

Git is an Open Source project covered by the GNU General Public License version 2 (some parts of it are under different licenses, compatible with the GPLv2). It was originally written by Linus Torvalds with help of a group of hackers around the net.

Please read the file INSTALL for installation instructions.

Many Git online resources are accessible from https://git-scm.com/ including full documentation and Git related tools.

See Documentation/gittutorial.adoc to get started, then see Documentation/giteveryday.adoc for a useful minimum set of commands, and Documentation/git-<commandname>.adoc for documentation of each command. If git has been correctly installed, then the tutorial can also be read with man gittutorial or git help tutorial, and the documentation of each command with man git-<commandname> or git help <commandname>.

CVS users may also want to read Documentation/gitcvs-migration.adoc (man gitcvs-migration or git help cvs-migration if git is installed).

The user discussion and development of Git take place on the Git mailing list -- everyone is welcome to post bug reports, feature requests, comments and patches to git@vger.kernel.org (read Documentation/SubmittingPatches for instructions on patch submission and Documentation/CodingGuidelines).

Those wishing to help with error message, usage and informational message string translations (localization l10) should see po/README.md (a po file is a Portable Object file that holds the translations).

To subscribe to the list, send an email to git+subscribe@vger.kernel.org (see https://subspace.kernel.org/subscribing.html for details). The mailing list archives are available at https://lore.kernel.org/git/, https://marc.info/?l=git and other archival sites.

Issues which are security relevant should be disclosed privately to the Git Security mailing list git-security@googlegroups.com.

The maintainer frequently sends the "What's cooking" reports that list the current status of various development topics to the mailing list. The discussion following them give a good reference for project status, development direction and remaining tasks.

The name "git" was given by Linus Torvalds when he wrote the very first version. He described the tool as "the stupid content tracker" and the name as (depending on your mood):

  • random three-letter combination that is pronounceable, and not actually used by any common UNIX command. The fact that it is a mispronunciation of "get" may or may not be relevant.
  • stupid. contemptible and despicable. simple. Take your pick from the dictionary of slang.
  • "global information tracker": you're in a good mood, and it actually works for you. Angels sing, and a light suddenly fills the room.
  • "goddamn idiotic truckload of sh*t": when it breaks