Go to file
Jeff King 7dbabbbebe pack-objects: enforce --depth limit in reused deltas
Since 898b14c (pack-objects: rework check_delta_limit usage,
2007-04-16), we check the delta depth limit only when
figuring out whether we should make a new delta. We don't
consider it at all when reusing deltas, which means that
packing once with --depth=250, and then again with
--depth=50, the second pack may still contain chains larger
than 50.

This is generally considered a feature, as the results of
earlier high-depth repacks are carried forward, used for
serving fetches, etc. However, since we started using
cross-pack deltas in c9af708b1 (pack-objects: use mru list
when iterating over packs, 2016-08-11), we are no longer
bounded by the length of an existing delta chain in a single
pack.

Here's one particular pathological case: a sequence of N
packs, each with 2 objects, the base of which is stored as a
delta in a previous pack. If we chain all the deltas
together, we have a cycle of length N. We break the cycle,
but the tip delta is still at depth N-1.

This is less unlikely than it might sound. See the included
test for a reconstruction based on real-world actions.  I
ran into such a case in the wild, where a client was rapidly
sending packs, and we had accumulated 10,000 before doing a
server-side repack.  The pack that "git repack" tried to
generate had a very deep chain, which caused pack-objects to
run out of stack space in the recursive write_one().

This patch bounds the length of delta chains in the output
pack based on --depth, regardless of whether they are caused
by cross-pack deltas or existed in the input packs. This
fixes the problem, but does have two possible downsides:

  1. High-depth aggressive repacks followed by "normal"
     repacks will throw away the high-depth chains.

     In the long run this is probably OK; investigation
     showed that high-depth repacks aren't actually
     beneficial, and we dropped the aggressive depth default
     to match the normal case in 07e7dbf0d (gc: default
     aggressive depth to 50, 2016-08-11).

  2. If you really do want to store high-depth deltas on
     disk, they may be discarded and new delta computed when
     serving a fetch, unless you set pack.depth to match
     your high-depth size.

The implementation uses the existing search for delta
cycles.  That lets us compute the depth of any node based on
the depth of its base, because we know the base is DFS_DONE
by the time we look at it (modulo any cycles in the graph,
but we know there cannot be any because we break them as we
see them).

There is some subtlety worth mentioning, though. We record
the depth of each object as we compute it. It might seem
like we could save the per-object storage space by just
keeping track of the depth of our traversal (i.e., have
break_delta_chains() report how deep it went). But we may
visit an object through multiple delta paths, and on
subsequent paths we want to know its depth immediately,
without having to walk back down to its final base (doing so
would make our graph walk quadratic rather than linear).

Likewise, one could try to record the depth not from the
base, but from our starting point (i.e., start
recursion_depth at 0, and pass "recursion_depth + 1" to each
invocation of break_delta_chains()). And then when
recursion_depth gets too big, we know that we must cut the
delta chain.  But that technique is wrong if we do not visit
the nodes in topological order. In a chain A->B->C, it
if we visit "C", then "B", then "A", we will never recurse
deeper than 1 link (because we see at each node that we have
already visited it).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-01-27 16:24:44 -08:00
Documentation Almost ready for 2.11.1 2017-01-17 15:19:11 -08:00
block-sha1
builtin pack-objects: enforce --depth limit in reused deltas 2017-01-27 16:24:44 -08:00
ci
compat Merge branch 'mk/mingw-winansi-ttyname-termination-fix' into maint 2017-01-17 15:19:03 -08:00
contrib Merge branch 'ls/filter-process' into maint 2017-01-17 15:19:08 -08:00
ewah
git-gui git-gui 0.21.0 2016-10-20 09:33:17 -07:00
gitk-git
gitweb Merge branch 'ab/gitweb-abbrev-links' 2016-10-26 13:14:46 -07:00
mergetools Merge branch 'da/mergetool-xxdiff-hotkey' into maint 2017-01-17 15:11:05 -08:00
perl Merge branch 'mm/send-email-cc-cruft-after-address' into maint 2016-11-29 13:27:55 -08:00
po Merge branch 'russian-l10n' of https://github.com/DJm00n/git-po-ru 2016-11-29 21:19:43 +08:00
ppc
refs Merge branch 'jk/ref-symlink-loop' 2016-10-17 13:25:20 -07:00
t pack-objects: enforce --depth limit in reused deltas 2017-01-27 16:24:44 -08:00
templates pre-receive.sample: mark it executable 2016-10-28 14:21:11 -07:00
vcs-svn Merge branch 'mr/vcs-svn-printf-ulong' into maint 2016-09-29 16:49:37 -07:00
xdiff Merge branch 'mh/diff-indent-heuristic' 2016-10-03 13:30:38 -07:00
.gitattributes
.gitignore Merge branch 'bb/unicode-9.0' into maint 2017-01-17 14:49:25 -08:00
.mailmap add David Turner's Two Sigma address 2016-09-26 17:46:44 -07:00
.travis.yml travis-ci: update P4 to 16.2 and GitLFS to 1.5.2 in Linux build 2016-12-05 14:55:52 -08:00
COPYING
GIT-VERSION-GEN Almost ready for 2.11.1 2017-01-17 15:19:11 -08:00
INSTALL
LGPL-2.1
Makefile Merge branch 'ls/macos-update' into maint 2016-11-29 13:27:56 -08:00
README.md README: replace gmane link with public-inbox 2016-12-15 09:30:09 -08:00
RelNotes Almost ready for 2.11.1 2017-01-17 15:19:11 -08:00
abspath.c
aclocal.m4
advice.c
advice.h
alias.c
alloc.c
apply.c i18n: apply: mark error message for translation 2016-10-17 14:51:42 -07:00
apply.h apply: learn to use a different index file 2016-09-07 12:29:54 -07:00
archive-tar.c
archive-zip.c
archive.c archive: read local configuration 2016-11-22 13:55:20 -08:00
archive.h archive: read local configuration 2016-11-22 13:55:20 -08:00
argv-array.c
argv-array.h
attr.c read info/{attributes,exclude} only when in repository 2016-10-26 13:30:51 -07:00
attr.h
base85.c
bisect.c use QSORT 2016-09-29 15:42:18 -07:00
bisect.h
blob.c
blob.h
branch.c worktree.c: get_worktrees() takes a new flag argument 2016-11-28 13:18:51 -08:00
branch.h create_branch: drop unused "head" parameter 2016-11-09 14:56:21 -08:00
builtin.h builtin: convert textconv_object to use struct object_id 2016-09-07 12:59:42 -07:00
bulk-checkin.c
bulk-checkin.h
bundle.c
bundle.h
cache-tree.c cache: convert struct cache_entry to use struct object_id 2016-09-07 12:59:42 -07:00
cache-tree.h
cache.h Merge branch 'ls/git-open-cloexec' 2016-10-31 13:15:21 -07:00
check-builtins.sh
check-racy.c
check_bindir
color.c Merge branch 'jk/squelch-false-warning-from-gcc-o3' into maint 2016-09-19 13:51:41 -07:00
color.h
column.c
column.h
combine-diff.c diff_aligned_abbrev: use "struct oid" 2016-10-26 13:30:51 -07:00
command-list.txt
commit-slab.h
commit.c Merge branch 'rs/copy-array' into maint 2016-10-11 14:18:32 -07:00
commit.h Merge branch 'nd/shallow-deepen' 2016-10-10 14:03:50 -07:00
common-main.c common-main: stop munging argv[0] path 2016-11-29 11:01:48 -08:00
config.c get_short_sha1: make default disambiguation configurable 2016-09-27 10:29:56 -07:00
config.mak.in
config.mak.uname
configure.ac Merge branch 'dp/autoconf-curl-ssl' into maint 2016-10-28 09:01:13 -07:00
connect.c Merge branch 'ls/filter-process' 2016-10-31 13:15:21 -07:00
connect.h
connected.c check_connected: accept an env argument 2016-10-10 13:54:02 -07:00
connected.h check_connected: accept an env argument 2016-10-10 13:54:02 -07:00
convert.c Merge branch 'jc/renormalize-merge-kill-safer-crlf' into maint 2017-01-17 14:49:28 -08:00
convert.h
copy.c
credential-cache--daemon.c i18n: credential-cache--daemon: mark advice for translation 2016-10-17 14:51:47 -07:00
credential-cache.c
credential-store.c
credential.c
credential.h
csum-file.c
csum-file.h
ctype.c
daemon.c Merge branch 'jk/daemon-path-ok-check-truncation' into maint 2016-11-29 13:27:56 -08:00
date.c
decorate.c
decorate.h
delta.h
diff-delta.c
diff-lib.c commit: fix empty commit creation when there's no changes but ita entries 2016-10-24 10:48:23 -07:00
diff-no-index.c Merge branch 'jk/setup-sequence-update' 2016-09-21 15:15:24 -07:00
diff.c diff: handle --no-abbrev in no-index case 2016-12-08 14:40:30 -08:00
diff.h Merge branch 'nd/ita-empty-commit' 2016-10-27 14:58:50 -07:00
diffcore-break.c Merge branch 'tk/diffcore-delta-remove-unused' into maint 2016-11-29 13:28:03 -08:00
diffcore-delta.c Merge branch 'tk/diffcore-delta-remove-unused' 2016-11-17 13:45:22 -08:00
diffcore-order.c use QSORT 2016-09-29 15:42:18 -07:00
diffcore-pickaxe.c Merge branch 'js/regexec-buf' into maint 2016-09-29 16:49:45 -07:00
diffcore-rename.c Merge branch 'tk/diffcore-delta-remove-unused' into maint 2016-11-29 13:28:03 -08:00
diffcore.h Merge branch 'tk/diffcore-delta-remove-unused' into maint 2016-11-29 13:28:03 -08:00
dir-iterator.c
dir-iterator.h
dir.c read info/{attributes,exclude} only when in repository 2016-10-26 13:30:51 -07:00
dir.h ls-files: add pathspec matching for submodules 2016-10-10 12:14:58 -07:00
editor.c
entry.c streaming: make stream_blob_to_fd take struct object_id 2016-09-07 12:59:42 -07:00
environment.c Merge branch 'lt/abbrev-auto' 2016-10-27 14:58:47 -07:00
exec_cmd.c common-main: stop munging argv[0] path 2016-11-29 11:01:48 -08:00
exec_cmd.h common-main: stop munging argv[0] path 2016-11-29 11:01:48 -08:00
fast-import.c use QSORT 2016-09-29 15:42:18 -07:00
fetch-pack.c fetch-pack.c: correct command at the beginning of an error message 2016-11-11 13:28:39 -08:00
fetch-pack.h
fmt-merge-msg.h
fsck.c fsck: handle bad trees like other errors 2016-09-27 14:09:10 -07:00
fsck.h
generate-cmdlist.sh
gettext.c
gettext.h
git-add--interactive.perl diff: improve positioning of add/delete blocks in diffs 2016-09-19 10:25:11 -07:00
git-archimport.perl
git-bisect.sh
git-compat-util.h Merge branch 'jk/common-main' into maint-2.10 2016-12-05 11:24:28 -08:00
git-cvsexportcommit.perl
git-cvsimport.perl
git-cvsserver.perl
git-difftool--helper.sh
git-difftool.perl Merge branch 'jk/difftool-in-subdir' into maint 2017-01-17 15:14:40 -08:00
git-filter-branch.sh
git-instaweb.sh
git-merge-octopus.sh git-merge-octopus: do not capitalize "octopus" 2016-09-08 12:17:10 -07:00
git-merge-one-file.sh
git-merge-resolve.sh
git-mergetool--lib.sh mergetool: honor mergetool.$tool.trustExitCode for built-in tools 2016-11-29 10:54:03 -08:00
git-mergetool.sh mergetool: honor -O<orderfile> 2016-10-11 10:04:31 -07:00
git-p4.py Merge branch 'gv/p4-multi-path-commit-fix' into maint 2017-01-17 15:19:02 -08:00
git-parse-remote.sh
git-quiltimport.sh
git-rebase--am.sh
git-rebase--interactive.sh Merge branch 'js/rebase-i-commentchar-fix' 2016-11-23 11:23:17 -08:00
git-rebase--merge.sh
git-rebase.sh
git-relink.perl
git-remote-testgit.sh
git-request-pull.sh
git-send-email.perl
git-sh-i18n.sh
git-sh-setup.sh git-sh-setup: be explicit where to dot-source git-sh-i18n from. 2016-10-30 16:13:49 -07:00
git-stash.sh Merge branch 'jk/stash-disable-renames-internally' into maint 2017-01-17 14:49:30 -08:00
git-submodule.sh clone: pass --progress decision to recursive submodules 2016-09-22 11:22:47 -07:00
git-svn.perl git-svn: "git worktree" awareness 2016-10-14 01:36:12 +00:00
git-web--browse.sh
git.c Merge branch 'jk/common-main' into maint-2.10 2016-12-05 11:24:28 -08:00
git.rc
gpg-interface.c gpg-interface: use more status letters 2016-10-12 10:41:59 -07:00
gpg-interface.h
graph.c Merge branch 'jk/graph-padding-fix' into maint 2016-10-11 14:19:03 -07:00
graph.h graph: add support for --line-prefix on all graph-aware output 2016-08-31 18:07:09 -07:00
grep.c Merge branch 'js/regexec-buf' into maint 2016-09-29 16:49:45 -07:00
grep.h
hashmap.c
hashmap.h
help.c use QSORT 2016-09-29 15:42:18 -07:00
help.h
hex.c hex: make wraparound of the index into ring-buffer explicit 2016-10-26 10:54:11 -07:00
http-backend.c pkt-line: rename packet_write() to packet_write_fmt() 2016-10-17 11:36:50 -07:00
http-fetch.c
http-push.c Merge branch 'jk/common-main' into maint 2016-09-08 21:35:51 -07:00
http-walker.c http-walker: complain about non-404 loose object errors 2016-12-06 12:43:34 -08:00
http.c Merge branch 'jk/http-walker-limit-redirect' into maint 2017-01-17 14:49:29 -08:00
http.h Merge branch 'jk/http-walker-limit-redirect' into maint 2017-01-17 14:49:29 -08:00
ident.c Merge branch 'jk/ident-ai-canonname-could-be-null' into maint 2016-10-03 13:22:32 -07:00
imap-send.c Merge branch 'jc/cocci-xstrdup-or-null' into maint 2016-10-28 09:01:23 -07:00
iterator.h
khash.h
kwset.c
kwset.h
levenshtein.c
levenshtein.h
line-log.c use QSORT 2016-09-29 15:42:18 -07:00
line-log.h
line-range.c
line-range.h
list-objects.c
list-objects.h
list.h
ll-merge.c
ll-merge.h
lockfile.c
lockfile.h
log-tree.c graph: add support for --line-prefix on all graph-aware output 2016-08-31 18:07:09 -07:00
log-tree.h
mailinfo.c Merge branch 'jt/mailinfo-fold-in-body-headers' into maint 2017-01-17 15:11:06 -08:00
mailinfo.h mailinfo: handle in-body header continuations 2016-09-21 10:23:11 -07:00
mailmap.c cocci: refactor common patterns to use xstrdup_or_null() 2016-10-12 11:22:10 -07:00
mailmap.h
match-trees.c
merge-blobs.c
merge-blobs.h
merge-recursive.c Merge branch 'nd/qsort-in-merge-recursive' into maint 2017-01-17 15:19:03 -08:00
merge-recursive.h
merge.c sequencer: lib'ify checkout_fast_forward() 2016-09-09 11:24:52 -07:00
mergesort.c
mergesort.h
mru.c
mru.h
name-hash.c
notes-cache.c
notes-cache.h
notes-merge.c Merge branch 'va/i18n-more' 2016-09-26 16:09:18 -07:00
notes-merge.h
notes-utils.c
notes-utils.h
notes.c notes: convert init_notes to use struct object_id 2016-09-07 12:59:42 -07:00
notes.h
object.c
object.h
pack-bitmap-write.c use QSORT 2016-09-29 15:42:18 -07:00
pack-bitmap.c sha1_file: rename git_open_noatime() to git_open() 2016-10-25 10:59:13 -07:00
pack-bitmap.h
pack-check.c Merge branch 'jk/verify-packfile-gently' into maint 2016-10-11 14:21:36 -07:00
pack-objects.c
pack-objects.h pack-objects: enforce --depth limit in reused deltas 2017-01-27 16:24:44 -08:00
pack-revindex.c use COPY_ARRAY 2016-09-25 16:44:13 -07:00
pack-revindex.h
pack-write.c use QSORT 2016-09-29 15:42:18 -07:00
pack.h
pager.c Merge branch 'jk/setup-sequence-update' 2016-09-21 15:15:24 -07:00
parse-options-cb.c Merge branch 'rs/cocci' 2016-10-17 13:25:21 -07:00
parse-options.c parse-options: print "fatal:" before usage_msg_opt() 2016-12-14 09:58:09 -08:00
parse-options.h Merge branch 'mh/diff-indent-heuristic' 2016-09-26 16:09:16 -07:00
patch-delta.c
patch-ids.c patch-ids: refuse to compute patch-id for merge commit 2016-09-12 13:45:01 -07:00
patch-ids.h
path.c Merge branch 'js/normalize-path-copy-ceil' into maint 2017-01-17 15:11:03 -08:00
pathspec.c Merge branch 'ex/deprecate-empty-pathspec-as-match-all' 2016-10-26 13:14:56 -07:00
pathspec.h Merge branch 'bw/pathspec-remove-unused-extern-decl' into maint 2016-09-29 16:49:34 -07:00
pkt-line.c pkt-line: add functions to read/write flush terminated packet streams 2016-10-17 11:36:50 -07:00
pkt-line.h pkt-line: add functions to read/write flush terminated packet streams 2016-10-17 11:36:50 -07:00
preload-index.c
pretty.c Merge branch 'rs/cocci' into maint 2016-10-28 09:01:23 -07:00
prio-queue.c
prio-queue.h
progress.c
progress.h
prompt.c
prompt.h
quote.c
quote.h
reachable.c
reachable.h
read-cache.c read-cache: make sure file handles are not inherited by child processes 2016-10-25 11:10:18 -07:00
ref-filter.c Merge branch 'jc/for-each-ref-head-segfault-fix' 2016-11-23 11:23:16 -08:00
ref-filter.h
reflog-walk.c
reflog-walk.h
refs.c Merge branch 'jc/cocci-xstrdup-or-null' 2016-10-26 13:14:45 -07:00
refs.h Merge branch 'nd/shallow-deepen' 2016-10-10 14:03:50 -07:00
remote-curl.c Merge branch 'dt/smart-http-detect-server-going-away' into maint 2017-01-17 15:19:03 -08:00
remote-testsvn.c
remote.c use strbuf_addstr() for adding constant strings to a strbuf, part 2 2016-09-15 12:23:38 -07:00
remote.h Merge branch 'jk/push-force-with-lease-creation' into maint 2016-09-08 21:35:53 -07:00
replace_object.c
rerere.c cache: convert struct cache_entry to use struct object_id 2016-09-07 12:59:42 -07:00
rerere.h
resolve-undo.c cache: convert struct cache_entry to use struct object_id 2016-09-07 12:59:42 -07:00
resolve-undo.h
revision.c Merge branch 'vn/revision-shorthand-for-side-branch-log' 2016-10-06 14:53:10 -07:00
revision.h
run-command.c run-command: add clean_on_exit_handler 2016-10-17 11:36:50 -07:00
run-command.h run-command: add clean_on_exit_handler 2016-10-17 11:36:50 -07:00
send-pack.c cocci: refactor common patterns to use xstrdup_or_null() 2016-10-12 11:22:10 -07:00
send-pack.h
sequencer.c Revert "sequencer: remove useless get_dir() function" 2016-12-14 14:56:46 -08:00
sequencer.h sequencer: get rid of the subcommand field 2016-10-21 09:32:34 -07:00
server-info.c use QSORT 2016-09-29 15:42:18 -07:00
setup.c
sh-i18n--envsubst.c remove unnecessary check before QSORT 2016-09-29 15:42:18 -07:00
sha1-array.c Merge branch 'rs/qsort' 2016-10-10 14:03:46 -07:00
sha1-array.h sha1_array: let callbacks interrupt iteration 2016-09-26 11:46:41 -07:00
sha1-lookup.c
sha1-lookup.h
sha1_file.c Merge branch 'jk/quote-env-path-list-component' into maint 2017-01-17 15:11:06 -08:00
sha1_name.c Merge branch 'jk/no-looking-at-dotgit-outside-repo' 2016-11-01 12:58:49 -07:00
shallow.c Merge branch 'nd/shallow-fixup' into maint 2017-01-17 15:11:05 -08:00
shell.c
shortlog.h
show-index.c
sideband.c
sideband.h
sigchain.c
sigchain.h
split-index.c split-index: s/eith/with/ typo fix 2016-11-01 11:48:02 -07:00
split-index.h
strbuf.c link_alt_odb_entry: handle normalize_path errors 2016-10-10 13:52:36 -07:00
strbuf.h link_alt_odb_entry: handle normalize_path errors 2016-10-10 13:52:36 -07:00
streaming.c Merge branch 'jk/pack-objects-optim-mru' 2016-10-10 14:03:47 -07:00
streaming.h streaming: make stream_blob_to_fd take struct object_id 2016-09-07 12:59:42 -07:00
string-list.c use QSORT 2016-09-29 15:42:18 -07:00
string-list.h
submodule-config.c
submodule-config.h
submodule.c Merge branch 'bw/push-dry-run' into maint 2017-01-17 14:49:27 -08:00
submodule.h push: fix --dry-run to not push submodules 2016-11-23 08:39:14 -08:00
symlinks.c
tag.c
tag.h
tar.h
tempfile.c
tempfile.h
thread-utils.c
thread-utils.h
tmp-objdir.c tmp-objdir: quote paths we add to alternates 2016-12-12 15:10:46 -08:00
tmp-objdir.h tmp-objdir: introduce API for temporary object directories 2016-10-10 13:54:02 -07:00
trace.c
trace.h
trailer.c Merge branch 'jt/trailer-with-cruft' 2016-10-31 13:15:22 -07:00
trailer.h
transport-helper.c Merge branch 'nd/shallow-deepen' 2016-10-10 14:03:50 -07:00
transport.c Merge branch 'bw/push-dry-run' into maint 2017-01-17 14:49:27 -08:00
transport.h Merge branch 'jc/abbrev-auto' 2016-10-27 14:58:48 -07:00
tree-diff.c
tree-walk.c fsck: handle bad trees like other errors 2016-09-27 14:09:10 -07:00
tree-walk.h fsck: handle bad trees like other errors 2016-09-27 14:09:10 -07:00
tree.c use QSORT 2016-09-29 15:42:18 -07:00
tree.h
unicode_width.h unicode_width.h: update the width tables to Unicode 9.0 2016-12-14 09:48:07 -08:00
unimplemented.sh
unix-socket.c
unix-socket.h
unpack-trees.c Merge branch 'sb/unpack-trees-grammofix' into maint 2017-01-17 15:19:05 -08:00
unpack-trees.h
upload-pack.c upload-pack: optionally allow fetching any sha1 2016-11-18 13:06:14 -08:00
url.c introduce hex2chr() for converting two hexadecimal digits to a character 2016-09-07 10:42:46 -07:00
url.h
urlmatch.c
urlmatch.h
usage.c Merge branch 'cc/apply-am' 2016-09-19 13:47:18 -07:00
userdiff.c
userdiff.h
utf8.c
utf8.h
varint.c
varint.h
version.c
version.h
versioncmp.c
walker.c
walker.h
wildmatch.c
wildmatch.h
worktree.c worktree list: keep the list sorted 2016-11-28 13:18:51 -08:00
worktree.h worktree list: keep the list sorted 2016-11-28 13:18:51 -08:00
wrap-for-bin.sh
wrapper.c
write_or_die.c run-command: move check_pipe() from write_or_die to run_command 2016-10-17 11:36:49 -07:00
ws.c
wt-status.c Merge branch 'nd/ita-empty-commit' 2016-10-27 14:58:50 -07:00
wt-status.h wt-status: teach has_{unstaged,uncommitted}_changes() about submodules 2016-10-07 09:29:31 -07:00
xdiff-interface.c Merge branch 'js/regexec-buf' into maint 2016-09-29 16:49:45 -07:00
xdiff-interface.h Convert read_mmblob to take struct object_id. 2016-09-07 12:59:42 -07:00
zlib.c

README.md

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 http://git-scm.com/ including full documentation and Git related tools.

See Documentation/gittutorial.txt to get started, then see Documentation/giteveryday.txt for a useful minimum set of commands, and Documentation/git-.txt 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.txt (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). To subscribe to the list, send an email with just "subscribe git" in the body to majordomo@vger.kernel.org. The mailing list archives are available at https://public-inbox.org/git, http://marc.info/?l=git and other archival sites.

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