Go to file
Derrick Stolee 98f8854c94 index-pack: allow revisiting REF_DELTA chains
As detailed in the previous changes to t5309-pack-delta-cycles.sh, the
logic within 'git index-pack' to analyze an incoming thin packfile with
REF_DELTAs is suspect. The algorithm is overly cautious around delta
cycles, and that leads in fact to failing even when there is no cycle.

This change adjusts the algorithm to no longer fail in these cases. In
fact, these cycle cases will no longer fail but more importantly the
valid cases will no longer fail, either. The resulting packfile from the
--fix-thin operation will not have cycles either since REF_DELTAs are
forbidden from the on-disk format and OFS_DELTAs are impossible to write
as a cycle.

The crux of the matter is how the algorithm works when the REF_DELTAs
point to base objects that exist in the local repository. When reading
the thin packfile, the object IDs for the delta objects are unknown so
we do not have the delta chain structure automatically. Instead, we need
to start somewhere by selecting a delta whose base is inside our current
object database.

Consider the case where the packfile has two REF_DELTA objects, A and B,
and the delta chain looks like "A depends on B" and "B depends on C" for
some third object C, where C is already in the current repository. The
algorithm _should_ start with all objects that depend on C, finding B,
and then moving on to all objects depending on B, finding A.

However, if the repository also already has object B, then the delta
chain can be analyzed in a different order. The deltas with base B can
be analyzed first, finding A, and then the deltas with base C are
analyzed, finding B. The algorithm currently continues to look for
objects that depend on B, finding A again. This fails due to A's
'real_type' member already being overwritten from OBJ_REF_DELTA to the
correct object type.

This scenario is possible in a typical 'git fetch' where the client does
not advertise B as a 'have' but requests A as a 'want' (and C is noticed
as a common object based on other 'have's). The reason this isn't
typically seen is that most Git servers use OFS_DELTAs to represent
deltas within a packfile. However, if a server uses only REF_DELTAs,
then this kind of issue can occur. There is nothing in the explicit
packfile format that states this use of inter-pack REF_DELTA is
incorrect, only that REF_DELTAs should not be used in the on-disk
representation to avoid cycles.

This die() was introduced in ab791dd138 (index-pack: fix race condition
with duplicate bases, 2014-08-29). Several refactors have adjusted the
error message and the surrounding logic, but this issue has existed for
a longer time as that was only a conversion from an assert().

The tests in t5309 originated in 3b910d0c5e (add tests for indexing
packs with delta cycles, 2013-08-23) and b2ef3d9ebb (test index-pack on
packs with recoverable delta cycles, 2013-08-23). These changes make
note that the current behavior of handling "resolvable" cycles is mostly
a documentation-only test, not that this behavior is the best way for
Git to handle the situation.

The fix here is somewhat complicated due to the amount of state being
adjusted by the loop within threaded_second_pass(). Instead of trying to
resume the start of the loop while adjusting the necessary context, I
chose to scan the REF_DELTAs depending on the current 'parent' and skip
any that have already been processed. This necessarily leaves us in a
state where 'child' and 'child_obj' could be left as NULL and that must
be handled later. There is also some careful handling around skipping
REF_DELTAs when there are also OFS_DELTAs depending on that parent.
There may be value in extending 'test-tool pack-deltas' to allow writing
OFS_DELTAs in order to exercise this logic across the delta types.

Signed-off-by: Derrick Stolee <stolee@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-04-28 15:37:26 -07:00
.github Merge branch 'ps/misc-build-fixes' 2025-04-16 13:54:18 -07:00
Documentation The seventh batch 2025-04-17 10:28:20 -07:00
bin-wrappers
block-sha1
builtin index-pack: allow revisiting REF_DELTA chains 2025-04-28 15:37:26 -07:00
ci Merge branch 'en/merge-recursive-debug' 2025-04-17 10:28:18 -07:00
compat Merge branch 'js/comma-semicolon-confusion' 2025-04-15 13:50:17 -07:00
compiler-tricks git-compat-util: add NOT_CONSTANT macro and use it in atfork_prepare() 2025-03-17 17:30:49 -07:00
contrib Merge branch 'ps/misc-build-fixes' 2025-04-16 13:54:18 -07:00
ewah ewah: implement `struct ewah_or_iterator` 2025-03-21 04:34:04 -07:00
git-gui
gitk-git
gitweb meson: distinguish build and target host binaries 2025-04-01 02:20:44 -07:00
mergetools Merge branch 'fr/vimdiff-layout-fixes' 2025-04-08 11:43:16 -07:00
negotiator
oss-fuzz
perl
po Merge branch 'l10n/zh-TW/2025-03-09' of github.com:l10n-tw/git-po 2025-03-13 21:57:56 +08:00
refs Merge branch 'ps/refname-avail-check-optim' 2025-04-17 10:28:19 -07:00
reftable Merge branch 'ps/reftable-windows-unlink-fix' 2025-04-15 13:50:13 -07:00
sha1
sha1collisiondetection@855827c583
sha1dc
sha256
subprojects
t index-pack: allow revisiting REF_DELTA chains 2025-04-28 15:37:26 -07:00
templates meson: distinguish build and target host binaries 2025-04-01 02:20:44 -07:00
trace2
xdiff Merge branch 'js/comma-semicolon-confusion' 2025-04-15 13:50:17 -07:00
.cirrus.yml
.clang-format
.editorconfig
.gitattributes merge-file doc: set conflict-marker-size attribute 2025-03-29 10:31:19 +09:00
.gitignore
.gitlab-ci.yml ci: use Visual Studio for win+meson job on GitHub Workflows 2025-04-01 02:20:44 -07:00
.gitmodules
.mailmap
.tsan-suppressions
CODE_OF_CONDUCT.md
COPYING
GIT-BUILD-OPTIONS.in
GIT-VERSION-FILE.in
GIT-VERSION-GEN Start 2.50 cycle (batch #1) 2025-03-26 16:26:11 +09:00
INSTALL
LGPL-2.1
Makefile test-tool: add pack-deltas helper 2025-04-28 15:37:25 -07:00
README.md
RelNotes Start 2.50 cycle (batch #1) 2025-03-26 16:26:11 +09:00
SECURITY.md
abspath.c
abspath.h
aclocal.m4
add-interactive.c
add-interactive.h
add-patch.c
advice.c advice: allow disabling default branch name advice 2025-03-25 16:09:28 -07:00
advice.h advice: allow disabling default branch name advice 2025-03-25 16:09:28 -07:00
alias.c
alias.h
alloc.c
alloc.h
apply.c
apply.h
archive-tar.c
archive-zip.c
archive.c hash: stop depending on `the_repository` in `null_oid()` 2025-03-10 13:16:20 -07:00
archive.h
attr.c
attr.h
banned.h
base85.c
base85.h
bisect.c
bisect.h
blame.c hash: stop depending on `the_repository` in `null_oid()` 2025-03-10 13:16:20 -07:00
blame.h
blob.c
blob.h
bloom.c
bloom.h
branch.c hash: stop depending on `the_repository` in `null_oid()` 2025-03-10 13:16:20 -07:00
branch.h
builtin.h Merge branch 'jt/diff-pairs' 2025-03-26 16:26:09 +09:00
bulk-checkin.c Merge branch 'ps/object-wo-the-repository' 2025-04-15 13:50:15 -07:00
bulk-checkin.h
bundle-uri.c
bundle-uri.h
bundle.c
bundle.h
cache-tree.c
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 hash: stop depending on `the_repository` in `null_oid()` 2025-03-10 13:16:20 -07:00
command-list.txt
commit-graph.c csum-file: stop depending on `the_repository` 2025-03-10 13:16:18 -07:00
commit-graph.h
commit-reach.c
commit-reach.h
commit-slab-decl.h
commit-slab-impl.h
commit-slab.h
commit.c Merge branch 'ps/object-wo-the-repository' 2025-04-15 13:50:15 -07:00
commit.h
common-exit.c
common-init.c
common-init.h
common-main.c
config.c Merge branch 'ps/object-wo-the-repository' 2025-04-15 13:50:15 -07:00
config.h
config.mak.dev Merge branch 'js/comma-semicolon-confusion' 2025-04-15 13:50:17 -07:00
config.mak.in
config.mak.uname
configure.ac
connect.c
connect.h
connected.c
connected.h
convert.c
convert.h
copy.c
copy.h
credential.c
credential.h
csum-file.c csum-file: stop depending on `the_repository` 2025-03-10 13:16:18 -07:00
csum-file.h csum-file: stop depending on `the_repository` 2025-03-10 13:16:18 -07:00
ctype.c
daemon.c
date.c
date.h
decorate.c decorate: fix sign comparison warnings 2025-03-10 13:21:13 -07:00
decorate.h
delta-islands.c delta-islands: stop depending on `the_repository` 2025-03-10 13:16:20 -07:00
delta-islands.h delta-islands: stop depending on `the_repository` 2025-03-10 13:16:20 -07:00
delta.h
detect-compiler detect-compiler: detect clang even if it found CUDA 2025-03-28 17:38:12 -07:00
diagnose.c
diagnose.h
diff-delta.c diff-delta: avoid using the comma operator 2025-03-28 17:38:10 -07:00
diff-lib.c hash: stop depending on `the_repository` in `null_oid()` 2025-03-10 13:16:20 -07:00
diff-merges.c
diff-merges.h
diff-no-index.c hash: stop depending on `the_repository` in `null_oid()` 2025-03-10 13:16:20 -07:00
diff.c Merge branch 'ps/object-wo-the-repository' 2025-04-15 13:50:15 -07:00
diff.h Merge branch 'ps/object-wo-the-repository' 2025-04-15 13:50:15 -07:00
diffcore-break.c
diffcore-delta.c
diffcore-order.c
diffcore-pickaxe.c
diffcore-rename.c Merge branch 'en/assert-wo-side-effects' 2025-04-08 11:43:12 -07:00
diffcore-rotate.c
diffcore.h
dir-iterator.c refs/iterator: separate lifecycle from iteration 2025-03-12 11:31:18 -07:00
dir-iterator.h refs/iterator: separate lifecycle from iteration 2025-03-12 11:31:18 -07:00
dir.c hash: stop depending on `the_repository` in `null_oid()` 2025-03-10 13:16:20 -07:00
dir.h Merge branch 'am/dir-dedup-decl-of-repository' 2025-03-29 16:39:09 +09:00
editor.c
editor.h
entry.c
entry.h
environment.c environment: move access to "core.bigFileThreshold" into repo settings 2025-03-10 13:16:18 -07:00
environment.h Merge branch 'ab/environment-clean-header' 2025-04-17 10:28:20 -07:00
exec-cmd.c
exec-cmd.h
fetch-negotiator.c
fetch-negotiator.h
fetch-pack.c
fetch-pack.h
fmt-merge-msg.c
fmt-merge-msg.h
fsck.c
fsck.h Merge branch 'sj/ref-consistency-checks-more' 2025-03-26 16:26:10 +09: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 completion: take into account the formatting backticks for options 2025-03-20 19:27:29 -07:00
generate-hooklist.sh
generate-perl.sh
generate-python.sh
generate-script.sh
gettext.c
gettext.h
git-archimport.perl
git-compat-util.h Merge branch 'ps/reftable-sans-compat-util' 2025-04-08 11:43:14 -07:00
git-curl-compat.h http.c: allow custom TCP keepalive behavior via config 2025-03-21 01:38:52 -07:00
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 send-email: finer-grained SMTP error handling 2025-04-07 14:54:05 -07:00
git-sh-i18n.sh
git-sh-setup.sh
git-submodule.sh
git-svn.perl
git-web--browse.sh
git-zlib.c Merge branch 'jk/zlib-inflate-fixes' 2025-04-15 13:50:14 -07:00
git-zlib.h
git.c
git.rc.in
gpg-interface.c
gpg-interface.h
graph.c
graph.h
grep.c hash: stop depending on `the_repository` in `null_oid()` 2025-03-10 13:16:20 -07:00
grep.h
hash-lookup.c
hash-lookup.h
hash.c hash: stop depending on `the_repository` in `null_oid()` 2025-03-10 13:16:20 -07:00
hash.h Merge branch 'jt/help-sha-backend-info-in-build-options' 2025-04-16 13:54:20 -07:00
hashmap.c
hashmap.h
help.c help: include unsafe SHA-1 build info in version 2025-04-07 14:39:27 -07:00
help.h
hex-ll.c
hex-ll.h
hex.c
hex.h
hook.c
hook.h
http-backend.c
http-fetch.c
http-push.c
http-walker.c
http.c http.c: allow custom TCP keepalive behavior via config 2025-03-21 01:38:52 -07:00
http.h
ident.c
ident.h
imap-send.c imap-send: explicitly verify the peer certificate 2025-03-25 15:48:58 -07:00
iterator.h refs/iterator: separate lifecycle from iteration 2025-03-12 11:31:18 -07:00
json-writer.c
json-writer.h
khash.h
kwset.c kwset: avoid using the comma operator unnecessarily 2025-03-28 17:38:09 -07:00
kwset.h
levenshtein.c
levenshtein.h
line-log.c
line-log.h
line-range.c
line-range.h
linear-assignment.c
linear-assignment.h
list-objects-filter-options.c
list-objects-filter-options.h
list-objects-filter.c
list-objects-filter.h
list-objects.c
list-objects.h
list.h
lockfile.c
lockfile.h
log-tree.c hash: stop depending on `the_repository` in `null_oid()` 2025-03-10 13:16:20 -07:00
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: support having merge verbosity be set to 0 2025-03-18 09:48:51 -07:00
merge-ort-wrappers.h merge-recursive.[ch]: thoroughly debug these 2025-04-08 13:59:13 -07:00
merge-ort.c Merge branch 'en/merge-recursive-debug' 2025-04-17 10:28:18 -07:00
merge-ort.h merge-recursive.[ch]: thoroughly debug these 2025-04-08 13:59:13 -07:00
merge.c
merge.h
mergesort.h
meson.build Merge branch 'en/merge-recursive-debug' 2025-04-17 10:28:18 -07:00
meson_options.txt
midx-write.c Merge branch 'ps/object-wo-the-repository' 2025-04-15 13:50:15 -07:00
midx.c csum-file: stop depending on `the_repository` 2025-03-10 13:16:18 -07:00
midx.h
name-hash.c
name-hash.h
notes-cache.c
notes-cache.h
notes-merge.c hash: stop depending on `the_repository` in `null_oid()` 2025-03-10 13:16:20 -07:00
notes-merge.h
notes-utils.c
notes-utils.h
notes.c hash: stop depending on `the_repository` in `null_oid()` 2025-03-10 13:16:20 -07:00
notes.h
object-file-convert.c object-file-convert: stop depending on `the_repository` 2025-03-10 13:16:19 -07:00
object-file-convert.h object-file-convert: stop depending on `the_repository` 2025-03-10 13:16:19 -07:00
object-file.c Merge branch 'ps/object-wo-the-repository' 2025-04-15 13:50:15 -07:00
object-file.h
object-name.c Merge branch 'ps/refname-avail-check-optim' 2025-03-29 16:39:07 +09:00
object-name.h object-name: introduce `repo_get_oid_with_flags()` 2025-03-12 11:31:16 -07:00
object-store-ll.h
object-store.h
object.c object: stop depending on `the_repository` 2025-03-10 13:16:18 -07:00
object.h object: stop depending on `the_repository` 2025-03-10 13:16:18 -07: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 'ps/object-wo-the-repository' 2025-04-15 13:50:15 -07:00
pack-bitmap.c Merge branch 'ps/cat-file-filter-batch' 2025-04-16 13:54:21 -07:00
pack-bitmap.h Merge branch 'ps/cat-file-filter-batch' 2025-04-16 13:54:21 -07:00
pack-check.c pack-check: stop depending on `the_repository` 2025-03-10 13:16:19 -07:00
pack-mtimes.c
pack-mtimes.h
pack-objects.c
pack-objects.h
pack-revindex.c Merge branch 'ps/object-wo-the-repository' 2025-04-15 13:50:15 -07:00
pack-revindex.h
pack-write.c pack-write: stop depending on `the_repository` and `the_hash_algo` 2025-03-10 13:16:18 -07:00
pack.h pack-write: stop depending on `the_repository` and `the_hash_algo` 2025-03-10 13:16:18 -07:00
packfile.c builtin/pack-objects.c: freshen objects from existing cruft packs 2025-03-13 11:48:04 -07:00
packfile.h builtin/pack-objects.c: freshen objects from existing cruft packs 2025-03-13 11:48:04 -07:00
pager.c
pager.h
parallel-checkout.c treewide: replace assert() with ASSERT() in special cases 2025-03-21 03:32:10 -07:00
parallel-checkout.h
parse-options-cb.c hash: stop depending on `the_repository` in `null_oid()` 2025-03-10 13:16:20 -07:00
parse-options.c
parse-options.h
parse.c
parse.h
patch-delta.c
patch-ids.c
patch-ids.h
path-walk.c
path-walk.h
path.c
path.h
pathspec.c pathspec: fix sign comparison warnings 2025-04-01 02:51:47 -07:00
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: compare remote names case sensitively 2025-03-18 12:22:34 -07:00
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 Merge branch 'tb/bitamp-typofix' 2025-04-07 14:23:20 -07:00
quote.c
quote.h
range-diff.c hash: stop depending on `the_repository` in `null_oid()` 2025-03-10 13:16:20 -07:00
range-diff.h
reachable.c Merge branch 'ps/cat-file-filter-batch' 2025-04-16 13:54:21 -07:00
reachable.h
read-cache-ll.h
read-cache.c hash: stop depending on `the_repository` in `null_oid()` 2025-03-10 13:16:20 -07:00
read-cache.h
rebase-interactive.c
rebase-interactive.h
rebase.c
rebase.h
ref-filter.c
ref-filter.h
reflog-walk.c
reflog-walk.h
reflog.c builtin/reflog: make functions regarding `reflog_expire_options` public 2025-04-08 07:53:27 -07:00
reflog.h builtin/reflog: make functions regarding `reflog_expire_options` public 2025-04-08 07:53:27 -07:00
refs.c Merge branch 'cj/refname-avail-check-optim-typofix' 2025-04-17 10:28:19 -07:00
refs.h Merge branch 'kn/non-transactional-batch-updates' 2025-04-16 13:54:19 -07:00
refspec.c refspec: replace `refspec_item_init()` with fetch/push variants 2025-03-21 01:45:16 -07:00
refspec.h refspec: replace `refspec_item_init()` with fetch/push variants 2025-03-21 01:45:16 -07:00
remote-curl.c remote-curl: avoid using the comma operator unnecessarily 2025-03-28 17:38:08 -07:00
remote.c Merge branch 'jt/clone-guess-remote-head-fix' 2025-04-15 13:50:16 -07:00
remote.h remote: allow `guess_remote_head()` to suppress advice 2025-03-25 16:09:27 -07:00
replace-object.c
replace-object.h
repo-settings.c environment: move access to "core.bigFileThreshold" into repo settings 2025-03-10 13:16:18 -07:00
repo-settings.h environment: move access to "core.bigFileThreshold" into repo settings 2025-03-10 13:16:18 -07:00
repository.c
repository.h
rerere.c
rerere.h
reset.c hash: stop depending on `the_repository` in `null_oid()` 2025-03-10 13:16:20 -07:00
reset.h
resolve-undo.c
resolve-undo.h
revision.c Merge branch 'jt/rev-list-z' 2025-04-16 13:54:18 -07:00
revision.h rev-list: inline `show_object_with_name()` in `show_object()` 2025-03-21 03:40:02 -07:00
run-command.c git-compat-util: add NOT_CONSTANT macro and use it in atfork_prepare() 2025-03-17 17:30:49 -07:00
run-command.h
sane-ctype.h
scalar.c treewide: replace assert() with ASSERT() in special cases 2025-03-21 03:32:10 -07:00
send-pack.c
send-pack.h
sequencer.c Merge branch 'en/merge-recursive-debug' 2025-04-17 10:28:18 -07:00
sequencer.h
serve.c
serve.h
server-info.c
server-info.h
setup.c
setup.h
sh-i18n--envsubst.c
sha1dc_git.c
sha1dc_git.h
shallow.c object: stop depending on `the_repository` 2025-03-10 13:16:18 -07:00
shallow.h
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
strbuf.h
streaming.c environment: move access to "core.bigFileThreshold" into repo settings 2025-03-10 13:16:18 -07:00
streaming.h
string-list.c
string-list.h
strmap.c
strmap.h
strvec.c
strvec.h
sub-process.c
sub-process.h
submodule-config.c hash: stop depending on `the_repository` in `null_oid()` 2025-03-10 13:16:20 -07:00
submodule-config.h
submodule.c hash: stop depending on `the_repository` in `null_oid()` 2025-03-10 13:16:20 -07:00
submodule.h
symlinks.c
symlinks.h
tag.c
tag.h
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 refspec: replace `refspec_init()` with fetch/push variants 2025-03-21 01:45:16 -07:00
transport-internal.h
transport.c
transport.h
tree-diff.c hash: stop depending on `the_repository` in `null_oid()` 2025-03-10 13:16:20 -07:00
tree-walk.c
tree-walk.h
tree.c
tree.h
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 hash: stop depending on `the_repository` in `null_oid()` 2025-03-10 13:16:20 -07:00
upload-pack.h
url.c
url.h
urlmatch.c
urlmatch.h
usage.c
userdiff.c userdiff: add builtin driver for INI files 2025-04-01 03:02:09 -07:00
userdiff.h
utf8.c
utf8.h
varint.c
varint.h
version-def.h.in
version.c
version.h
versioncmp.c
versioncmp.h
walker.c
walker.h
wildmatch.c wildmatch: avoid using of the comma operator 2025-03-28 17:38:11 -07:00
wildmatch.h
worktree.c Merge branch 'sj/ref-consistency-checks-more' 2025-03-26 16:26:10 +09:00
worktree.h Merge branch 'sj/ref-consistency-checks-more' 2025-03-26 16:26:10 +09:00
wrapper.c
wrapper.h
write-or-die.c
write-or-die.h
ws.c
ws.h
wt-status.c hash: stop depending on `the_repository` in `null_oid()` 2025-03-10 13:16:20 -07:00
wt-status.h
xdiff-interface.c hash: stop depending on `the_repository` in `null_oid()` 2025-03-10 13:16:20 -07:00
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