summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Documentation/.gitignore1
-rw-r--r--Documentation/Makefile30
-rw-r--r--Documentation/RelNotes/1.7.6.1.txt63
-rw-r--r--Documentation/RelNotes/1.7.6.2.txt8
-rw-r--r--Documentation/RelNotes/1.7.6.3.txt24
-rw-r--r--Documentation/RelNotes/1.7.6.4.txt32
-rw-r--r--Documentation/RelNotes/1.7.7.1.txt60
-rw-r--r--Documentation/RelNotes/1.7.7.2.txt44
-rw-r--r--Documentation/RelNotes/1.7.7.3.txt19
-rw-r--r--Documentation/RelNotes/1.7.7.4.txt14
-rw-r--r--Documentation/RelNotes/1.7.7.txt134
-rw-r--r--Documentation/RelNotes/1.7.8.txt161
-rw-r--r--Documentation/RelNotes/1.7.9.txt27
-rw-r--r--Documentation/SubmittingPatches3
-rw-r--r--Documentation/blame-options.txt1
-rw-r--r--Documentation/config.txt68
-rw-r--r--Documentation/diff-options.txt29
-rw-r--r--Documentation/git-am.txt4
-rw-r--r--Documentation/git-annotate.txt1
-rw-r--r--Documentation/git-archive.txt43
-rw-r--r--Documentation/git-bisect.txt35
-rw-r--r--Documentation/git-branch.txt25
-rw-r--r--Documentation/git-check-attr.txt26
-rw-r--r--Documentation/git-check-ref-format.txt62
-rw-r--r--Documentation/git-cherry-pick.txt22
-rw-r--r--Documentation/git-cherry.txt1
-rw-r--r--Documentation/git-citool.txt1
-rw-r--r--Documentation/git-clean.txt10
-rw-r--r--Documentation/git-clone.txt11
-rw-r--r--Documentation/git-commit-tree.txt9
-rw-r--r--Documentation/git-commit.txt2
-rw-r--r--Documentation/git-count-objects.txt1
-rw-r--r--Documentation/git-cvsexportcommit.txt1
-rw-r--r--Documentation/git-daemon.txt20
-rw-r--r--Documentation/git-diff-files.txt1
-rw-r--r--Documentation/git-diff-index.txt1
-rw-r--r--Documentation/git-difftool.txt3
-rw-r--r--Documentation/git-fast-export.txt5
-rw-r--r--Documentation/git-fast-import.txt51
-rw-r--r--Documentation/git-fetch-pack.txt1
-rw-r--r--Documentation/git-fetch.txt4
-rw-r--r--Documentation/git-filter-branch.txt5
-rw-r--r--Documentation/git-for-each-ref.txt7
-rw-r--r--Documentation/git-format-patch.txt9
-rw-r--r--Documentation/git-fsck-objects.txt1
-rw-r--r--Documentation/git-fsck.txt11
-rw-r--r--Documentation/git-gc.txt1
-rw-r--r--Documentation/git-get-tar-commit-id.txt1
-rw-r--r--Documentation/git-grep.txt58
-rw-r--r--Documentation/git-gui.txt17
-rw-r--r--Documentation/git-help.txt1
-rw-r--r--Documentation/git-http-backend.txt8
-rw-r--r--Documentation/git-http-fetch.txt4
-rw-r--r--Documentation/git-http-push.txt1
-rw-r--r--Documentation/git-imap-send.txt1
-rw-r--r--Documentation/git-init-db.txt1
-rw-r--r--Documentation/git-init.txt1
-rw-r--r--Documentation/git-instaweb.txt12
-rw-r--r--Documentation/git-log.txt28
-rw-r--r--Documentation/git-lost-found.txt1
-rw-r--r--Documentation/git-mailinfo.txt1
-rw-r--r--Documentation/git-mailsplit.txt1
-rw-r--r--Documentation/git-merge-file.txt4
-rw-r--r--Documentation/git-merge-index.txt1
-rw-r--r--Documentation/git-merge-one-file.txt1
-rw-r--r--Documentation/git-merge-tree.txt1
-rw-r--r--Documentation/git-mergetool--lib.txt3
-rw-r--r--Documentation/git-mergetool.txt8
-rw-r--r--Documentation/git-mktag.txt1
-rw-r--r--Documentation/git-mktree.txt1
-rw-r--r--Documentation/git-mv.txt1
-rw-r--r--Documentation/git-notes.txt7
-rw-r--r--Documentation/git-pack-redundant.txt1
-rw-r--r--Documentation/git-pack-refs.txt1
-rw-r--r--Documentation/git-parse-remote.txt1
-rw-r--r--Documentation/git-patch-id.txt1
-rw-r--r--Documentation/git-peek-remote.txt1
-rw-r--r--Documentation/git-prune-packed.txt1
-rw-r--r--Documentation/git-prune.txt1
-rw-r--r--Documentation/git-pull.txt1
-rw-r--r--Documentation/git-push.txt26
-rw-r--r--Documentation/git-read-tree.txt53
-rw-r--r--Documentation/git-rebase.txt9
-rw-r--r--Documentation/git-receive-pack.txt3
-rw-r--r--Documentation/git-reflog.txt1
-rw-r--r--Documentation/git-relink.txt1
-rw-r--r--Documentation/git-remote-ext.txt1
-rw-r--r--Documentation/git-remote-fd.txt8
-rw-r--r--Documentation/git-remote-helpers.txt187
-rw-r--r--Documentation/git-remote-testgit.txt30
-rw-r--r--Documentation/git-remote.txt19
-rw-r--r--Documentation/git-repack.txt1
-rw-r--r--Documentation/git-repo-config.txt1
-rw-r--r--Documentation/git-request-pull.txt1
-rw-r--r--Documentation/git-rerere.txt1
-rw-r--r--Documentation/git-reset.txt8
-rw-r--r--Documentation/git-rev-parse.txt5
-rw-r--r--Documentation/git-revert.txt14
-rw-r--r--Documentation/git-rm.txt5
-rw-r--r--Documentation/git-send-email.txt1
-rw-r--r--Documentation/git-send-pack.txt1
-rw-r--r--Documentation/git-sh-i18n--envsubst.txt10
-rw-r--r--Documentation/git-sh-i18n.txt3
-rw-r--r--Documentation/git-sh-setup.txt1
-rw-r--r--Documentation/git-shell.txt1
-rw-r--r--Documentation/git-show-branch.txt1
-rw-r--r--Documentation/git-show-index.txt1
-rw-r--r--Documentation/git-show.txt11
-rw-r--r--Documentation/git-stash.txt10
-rw-r--r--Documentation/git-status.txt8
-rw-r--r--Documentation/git-stripspace.txt1
-rw-r--r--Documentation/git-submodule.txt56
-rw-r--r--Documentation/git-svn.txt35
-rw-r--r--Documentation/git-symbolic-ref.txt10
-rw-r--r--Documentation/git-tag.txt17
-rw-r--r--Documentation/git-tar-tree.txt11
-rw-r--r--Documentation/git-unpack-file.txt1
-rw-r--r--Documentation/git-unpack-objects.txt1
-rw-r--r--Documentation/git-update-index.txt7
-rw-r--r--Documentation/git-update-ref.txt6
-rw-r--r--Documentation/git-update-server-info.txt1
-rw-r--r--Documentation/git-upload-archive.txt1
-rw-r--r--Documentation/git-upload-pack.txt5
-rw-r--r--Documentation/git-var.txt1
-rw-r--r--Documentation/git-verify-pack.txt1
-rw-r--r--Documentation/git-verify-tag.txt1
-rw-r--r--Documentation/git-web--browse.txt3
-rw-r--r--Documentation/git-whatchanged.txt5
-rw-r--r--Documentation/git-write-tree.txt1
-rw-r--r--Documentation/git.txt37
-rw-r--r--Documentation/gitattributes.txt30
-rw-r--r--Documentation/gitcvs-migration.txt3
-rw-r--r--Documentation/gitdiffcore.txt1
-rw-r--r--Documentation/gitk.txt1
-rw-r--r--Documentation/gitnamespaces.txt82
-rw-r--r--Documentation/gitrepository-layout.txt58
-rw-r--r--Documentation/gittutorial-2.txt1
-rw-r--r--Documentation/gittutorial.txt1
-rw-r--r--Documentation/gitweb.conf.txt889
-rw-r--r--Documentation/gitweb.txt704
-rw-r--r--Documentation/gitworkflows.txt1
-rw-r--r--Documentation/glossary-content.txt29
-rw-r--r--Documentation/howto/maintain-git.txt13
-rwxr-xr-xDocumentation/install-doc-quick.sh44
-rw-r--r--Documentation/merge-options.txt5
-rw-r--r--Documentation/rev-list-options.txt4
-rw-r--r--Documentation/sequencer.txt12
-rw-r--r--Documentation/technical/api-argv-array.txt46
-rw-r--r--Documentation/technical/api-builtin.txt2
-rw-r--r--Documentation/technical/api-gitattributes.txt61
-rw-r--r--Documentation/technical/api-parse-options.txt21
-rw-r--r--Documentation/technical/api-ref-iteration.txt81
-rw-r--r--Documentation/technical/api-sha1-array.txt79
-rw-r--r--Documentation/technical/api-string-list.txt10
-rw-r--r--Documentation/technical/index-format.txt5
-rw-r--r--Documentation/technical/pack-protocol.txt110
-rwxr-xr-xGIT-VERSION-GEN2
-rw-r--r--INSTALL42
-rw-r--r--Makefile184
l---------RelNotes2
-rw-r--r--abspath.c35
-rw-r--r--advice.c31
-rw-r--r--advice.h3
-rw-r--r--archive-tar.c135
-rw-r--r--archive-zip.c24
-rw-r--r--archive.c96
-rw-r--r--archive.h23
-rw-r--r--argv-array.c51
-rw-r--r--argv-array.h20
-rw-r--r--attr.c236
-rw-r--r--attr.h20
-rw-r--r--bisect.c101
-rw-r--r--bisect.h2
-rw-r--r--branch.c42
-rw-r--r--branch.h18
-rw-r--r--builtin/apply.c28
-rw-r--r--builtin/archive.c53
-rw-r--r--builtin/bisect--helper.c7
-rw-r--r--builtin/blame.c5
-rw-r--r--builtin/branch.c78
-rw-r--r--builtin/bundle.c2
-rw-r--r--builtin/check-attr.c132
-rw-r--r--builtin/check-ref-format.c63
-rw-r--r--builtin/checkout-index.c32
-rw-r--r--builtin/checkout.c116
-rw-r--r--builtin/clean.c5
-rw-r--r--builtin/clone.c173
-rw-r--r--builtin/commit.c114
-rw-r--r--builtin/config.c48
-rw-r--r--builtin/describe.c17
-rw-r--r--builtin/diff.c5
-rw-r--r--builtin/fast-export.c40
-rw-r--r--builtin/fetch-pack.c54
-rw-r--r--builtin/fetch.c132
-rw-r--r--builtin/fmt-merge-msg.c2
-rw-r--r--builtin/for-each-ref.c93
-rw-r--r--builtin/fsck.c87
-rw-r--r--builtin/gc.c4
-rw-r--r--builtin/grep.c123
-rw-r--r--builtin/index-pack.c264
-rw-r--r--builtin/init-db.c2
-rw-r--r--builtin/log.c15
-rw-r--r--builtin/ls-files.c48
-rw-r--r--builtin/ls-remote.c3
-rw-r--r--builtin/ls-tree.c4
-rw-r--r--builtin/merge.c295
-rw-r--r--builtin/mktree.c1
-rw-r--r--builtin/mv.c6
-rw-r--r--builtin/name-rev.c6
-rw-r--r--builtin/pack-objects.c277
-rw-r--r--builtin/patch-id.c10
-rw-r--r--builtin/prune.c13
-rw-r--r--builtin/push.c19
-rw-r--r--builtin/receive-pack.c205
-rw-r--r--builtin/reflog.c5
-rw-r--r--builtin/remote.c55
-rw-r--r--builtin/replace.c2
-rw-r--r--builtin/reset.c51
-rw-r--r--builtin/rev-list.c27
-rw-r--r--builtin/rev-parse.c8
-rw-r--r--builtin/revert.c857
-rw-r--r--builtin/send-pack.c4
-rw-r--r--builtin/show-branch.c9
-rw-r--r--builtin/show-ref.c2
-rw-r--r--builtin/stripspace.c2
-rw-r--r--builtin/tag.c92
-rw-r--r--builtin/unpack-objects.c2
-rw-r--r--builtin/update-ref.c2
-rw-r--r--builtin/upload-archive.c2
-rw-r--r--builtin/verify-pack.c132
-rw-r--r--bundle.c142
-rw-r--r--bundle.h4
-rw-r--r--cache.h169
-rw-r--r--color.c46
-rw-r--r--color.h22
-rw-r--r--combine-diff.c298
-rw-r--r--command-list.txt1
-rw-r--r--commit.c48
-rw-r--r--commit.h11
-rw-r--r--compat/cygwin.c5
-rw-r--r--compat/inet_ntop.c2
-rw-r--r--compat/mingw.c58
-rw-r--r--compat/mingw.h14
-rw-r--r--compat/msvc.h1
-rw-r--r--compat/obstack.c413
-rw-r--r--compat/obstack.h506
-rw-r--r--compat/qsort.c2
-rw-r--r--compat/strtoimax.c10
-rw-r--r--compat/vcbuild/include/arpa/inet.h1
-rw-r--r--compat/vcbuild/include/grp.h1
-rw-r--r--compat/vcbuild/include/inttypes.h1
-rw-r--r--compat/vcbuild/include/netdb.h1
-rw-r--r--compat/vcbuild/include/netinet/in.h1
-rw-r--r--compat/vcbuild/include/netinet/tcp.h1
-rw-r--r--compat/vcbuild/include/pwd.h1
-rw-r--r--compat/vcbuild/include/sys/ioctl.h1
-rw-r--r--compat/vcbuild/include/sys/select.h1
-rw-r--r--compat/vcbuild/include/sys/socket.h1
-rw-r--r--compat/vcbuild/include/sys/wait.h1
-rw-r--r--compat/vcbuild/include/termios.h1
-rw-r--r--compat/win32/poll.c (renamed from compat/win32/sys/poll.c)19
-rw-r--r--compat/win32/poll.h (renamed from compat/win32/sys/poll.h)0
-rw-r--r--compat/win32/syslog.c30
-rw-r--r--config.c183
-rw-r--r--connect.c52
-rw-r--r--connected.c62
-rw-r--r--connected.h20
-rwxr-xr-xcontrib/completion/git-completion.bash56
-rw-r--r--contrib/convert-objects/git-convert-objects.txt1
-rw-r--r--contrib/diff-highlight/README57
-rwxr-xr-xcontrib/diff-highlight/diff-highlight124
-rwxr-xr-xcontrib/fast-import/git-p4429
-rw-r--r--contrib/fast-import/git-p4.txt57
-rw-r--r--contrib/git-jump/README92
-rwxr-xr-xcontrib/git-jump/git-jump69
-rw-r--r--contrib/gitview/gitview.txt1
-rwxr-xr-xcontrib/hooks/post-receive-email13
-rwxr-xr-xcontrib/mw-to-git/git-remote-mediawiki827
-rw-r--r--contrib/mw-to-git/git-remote-mediawiki.txt7
-rw-r--r--contrib/svn-fe/svn-fe.txt1
-rw-r--r--convert.c409
-rw-r--r--convert.h72
-rw-r--r--csum-file.c46
-rw-r--r--csum-file.h2
-rw-r--r--daemon.c66
-rw-r--r--date.c34
-rw-r--r--diff-lib.c84
-rw-r--r--diff.c147
-rw-r--r--diff.h7
-rw-r--r--diffcore-pickaxe.c192
-rw-r--r--diffcore.h2
-rw-r--r--dir.c113
-rw-r--r--dir.h1
-rw-r--r--entry.c116
-rw-r--r--environment.c45
-rw-r--r--fast-import.c158
-rw-r--r--fsck.c10
-rwxr-xr-xgenerate-cmdlist.sh4
-rwxr-xr-xgit-am.sh136
-rwxr-xr-xgit-bisect.sh408
-rw-r--r--git-compat-util.h25
-rwxr-xr-xgit-cvsserver.perl4
-rwxr-xr-xgit-difftool--helper.sh27
-rwxr-xr-xgit-difftool.perl2
-rwxr-xr-xgit-filter-branch.sh18
-rwxr-xr-xgit-gui/git-gui.sh3
-rw-r--r--git-gui/lib/blame.tcl31
-rw-r--r--git-gui/lib/choose_rev.tcl4
-rw-r--r--git-gui/lib/commit.tcl15
-rw-r--r--git-gui/lib/index.tcl9
-rw-r--r--git-gui/lib/line.tcl81
-rw-r--r--git-gui/lib/search.tcl4
-rw-r--r--git-gui/po/README39
-rw-r--r--git-gui/po/sv.po2
-rwxr-xr-xgit-instaweb.sh84
-rwxr-xr-xgit-merge-one-file.sh2
-rw-r--r--git-mergetool--lib.sh405
-rwxr-xr-xgit-mergetool.sh86
-rwxr-xr-xgit-pull.sh37
-rw-r--r--git-rebase--interactive.sh48
-rwxr-xr-xgit-rebase.sh17
-rw-r--r--git-remote-testgit.py75
-rwxr-xr-xgit-send-email.perl31
-rw-r--r--git-sh-i18n.sh19
-rw-r--r--git-sh-setup.sh14
-rwxr-xr-xgit-stash.sh146
-rwxr-xr-xgit-submodule.sh274
-rwxr-xr-xgit-svn.perl553
-rwxr-xr-xgit-web--browse.sh10
-rw-r--r--git.c32
-rw-r--r--git.spec.in7
-rw-r--r--git_remote_helpers/git/exporter.py15
-rw-r--r--git_remote_helpers/git/git.py2
-rw-r--r--git_remote_helpers/git/importer.py32
-rw-r--r--git_remote_helpers/git/non_local.py20
-rw-r--r--git_remote_helpers/git/repo.py7
-rw-r--r--git_remote_helpers/util.py81
-rw-r--r--gitweb/INSTALL111
-rw-r--r--gitweb/Makefile8
-rw-r--r--gitweb/README434
-rwxr-xr-xgitweb/gitweb.perl676
-rw-r--r--gitweb/static/js/blame_incremental.js79
-rw-r--r--gitweb/static/js/javascript-detection.js8
-rw-r--r--graph.c2
-rw-r--r--grep.c122
-rw-r--r--grep.h5
-rw-r--r--help.c17
-rw-r--r--hex.c10
-rw-r--r--http-backend.c11
-rw-r--r--http-fetch.c6
-rw-r--r--http-push.c40
-rw-r--r--http.c174
-rw-r--r--http.h6
-rw-r--r--ident.c84
-rw-r--r--kwset.c771
-rw-r--r--kwset.h63
-rw-r--r--list-objects.c37
-rw-r--r--list-objects.h5
-rw-r--r--ll-merge.c4
-rw-r--r--log-tree.c52
-rw-r--r--mailmap.c5
-rw-r--r--merge-recursive.c1095
-rw-r--r--merge-recursive.h1
-rw-r--r--mergetools/araxis20
-rw-r--r--mergetools/bc325
-rw-r--r--mergetools/defaults46
-rw-r--r--mergetools/diffuse17
-rw-r--r--mergetools/ecmerge16
-rw-r--r--mergetools/emerge23
-rw-r--r--mergetools/kdiff324
-rw-r--r--mergetools/kompare7
-rw-r--r--mergetools/meld32
-rw-r--r--mergetools/opendiff16
-rw-r--r--mergetools/p4merge10
-rw-r--r--mergetools/tkdiff12
-rw-r--r--mergetools/tortoisemerge17
-rw-r--r--mergetools/vim44
-rw-r--r--mergetools/xxdiff25
-rw-r--r--name-hash.c17
-rw-r--r--notes-merge.c112
-rw-r--r--notes.c2
-rw-r--r--object.c2
-rw-r--r--pack-check.c32
-rw-r--r--pack-refs.c2
-rw-r--r--pack-write.c86
-rw-r--r--pack.h30
-rw-r--r--pager.c8
-rw-r--r--parse-options-cb.c130
-rw-r--r--parse-options.c112
-rw-r--r--parse-options.h22
-rw-r--r--path.c36
-rw-r--r--perl/.gitignore1
-rw-r--r--perl/Git.pm78
-rw-r--r--pretty.c10
-rw-r--r--quote.c31
-rw-r--r--quote.h13
-rw-r--r--reachable.c55
-rw-r--r--reachable.h3
-rw-r--r--read-cache.c150
-rw-r--r--refs.c819
-rw-r--r--refs.h38
-rw-r--r--remote-curl.c39
-rw-r--r--remote.c176
-rw-r--r--remote.h8
-rw-r--r--revision.c117
-rw-r--r--revision.h25
-rw-r--r--run-command.c48
-rw-r--r--sequencer.c19
-rw-r--r--sequencer.h20
-rw-r--r--setup.c46
-rw-r--r--sh-i18n--envsubst.c1
-rw-r--r--sha1_file.c305
-rw-r--r--sha1_name.c95
-rw-r--r--show-index.c2
-rw-r--r--strbuf.c25
-rw-r--r--strbuf.h17
-rw-r--r--streaming.c491
-rw-r--r--streaming.h15
-rw-r--r--string-list.c9
-rw-r--r--string-list.h1
-rw-r--r--submodule.c173
-rw-r--r--submodule.h3
-rwxr-xr-xt/aggregate-results.sh14
-rw-r--r--t/gitweb-lib.sh6
-rw-r--r--t/lib-diff-alternative.sh165
-rw-r--r--t/lib-git-p4.sh74
-rwxr-xr-xt/lib-gpg.sh34
-rw-r--r--t/lib-gpg/pubring.gpg (renamed from t/t7004/pubring.gpg)bin1164 -> 1164 bytes
-rw-r--r--t/lib-gpg/random_seed (renamed from t/t7004/random_seed)bin600 -> 600 bytes
-rw-r--r--t/lib-gpg/secring.gpg (renamed from t/t7004/secring.gpg)bin1237 -> 1237 bytes
-rw-r--r--t/lib-gpg/trustdb.gpg (renamed from t/t7004/trustdb.gpg)bin1280 -> 1280 bytes
-rw-r--r--t/lib-httpd.sh10
-rwxr-xr-xt/t0003-attributes.sh172
-rwxr-xr-xt/t0006-date.sh6
-rwxr-xr-xt/t0021-conversion.sh51
-rwxr-xr-xt/t0040-parse-options.sh19
-rwxr-xr-xt/t1011-read-tree-sparse-checkout.sh16
-rwxr-xr-xt/t1013-loose-object-format.sh66
-rw-r--r--t/t1013/objects/14/9cedb5c46929d18e0f118e9fa31927487af3b6bin0 -> 117 bytes
-rw-r--r--t/t1013/objects/16/56f9233d999f61ef23ef390b9c71d75399f435bin0 -> 17 bytes
-rw-r--r--t/t1013/objects/1e/72a6b2c4a577ab0338860fa9fe87f761fc9bbdbin0 -> 18 bytes
-rw-r--r--t/t1013/objects/25/7cc5642cb1a054f08cc83f2d943e56fd3ebe99bin0 -> 19 bytes
-rw-r--r--t/t1013/objects/2e/65efe2a145dda7ee51d1741299f848e5bf752ebin0 -> 10 bytes
-rw-r--r--t/t1013/objects/6b/aee0540ea990d9761a3eb9ab183003a71c3696bin0 -> 181 bytes
-rw-r--r--t/t1013/objects/70/e6a83d8dcb26fc8bc0cf702e2ddeb6adca18fdbin0 -> 26 bytes
-rw-r--r--t/t1013/objects/76/e7fa9941f4d5f97f64fea65a2cba436bc79cbb2
-rw-r--r--t/t1013/objects/78/75c6237d3fcdd0ac2f0decc7d3fa6a50b66c09bin0 -> 139 bytes
-rw-r--r--t/t1013/objects/7a/37b887a73791d12d26c0d3e39568a8fb0fa6e8bin0 -> 54 bytes
-rw-r--r--t/t1013/objects/85/df50785d62d3b05ab03d9cbf7e4a0b49449730bin0 -> 13 bytes
-rw-r--r--t/t1013/objects/8d/4e360d6c70fbd72411991c02a09c442cf7a9fabin0 -> 156 bytes
-rw-r--r--t/t1013/objects/95/b1625de3ba8b2214d1e0d0591138aea733f64fbin0 -> 252 bytes
-rw-r--r--t/t1013/objects/9a/e9e86b7bd6cb1472d9373702d8249973da0832bin0 -> 11 bytes
-rw-r--r--t/t1013/objects/bd/15045f6ce8ff75747562173640456a394412c8bin0 -> 34 bytes
-rw-r--r--t/t1013/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391bin0 -> 9 bytes
-rw-r--r--t/t1013/objects/f8/16d5255855ac160652ee5253b06cd8ee14165a1
-rwxr-xr-xt/t1020-subdirectory.sh20
-rwxr-xr-xt/t1300-repo-config.sh244
-rwxr-xr-xt/t1304-default-acl.sh5
-rwxr-xr-xt/t1402-check-ref-format.sh143
-rwxr-xr-xt/t1412-reflog-loop.sh8
-rwxr-xr-xt/t1450-fsck.sh36
-rwxr-xr-xt/t2018-checkout-branch.sh28
-rwxr-xr-xt/t2020-checkout-detach.sh7
-rwxr-xr-xt/t2022-checkout-paths.sh42
-rwxr-xr-xt/t3000-ls-files-others.sh19
-rwxr-xr-xt/t3005-ls-files-relative.sh72
-rwxr-xr-xt/t3030-merge-recursive.sh7
-rwxr-xr-xt/t3103-ls-tree-misc.sh24
-rwxr-xr-xt/t3200-branch.sh94
-rwxr-xr-xt/t3203-branch-output.sh28
-rwxr-xr-xt/t3307-notes-man.sh6
-rwxr-xr-xt/t3404-rebase-interactive.sh16
-rwxr-xr-xt/t3409-rebase-preserve-merges.sh28
-rwxr-xr-xt/t3411-rebase-preserve-around-merges.sh2
-rwxr-xr-xt/t3503-cherry-pick-root.sh27
-rwxr-xr-xt/t3507-cherry-pick-conflict.sh69
-rwxr-xr-xt/t3510-cherry-pick-sequence.sh331
-rwxr-xr-xt/t3900-i18n-commit.sh4
-rwxr-xr-xt/t3902-quoted.sh2
-rwxr-xr-xt/t3903-stash.sh2
-rwxr-xr-xt/t3905-stash-include-untracked.sh175
-rwxr-xr-xt/t4012-diff-binary.sh2
-rwxr-xr-xt/t4014-format-patch.sh39
-rwxr-xr-xt/t4018-diff-funcname.sh2
-rwxr-xr-xt/t4033-diff-patience.sh162
-rwxr-xr-xt/t4034-diff-words.sh1
-rw-r--r--t/t4034/matlab/expect14
-rw-r--r--t/t4034/matlab/post9
-rw-r--r--t/t4034/matlab/pre9
-rwxr-xr-xt/t4048-diff-combined-binary.sh212
-rwxr-xr-xt/t4049-diff-stat-count.sh25
-rwxr-xr-xt/t4050-diff-histogram.sh12
-rwxr-xr-xt/t4051-diff-function-context.sh92
-rwxr-xr-xt/t4150-am.sh20
-rwxr-xr-xt/t4151-am-abort.sh5
-rwxr-xr-xt/t4254-am-corrupt.sh43
-rwxr-xr-xt/t5000-tar-tree.sh100
-rwxr-xr-xt/t5001-archive-attr.sh9
-rwxr-xr-xt/t5302-pack-index.sh23
-rwxr-xr-xt/t5403-post-checkout-hook.sh46
-rwxr-xr-xt/t5501-fetch-push-alternates.sh2
-rwxr-xr-xt/t5504-fetch-receive-strict.sh104
-rwxr-xr-xt/t5505-remote.sh31
-rwxr-xr-xt/t5509-fetch-push-namespaces.sh85
-rwxr-xr-xt/t5510-fetch.sh50
-rwxr-xr-xt/t5516-fetch-push.sh197
-rwxr-xr-xt/t5526-fetch-submodules.sh16
-rwxr-xr-xt/t5531-deep-submodule-push.sh87
-rwxr-xr-xt/t5540-http-push.sh8
-rwxr-xr-xt/t5550-http-fetch.sh53
-rwxr-xr-xt/t5601-clone.sh41
-rwxr-xr-xt/t5700-clone-reference.sh7
-rwxr-xr-xt/t5707-clone-detached.sh76
-rwxr-xr-xt/t5708-clone-config.sh40
-rwxr-xr-xt/t5800-remote-helpers.sh93
-rwxr-xr-xt/t6019-rev-list-ancestry-path.sh38
-rwxr-xr-xt/t6020-merge-df.sh26
-rwxr-xr-xt/t6022-merge-rename.sh291
-rwxr-xr-xt/t6023-merge-file.sh2
-rwxr-xr-xt/t6027-merge-binary.sh2
-rwxr-xr-xt/t6030-bisect-porcelain.sh175
-rwxr-xr-xt/t6036-recursive-corner-cases.sh598
-rwxr-xr-xt/t6040-tracking-info.sh30
-rwxr-xr-xt/t6042-merge-rename-corner-cases.sh578
-rwxr-xr-xt/t6300-for-each-ref.sh101
-rwxr-xr-xt/t7004-tag.sh34
-rwxr-xr-xt/t7006-pager.sh102
-rwxr-xr-xt/t7008-grep-binary.sh4
-rwxr-xr-xt/t7102-reset.sh15
-rwxr-xr-xt/t7106-reset-sequence.sh52
-rwxr-xr-xt/t7400-submodule-basic.sh30
-rwxr-xr-xt/t7401-submodule-summary.sh12
-rwxr-xr-xt/t7403-submodule-sync.sh20
-rwxr-xr-xt/t7405-submodule-merge.sh51
-rwxr-xr-xt/t7406-submodule-update.sh315
-rwxr-xr-xt/t7407-submodule-foreach.sh125
-rwxr-xr-xt/t7408-submodule-reference.sh4
-rwxr-xr-xt/t7503-pre-commit-hook.sh33
-rwxr-xr-xt/t7508-status.sh121
-rwxr-xr-xt/t7511-status-index.sh50
-rwxr-xr-xt/t7600-merge.sh23
-rwxr-xr-xt/t7602-merge-octopus-many.sh6
-rwxr-xr-xt/t7607-merge-overwrite.sh1
-rwxr-xr-xt/t7609-merge-co-error-msgs.sh5
-rwxr-xr-xt/t7610-mergetool.sh58
-rwxr-xr-xt/t7800-difftool.sh46
-rwxr-xr-xt/t7810-grep.sh143
-rwxr-xr-xt/t8006-blame-textconv.sh11
-rwxr-xr-xt/t9001-send-email.sh29
-rwxr-xr-xt/t9158-git-svn-mergeinfo.sh13
-rwxr-xr-xt/t9159-git-svn-no-parent-mergeinfo.sh41
-rwxr-xr-xt/t9160-git-svn-preserve-empty-dirs.sh153
-rwxr-xr-xt/t9161-git-svn-mergeinfo-push.sh104
-rw-r--r--t/t9161/branches.dump374
-rwxr-xr-xt/t9162-git-svn-dcommit-interactive.sh64
-rwxr-xr-xt/t9200-git-cvsexportcommit.sh14
-rwxr-xr-xt/t9300-fast-import.sh333
-rwxr-xr-xt/t9350-fast-export.sh28
-rwxr-xr-xt/t9700-perl-git.sh6
-rwxr-xr-xt/t9700/test.pl4
-rwxr-xr-xt/t9800-git-p4.sh438
-rwxr-xr-xt/t9801-git-p4-branch.sh233
-rwxr-xr-xt/t9802-git-p4-filetype.sh139
-rwxr-xr-xt/t9803-git-shell-metachars.sh64
-rwxr-xr-xt/t9805-skip-submit-edit.sh82
-rwxr-xr-xt/t9901-git-web--browse.sh63
-rw-r--r--t/test-binary-1.png (renamed from t/test9200a.png)bin5660 -> 5660 bytes
-rw-r--r--t/test-binary-2.png (renamed from t/test9200b.png)bin275 -> 275 bytes
-rw-r--r--t/test-lib.sh50
-rw-r--r--t/test4012.pngbin5660 -> 0 bytes
-rwxr-xr-xtemplates/hooks--post-commit.sample8
-rwxr-xr-xtemplates/hooks--post-receive.sample15
-rwxr-xr-xtemplates/hooks--pre-commit.sample8
-rw-r--r--test-ctype.c80
-rw-r--r--test-parse-options.c7
-rw-r--r--test-path-utils.c22
-rw-r--r--transport-helper.c259
-rw-r--r--transport.c34
-rw-r--r--transport.h1
-rw-r--r--tree-diff.c22
-rw-r--r--tree-walk.c124
-rw-r--r--tree-walk.h19
-rw-r--r--tree.c11
-rw-r--r--unpack-trees.c49
-rw-r--r--unpack-trees.h2
-rw-r--r--upload-pack.c143
-rw-r--r--url.c58
-rw-r--r--url.h1
-rw-r--r--usage.c18
-rw-r--r--userdiff.c22
-rw-r--r--userdiff.h2
-rw-r--r--walker.c2
-rw-r--r--ws.c2
-rw-r--r--wt-status.c10
-rw-r--r--xdiff/xdiff.h3
-rw-r--r--xdiff/xdiffi.c3
-rw-r--r--xdiff/xdiffi.h2
-rw-r--r--xdiff/xemit.c85
-rw-r--r--xdiff/xhistogram.c363
-rw-r--r--xdiff/xpatience.c27
-rw-r--r--xdiff/xprepare.c219
-rw-r--r--xdiff/xutils.c51
-rw-r--r--xdiff/xutils.h4
-rw-r--r--zlib.c256
605 files changed, 28183 insertions, 7715 deletions
diff --git a/.gitignore b/.gitignore
index acffdfa..8572c8c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
/GIT-BUILD-OPTIONS
/GIT-CFLAGS
+/GIT-LDFLAGS
/GIT-GUI-VARS
/GIT-VERSION-FILE
/bin-wrappers/
diff --git a/Documentation/.gitignore b/Documentation/.gitignore
index 1c3a9fe..d62aebd 100644
--- a/Documentation/.gitignore
+++ b/Documentation/.gitignore
@@ -3,6 +3,7 @@
*.[1-8]
*.made
*.texi
+*.pdf
git.info
gitman.info
howto-index.txt
diff --git a/Documentation/Makefile b/Documentation/Makefile
index 36989b7..304b31e 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -1,12 +1,12 @@
MAN1_TXT= \
$(filter-out $(addsuffix .txt, $(ARTICLES) $(SP_ARTICLES)), \
$(wildcard git-*.txt)) \
- gitk.txt git.txt
+ gitk.txt gitweb.txt git.txt
MAN5_TXT=gitattributes.txt gitignore.txt gitmodules.txt githooks.txt \
- gitrepository-layout.txt
+ gitrepository-layout.txt gitweb.conf.txt
MAN7_TXT=gitcli.txt gittutorial.txt gittutorial-2.txt \
gitcvs-migration.txt gitcore-tutorial.txt gitglossary.txt \
- gitdiffcore.txt gitrevisions.txt gitworkflows.txt
+ gitdiffcore.txt gitnamespaces.txt gitrevisions.txt gitworkflows.txt
MAN_TXT = $(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT)
MAN_XML=$(patsubst %.txt,%.xml,$(MAN_TXT))
@@ -46,8 +46,8 @@ MANPAGE_XSL = manpage-normal.xsl
XMLTO_EXTRA =
INSTALL?=install
RM ?= rm -f
-DOC_REF = origin/man
-HTML_REF = origin/html
+MAN_REPO = ../../git-manpages
+HTML_REPO = ../../git-htmldocs
infodir?=$(prefix)/share/info
MAKEINFO=makeinfo
@@ -232,6 +232,7 @@ cmd-list.made: cmd-list.perl ../command-list.txt $(MAN1_TXT)
clean:
$(RM) *.xml *.xml+ *.html *.html+ *.1 *.5 *.7
$(RM) *.texi *.texi+ *.texi++ git.info gitman.info
+ $(RM) *.pdf
$(RM) howto-index.txt howto/*.html doc.dep
$(RM) technical/api-*.html technical/api-index.txt
$(RM) $(cmds_txt) *.made
@@ -326,12 +327,23 @@ $(patsubst %.txt,%.html,$(wildcard howto/*.txt)): %.html : %.txt
install-webdoc : html
'$(SHELL_PATH_SQ)' ./install-webdoc.sh $(WEBDOC_DEST)
+# You must have a clone of git-htmldocs and git-manpages repositories
+# next to the git repository itself for the following to work.
+
quick-install: quick-install-man
-quick-install-man:
- '$(SHELL_PATH_SQ)' ./install-doc-quick.sh $(DOC_REF) $(DESTDIR)$(mandir)
+require-manrepo::
+ @if test ! -d $(MAN_REPO); \
+ then echo "git-manpages repository must exist at $(MAN_REPO)"; exit 1; fi
+
+quick-install-man: require-manrepo
+ '$(SHELL_PATH_SQ)' ./install-doc-quick.sh $(MAN_REPO) $(DESTDIR)$(mandir)
+
+require-htmlrepo::
+ @if test ! -d $(HTML_REPO); \
+ then echo "git-htmldocs repository must exist at $(HTML_REPO)"; exit 1; fi
-quick-install-html:
- '$(SHELL_PATH_SQ)' ./install-doc-quick.sh $(HTML_REF) $(DESTDIR)$(htmldir)
+quick-install-html: require-htmlrepo
+ '$(SHELL_PATH_SQ)' ./install-doc-quick.sh $(HTML_REPO) $(DESTDIR)$(htmldir)
.PHONY: FORCE
diff --git a/Documentation/RelNotes/1.7.6.1.txt b/Documentation/RelNotes/1.7.6.1.txt
new file mode 100644
index 0000000..42e46ab
--- /dev/null
+++ b/Documentation/RelNotes/1.7.6.1.txt
@@ -0,0 +1,63 @@
+Git v1.7.6.1 Release Notes
+==========================
+
+Fixes since v1.7.6
+------------------
+
+ * Various codepaths that invoked zlib deflate/inflate assumed that these
+ functions can compress or uncompress more than 4GB data in one call on
+ platforms with 64-bit long, which has been corrected.
+
+ * "git unexecutable" reported that "unexecutable" was not found, even
+ though the actual error was that "unexecutable" was found but did
+ not have a proper she-bang line to be executed.
+
+ * Error exits from $PAGER were silently ignored.
+
+ * "git checkout -b <branch>" was confused when attempting to create a
+ branch whose name ends with "-g" followed by hexadecimal digits,
+ and refused to work.
+
+ * "git checkout -b <branch>" sometimes wrote a bogus reflog entry,
+ causing later "git checkout -" to fail.
+
+ * "git diff --cc" learned to correctly ignore binary files.
+
+ * "git diff -c/--cc" mishandled a deletion that resolves a conflict, and
+ looked in the working tree instead.
+
+ * "git fast-export" forgot to quote pathnames with unsafe characters
+ in its output.
+
+ * "git fetch" over smart-http transport used to abort when the
+ repository was updated between the initial connection and the
+ subsequent object transfer.
+
+ * "git fetch" did not recurse into submodules in subdirectories.
+
+ * "git ls-tree" did not error out when asked to show a corrupt tree.
+
+ * "git pull" without any argument left an extra whitespace after the
+ command name in its reflog.
+
+ * "git push --quiet" was not really quiet.
+
+ * "git rebase -i -p" incorrectly dropped commits from side branches.
+
+ * "git reset [<commit>] paths..." did not reset the index entry correctly
+ for unmerged paths.
+
+ * "git submodule add" did not allow a relative repository path when
+ the superproject did not have any default remote url.
+
+ * "git submodule foreach" failed to correctly give the standard input to
+ the user-supplied command it invoked.
+
+ * submodules that the user has never showed interest in by running
+ "git submodule init" was incorrectly marked as interesting by "git
+ submodule sync".
+
+ * "git submodule update --quiet" was not really quiet.
+
+ * "git tag -l <glob>..." did not take multiple glob patterns from the
+ command line.
diff --git a/Documentation/RelNotes/1.7.6.2.txt b/Documentation/RelNotes/1.7.6.2.txt
new file mode 100644
index 0000000..67ae414
--- /dev/null
+++ b/Documentation/RelNotes/1.7.6.2.txt
@@ -0,0 +1,8 @@
+Git v1.7.6.2 Release Notes
+==========================
+
+Fixes since v1.7.6.1
+--------------------
+
+ * v1.7.6.1 broke "git push --quiet"; it used to be a no-op against an old
+ version of Git running on the other end, but v1.7.6.1 made it abort.
diff --git a/Documentation/RelNotes/1.7.6.3.txt b/Documentation/RelNotes/1.7.6.3.txt
new file mode 100644
index 0000000..9597183
--- /dev/null
+++ b/Documentation/RelNotes/1.7.6.3.txt
@@ -0,0 +1,24 @@
+Git v1.7.6.3 Release Notes
+==========================
+
+Fixes since v1.7.6.2
+--------------------
+
+ * "git -c var=value subcmd" misparsed the custom configuration when
+ value contained an equal sign.
+
+ * "git fetch" had a major performance regression, wasting many
+ needless cycles in a repository where there is no submodules
+ present. This was especially bad, when there were many refs.
+
+ * "git reflog $refname" did not default to the "show" subcommand as
+ the documentation advertised the command to do.
+
+ * "git reset" did not leave meaningful log message in the reflog.
+
+ * "git status --ignored" did not show ignored items when there is no
+ untracked items.
+
+ * "git tag --contains $commit" was unnecessarily inefficient.
+
+Also contains minor fixes and documentation updates.
diff --git a/Documentation/RelNotes/1.7.6.4.txt b/Documentation/RelNotes/1.7.6.4.txt
new file mode 100644
index 0000000..e19acac
--- /dev/null
+++ b/Documentation/RelNotes/1.7.6.4.txt
@@ -0,0 +1,32 @@
+Git v1.7.6.4 Release Notes
+==========================
+
+Fixes since v1.7.6.3
+--------------------
+
+ * The error reporting logic of "git am" when the command is fed a file
+ whose mail-storage format is unknown was fixed.
+
+ * "git branch --set-upstream @{-1} foo" did not expand @{-1} correctly.
+
+ * "git check-ref-format --print" used to parrot a candidate string that
+ began with a slash (e.g. /refs/heads/master) without stripping it, to make
+ the result a suitably normalized string the caller can append to "$GIT_DIR/".
+
+ * "git clone" failed to clone locally from a ".git" file that itself
+ is not a directory but is a pointer to one.
+
+ * "git clone" from a local repository that borrows from another
+ object store using a relative path in its objects/info/alternates
+ file did not adjust the alternates in the resulting repository.
+
+ * "git describe --dirty" did not refresh the index before checking the
+ state of the working tree files.
+
+ * "git ls-files ../$path" that is run from a subdirectory reported errors
+ incorrectly when there is no such path that matches the given pathspec.
+
+ * "git mergetool" could loop forever prompting when nothing can be read
+ from the standard input.
+
+Also contains minor fixes and documentation updates.
diff --git a/Documentation/RelNotes/1.7.7.1.txt b/Documentation/RelNotes/1.7.7.1.txt
new file mode 100644
index 0000000..ac9b838
--- /dev/null
+++ b/Documentation/RelNotes/1.7.7.1.txt
@@ -0,0 +1,60 @@
+Git v1.7.7.1 Release Notes
+==========================
+
+Fixes since v1.7.7
+------------------
+
+ * On some BSD systems, adding +s bit on directories is detrimental
+ (it is not necessary on BSD to begin with). "git init --shared"
+ has been updated to take this into account without extra makefile
+ settings on platforms the Makefile knows about.
+
+ * After incorrectly written third-party tools store a tag object in
+ HEAD, git diagnosed it as a repository corruption and refused to
+ proceed in order to avoid spreading the damage. We now gracefully
+ recover from such a situation by pretending as if the commit that
+ is pointed at by the tag were in HEAD.
+
+ * "git apply --whitespace=error" did not bother to report the exact
+ line number in the patch that introduced new blank lines at the end
+ of the file.
+
+ * "git apply --index" did not check corrupted patch.
+
+ * "git checkout $tree $directory/" resurrected paths locally removed or
+ modified only in the working tree in $directory/ that did not appear
+ in $directory of the given $tree. They should have been kept intact.
+
+ * "git diff $tree $path" used to apply the pathspec at the output stage,
+ reading the whole tree, wasting resources.
+
+ * The code to check for updated submodules during a "git fetch" of the
+ superproject had an unnecessary quadratic loop.
+
+ * "git fetch" from a large bundle did not enable the progress output.
+
+ * When "git fsck --lost-and-found" found that an empty blob object in the
+ object store is unreachable, it incorrectly reported an error after
+ writing the lost blob out successfully.
+
+ * "git filter-branch" did not refresh the index before checking that the
+ working tree was clean.
+
+ * "git grep $tree" when run with multiple threads had an unsafe access to
+ the object database that should have been protected with mutex.
+
+ * The "--ancestry-path" option to "git log" and friends misbehaved in a
+ history with complex criss-cross merges and showed an uninteresting
+ side history as well.
+
+ * Test t1304 assumed LOGNAME is always set, which may not be true on
+ some systems.
+
+ * Tests with --valgrind failed to find "mergetool" scriptlets.
+
+ * "git patch-id" miscomputed the patch-id in a patch that has a line longer
+ than 1kB.
+
+ * When an "exec" insn failed after modifying the index and/or the working
+ tree during "rebase -i", we now check and warn that the changes need to
+ be cleaned up.
diff --git a/Documentation/RelNotes/1.7.7.2.txt b/Documentation/RelNotes/1.7.7.2.txt
new file mode 100644
index 0000000..e6bbef2
--- /dev/null
+++ b/Documentation/RelNotes/1.7.7.2.txt
@@ -0,0 +1,44 @@
+Git v1.7.7.2 Release Notes
+==========================
+
+Fixes since v1.7.7.1
+--------------------
+
+ * We used to drop error messages from libcurl on certain kinds of
+ errors.
+
+ * Error report from smart HTTP transport, when the connection was
+ broken in the middle of a transfer, showed a useless message on
+ a corrupt packet.
+
+ * "git fetch --prune" was unsafe when used with refspecs from the
+ command line.
+
+ * The attribute mechanism did not use case insensitive match when
+ core.ignorecase was set.
+
+ * "git bisect" did not notice when it failed to update the working tree
+ to the next commit to be tested.
+
+ * "git config --bool --get-regexp" failed to separate the variable name
+ and its value "true" when the variable is defined without "= true".
+
+ * "git remote rename $a $b" were not careful to match the remote name
+ against $a (i.e. source side of the remote nickname).
+
+ * "git mergetool" did not use its arguments as pathspec, but as a path to
+ the file that may not even have any conflict.
+
+ * "git diff --[num]stat" used to use the number of lines of context
+ different from the default, potentially giving different results from
+ "git diff | diffstat" and confusing the users.
+
+ * "git pull" and "git rebase" did not work well even when GIT_WORK_TREE is
+ set correctly with GIT_DIR if the current directory is outside the working
+ tree.
+
+ * "git send-email" did not honor the configured hostname when restarting
+ the HELO/EHLO exchange after switching TLS on.
+
+ * "gitweb" used to produce a non-working link while showing the contents
+ of a blob, when JavaScript actions are enabled.
diff --git a/Documentation/RelNotes/1.7.7.3.txt b/Documentation/RelNotes/1.7.7.3.txt
new file mode 100644
index 0000000..09301f0
--- /dev/null
+++ b/Documentation/RelNotes/1.7.7.3.txt
@@ -0,0 +1,19 @@
+Git v1.7.7.3 Release Notes
+==========================
+
+Fixes since v1.7.7.2
+--------------------
+
+ * Adjust the "quick-install-doc" procedures as preformatted
+ html/manpage are no longer in the source repository.
+
+ * The logic to optimize the locality of the data in a pack introduced in
+ 1.7.7 was grossly inefficient.
+
+ * The logic to filter out forked projects in the project list in
+ "gitweb" was broken for some time.
+
+ * "git branch -m/-M" advertised to update RENAME_REF ref in the
+ commit log message that introduced the feature but not anywhere in
+ the documentation, and never did update such a ref anyway. This
+ undocumented misfeature that did not exist has been excised.
diff --git a/Documentation/RelNotes/1.7.7.4.txt b/Documentation/RelNotes/1.7.7.4.txt
new file mode 100644
index 0000000..e523448
--- /dev/null
+++ b/Documentation/RelNotes/1.7.7.4.txt
@@ -0,0 +1,14 @@
+Git v1.7.7.4 Release Notes
+==========================
+
+Fixes since v1.7.7.3
+--------------------
+
+ * A few header dependencies were missing from the Makefile.
+
+ * Some newer parts of the code used C99 __VA_ARGS__ while we still
+ try to cater to older compilers.
+
+ * "git name-rev --all" tried to name all _objects_, naturally failing to
+ describe many blobs and trees, instead of showing only commits as
+ advertised in its documentation.
diff --git a/Documentation/RelNotes/1.7.7.txt b/Documentation/RelNotes/1.7.7.txt
new file mode 100644
index 0000000..7655ccc
--- /dev/null
+++ b/Documentation/RelNotes/1.7.7.txt
@@ -0,0 +1,134 @@
+Git v1.7.7 Release Notes
+========================
+
+Updates since v1.7.6
+--------------------
+
+ * The scripting part of the codebase is getting prepared for i18n/l10n.
+
+ * Interix, Cygwin and Minix ports got updated.
+
+ * Various updates to git-p4 (in contrib/), fast-import, and git-svn.
+
+ * Gitweb learned to read from /etc/gitweb-common.conf when it exists,
+ before reading from gitweb_config.perl or from /etc/gitweb.conf
+ (this last one is read only when per-repository gitweb_config.perl
+ does not exist).
+
+ * Various codepaths that invoked zlib deflate/inflate assumed that these
+ functions can compress or uncompress more than 4GB data in one call on
+ platforms with 64-bit long, which has been corrected.
+
+ * Git now recognizes loose objects written by other implementations that
+ use a non-standard window size for zlib deflation (e.g. Agit running on
+ Android with 4kb window). We used to reject anything that was not
+ deflated with 32kb window.
+
+ * Interaction between the use of pager and coloring of the output has
+ been improved, especially when a command that is not built-in was
+ involved.
+
+ * "git am" learned to pass the "--exclude=<path>" option through to underlying
+ "git apply".
+
+ * You can now feed many empty lines before feeding an mbox file to
+ "git am".
+
+ * "git archive" can be told to pass the output to gzip compression and
+ produce "archive.tar.gz".
+
+ * "git bisect" can be used in a bare repository (provided that the test
+ you perform per each iteration does not need a working tree, of
+ course).
+
+ * The length of abbreviated object names in "git branch -v" output
+ now honors the core.abbrev configuration variable.
+
+ * "git check-attr" can take relative paths from the command line.
+
+ * "git check-attr" learned an "--all" option to list the attributes for a
+ given path.
+
+ * "git checkout" (both the code to update the files upon checking out a
+ different branch and the code to checkout a specific set of files) learned
+ to stream the data from object store when possible, without having to
+ read the entire contents of a file into memory first. An earlier round
+ of this code that is not in any released version had a large leak but
+ now it has been plugged.
+
+ * "git clone" can now take a "--config key=value" option to set the
+ repository configuration options that affect the initial checkout.
+
+ * "git commit <paths>..." now lets you feed relative pathspecs that
+ refer to outside your current subdirectory.
+
+ * "git diff --stat" learned a --stat-count option to limit the output of
+ a diffstat report.
+
+ * "git diff" learned a "--histogram" option to use a different diff
+ generation machinery stolen from jgit, which might give better
+ performance.
+
+ * "git diff" had a weird worst case behaviour that can be triggered
+ when comparing files with potentially many places that could match.
+
+ * "git fetch", "git push" and friends no longer show connection
+ errors for addresses that couldn't be connected to when at least one
+ address succeeds (this is arguably a regression but a deliberate
+ one).
+
+ * "git grep" learned "--break" and "--heading" options, to let users mimic
+ the output format of "ack".
+
+ * "git grep" learned a "-W" option that shows wider context using the same
+ logic used by "git diff" to determine the hunk header.
+
+ * Invoking the low-level "git http-fetch" without "-a" option (which
+ git itself never did---normal users should not have to worry about
+ this) is now deprecated.
+
+ * The "--decorate" option to "git log" and its family learned to
+ highlight grafted and replaced commits.
+
+ * "git rebase master topci" no longer spews usage hints after giving
+ the "fatal: no such branch: topci" error message.
+
+ * The recursive merge strategy implementation got a fairly large
+ fix for many corner cases that may rarely happen in real world
+ projects (it has been verified that none of the 16000+ merges in
+ the Linux kernel history back to v2.6.12 is affected with the
+ corner case bugs this update fixes).
+
+ * "git stash" learned an "--include-untracked option".
+
+ * "git submodule update" used to stop at the first error updating a
+ submodule; it now goes on to update other submodules that can be
+ updated, and reports the ones with errors at the end.
+
+ * "git push" can be told with the "--recurse-submodules=check" option to
+ refuse pushing of the supermodule, if any of its submodules'
+ commits hasn't been pushed out to their remotes.
+
+ * "git upload-pack" and "git receive-pack" learned to pretend that only a
+ subset of the refs exist in a repository. This may help a site to
+ put many tiny repositories into one repository (this would not be
+ useful for larger repositories as repacking would be problematic).
+
+ * "git verify-pack" has been rewritten to use the "index-pack" machinery
+ that is more efficient in reading objects in packfiles.
+
+ * test scripts for gitweb tried to run even when CGI-related perl modules
+ are not installed; they now exit early when the latter are unavailable.
+
+Also contains various documentation updates and minor miscellaneous
+changes.
+
+
+Fixes since v1.7.6
+------------------
+
+Unless otherwise noted, all fixes in the 1.7.6.X maintenance track are
+included in this release.
+
+ * "git branch -m" and "git checkout -b" incorrectly allowed the tip
+ of the branch that is currently checked out updated.
diff --git a/Documentation/RelNotes/1.7.8.txt b/Documentation/RelNotes/1.7.8.txt
new file mode 100644
index 0000000..b4d90bb
--- /dev/null
+++ b/Documentation/RelNotes/1.7.8.txt
@@ -0,0 +1,161 @@
+Git v1.7.8 Release Notes
+========================
+
+Updates since v1.7.7
+--------------------
+
+ * Some git-svn, git-gui, git-p4 (in contrib) and msysgit updates.
+
+ * Updates to bash completion scripts.
+
+ * The build procedure has been taught to take advantage of computed
+ dependency automatically when the complier supports it.
+
+ * The date parser now accepts timezone designators that lack minutes
+ part and also has a colon between "hh:mm".
+
+ * The contents of the /etc/mailname file, if exists, is used as the
+ default value of the hostname part of the committer/author e-mail.
+
+ * "git am" learned how to read from patches generated by Hg.
+
+ * "git archive" talking with a remote repository can report errors
+ from the remote side in a more informative way.
+
+ * "git branch" learned an explicit --list option to ask for branches
+ listed, optionally with a glob matching pattern to limit its output.
+
+ * "git check-attr" learned "--cached" option to look at .gitattributes
+ files from the index, not from the working tree.
+
+ * Variants of "git cherry-pick" and "git revert" that take multiple
+ commits learned to "--continue" and "--abort".
+
+ * "git daemon" gives more human readble error messages to clients
+ using ERR packets when appropriate.
+
+ * Errors at the network layer is logged by "git daemon".
+
+ * "git diff" learned "--minimal" option to spend extra cycles to come
+ up with a minimal patch output.
+
+ * "git diff" learned "--function-context" option to show the whole
+ function as context that was affected by a change.
+
+ * "git difftool" can be told to skip launching the tool for a path by
+ answering 'n' to its prompt.
+
+ * "git fetch" learned to honor transfer.fsckobjects configuration to
+ validate the objects that were received from the other end, just like
+ "git receive-pack" (the receiving end of "git push") does.
+
+ * "git fetch" makes sure that the set of objects it received from the
+ other end actually completes the history before updating the refs.
+ "git receive-pack" (the receiving end of "git push") learned to do the
+ same.
+
+ * "git fetch" learned that fetching/cloning from a regular file on the
+ filesystem is not necessarily a request to unpack a bundle file; the
+ file could be ".git" with "gitdir: <path>" in it.
+
+ * "git for-each-ref" learned "%(contents:subject)", "%(contents:body)"
+ and "%(contents:signature)". The last one is useful for signed tags.
+
+ * "git grep" used to incorrectly pay attention to .gitignore files
+ scattered in the directory it was working in even when "--no-index"
+ option was used. It no longer does this. The "--exclude-standard"
+ option needs to be given to explicitly activate the ignore
+ mechanism.
+
+ * "git grep" learned "--untracked" option, where given patterns are
+ searched in untracked (but not ignored) files as well as tracked
+ files in the working tree, so that matches in new but not yet
+ added files do not get missed.
+
+ * The recursive merge backend no longer looks for meaningless
+ existing merges in submodules unless in the outermost merge.
+
+ * "git log" and friends learned "--children" option.
+
+ * "git ls-remote" learned to respond to "-h"(elp) requests.
+
+ * "mediawiki" remote helper can interact with (surprise!) MediaWiki
+ with "git fetch" & "git push".
+
+ * "git merge" learned the "--edit" option to allow users to edit the
+ merge commit log message.
+
+ * "git rebase -i" can be told to use special purpose editor suitable
+ only for its insn sheet via sequence.editor configuration variable.
+
+ * "git send-email" learned to respond to "-h"(elp) requests.
+
+ * "git send-email" allows the value given to sendemail.aliasfile to begin
+ with "~/" to refer to the $HOME directory.
+
+ * "git send-email" forces use of Authen::SASL::Perl to work around
+ issues between Authen::SASL::Cyrus and AUTH PLAIN/LOGIN.
+
+ * "git stash" learned "--include-untracked" option to stash away
+ untracked/ignored cruft from the working tree.
+
+ * "git submodule clone" does not leak an error message to the UI
+ level unnecessarily anymore.
+
+ * "git submodule update" learned to honor "none" as the value for
+ submodule.<name>.update to specify that the named submodule should
+ not be checked out by default.
+
+ * When populating a new submodule directory with "git submodule init",
+ the $GIT_DIR metainformation directory for submodules is created inside
+ $GIT_DIR/modules/<name>/ directory of the superproject and referenced
+ via the gitfile mechanism. This is to make it possible to switch
+ between commits in the superproject that has and does not have the
+ submodule in the tree without re-cloning.
+
+ * "gitweb" leaked unescaped control characters from syntax hiliter
+ outputs.
+
+ * "gitweb" can be told to give custom string at the end of the HTML
+ HEAD element.
+
+ * "gitweb" now has its own manual pages.
+
+
+Also contains other documentation updates and minor code cleanups.
+
+
+Fixes since v1.7.7
+------------------
+
+Unless otherwise noted, all fixes in the 1.7.7.X maintenance track are
+included in this release.
+
+ * HTTP transport did not use pushurl correctly, and also did not tell
+ what host it is trying to authenticate with when asking for
+ credentials.
+ (merge deba493 jk/http-auth later to maint).
+
+ * "git blame" was aborted if started from an uncommitted content and
+ the path had the textconv filter in effect.
+ (merge 8518088 ss/blame-textconv-fake-working-tree later to maint).
+
+ * Adding many refs to the local repository in one go (e.g. "git fetch"
+ that fetches many tags) and looking up a ref by name in a repository
+ with too many refs were unnecessarily slow.
+ (merge 17d68a54d jp/get-ref-dir-unsorted later to maint).
+
+ * Report from "git commit" on untracked files was confused under
+ core.ignorecase option.
+ (merge 395c7356 jk/name-hash-dirent later to maint).
+
+ * "git merge" did not understand ":/<pattern>" as a way to name a commit.
+
+ " "git push" on the receiving end used to call post-receive and post-update
+ hooks for attempted removal of non-existing refs.
+ (merge 160b81ed ph/push-to-delete-nothing later to maint).
+
+ * Help text for "git remote set-url" and "git remote set-branches"
+ were misspelled.
+ (merge c49904e fc/remote-seturl-usage-fix later to maint).
+ (merge 656cdf0 jc/remote-setbranches-usage-fix later to maint).
diff --git a/Documentation/RelNotes/1.7.9.txt b/Documentation/RelNotes/1.7.9.txt
new file mode 100644
index 0000000..7f05936
--- /dev/null
+++ b/Documentation/RelNotes/1.7.9.txt
@@ -0,0 +1,27 @@
+Git v1.7.9 Release Notes (draft)
+========================
+
+Updates since v1.7.8
+--------------------
+
+ * Porcelain commands like "git reset" did not distinguish deletions
+ and type-changes from ordinary modification, and reported them with
+ the same 'M' moniker. They now use 'D' (for deletion) and 'T' (for
+ type-change) to match "git status -s" and "git diff --name-status".
+
+ * fsck and prune are relatively lengthy operations that still go
+ silent while making the end-user wait. They learned to give progress
+ output like other slow operations.
+
+ * The set of built-in function-header patterns for various languages
+ knows MATLAB.
+
+May also contain documentation updates and code clean-ups.
+
+
+Fixes since v1.7.8
+------------------
+
+ * In some codepaths (notably, checkout and merge), the ignore patterns
+ recorded in $GIT_DIR/info/exclude were not honored. They now are.
+ (merge fc001b5 nd/maint-ignore-exclude later to maint).
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
index 938eccf..0dbf2c9 100644
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -134,8 +134,7 @@ Another thing: NULL pointers shall be written as NULL, not as 0.
(2) Generate your patch using git tools out of your commits.
-git based diff tools (git, Cogito, and StGIT included) generate
-unidiff which is the preferred format.
+git based diff tools generate unidiff which is the preferred format.
You do not have to be afraid to use -M option to "git diff" or
"git format-patch", if your patch involves file renames. The
diff --git a/Documentation/blame-options.txt b/Documentation/blame-options.txt
index e76195a..d4a51da 100644
--- a/Documentation/blame-options.txt
+++ b/Documentation/blame-options.txt
@@ -117,5 +117,4 @@ commit. And the default value is 40. If there are more than one
take effect.
-h::
---help::
Show help message.
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 256d27c..8a7d2d4 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -45,9 +45,10 @@ lines. Variables may belong directly to a section or to a given subsection.
You can have `[section]` if you have `[section "subsection"]`, but you
don't need to.
-There is also a case insensitive alternative `[section.subsection]` syntax.
-In this syntax, subsection names follow the same restrictions as for section
-names.
+There is also a deprecated `[section.subsection]` syntax. With this
+syntax, the subsection name is converted to lower-case and is also
+compared case sensitively. These subsection names follow the same
+restrictions as section names.
All the other lines (and the remainder of the line after the section
header) are recognized as setting variables, in the form
@@ -147,7 +148,7 @@ advice.*::
core.fileMode::
If false, the executable bit differences between the index and
- the working copy are ignored; useful on broken filesystems like FAT.
+ the working tree are ignored; useful on broken filesystems like FAT.
See linkgit:git-update-index[1].
+
The default is true, except linkgit:git-clone[1] or linkgit:git-init[1]
@@ -179,7 +180,7 @@ is created.
core.trustctime::
If false, the ctime differences between the index and the
- working copy are ignored; useful when the inode change time
+ working tree are ignored; useful when the inode change time
is regularly modified by something outside Git (file system
crawlers and some backup systems).
See linkgit:git-update-index[1]. True by default.
@@ -292,7 +293,7 @@ core.ignoreStat::
If true, commands which modify both the working tree and the index
will mark the updated paths with the "assume unchanged" bit in the
index. These marked files are then assumed to stay unchanged in the
- working copy, until you mark them otherwise manually - Git will not
+ working tree, until you mark them otherwise manually - Git will not
detect the file changes by lstat() calls. This is useful on systems
where those are very slow, such as Microsoft Windows.
See linkgit:git-update-index[1].
@@ -344,7 +345,9 @@ core.logAllRefUpdates::
SHA1, the date/time and the reason of the update, but
only when the file exists. If this configuration
variable is set to true, missing "$GIT_DIR/logs/<ref>"
- file is automatically created for branch heads.
+ file is automatically created for branch heads (i.e. under
+ refs/heads/), remote refs (i.e. under refs/remotes/),
+ note refs (i.e. under refs/notes/), and the symbolic ref HEAD.
+
This information can be used to determine what commit
was the tip of a branch "2 days ago".
@@ -471,6 +474,12 @@ core.editor::
variable when it is set, and the environment variable
`GIT_EDITOR` is not set. See linkgit:git-var[1].
+sequence.editor::
+ Text editor used by `git rebase -i` for editing the rebase insn file.
+ The value is meant to be interpreted by the shell when it is used.
+ It can be overridden by the `GIT_SEQUENCE_EDITOR` environment variable.
+ When not configured the default commit message editor is used instead.
+
core.pager::
The command that git will use to paginate output. Can
be overridden with the `GIT_PAGER` environment
@@ -678,7 +687,7 @@ for details).
browser.<tool>.cmd::
Specify the command to invoke the specified browser. The
specified command is evaluated in shell with the URLs passed
- as arguments. (See linkgit:git-web--browse[1].)
+ as arguments. (See linkgit:git-web{litdd}browse[1].)
browser.<tool>.path::
Override the path for the given tool that may be used to
@@ -857,6 +866,13 @@ fetch.recurseSubmodules::
when its superproject retrieves a commit that updates the submodule's
reference.
+fetch.fsckObjects::
+ If it is set to true, git-fetch-pack will check all fetched
+ objects. It will abort in the case of a malformed object or a
+ broken link. The result of an abort are only dangling objects.
+ Defaults to false. If not set, the value of `transfer.fsckObjects`
+ is used instead.
+
fetch.unpackLimit::
If the number of objects fetched over the git native
transfer is below this
@@ -1064,6 +1080,23 @@ All gitcvs variables except for 'gitcvs.usecrlfattr' and
is one of "ext" and "pserver") to make them apply only for the given
access method.
+gitweb.category::
+gitweb.description::
+gitweb.owner::
+gitweb.url::
+ See linkgit:gitweb[1] for description.
+
+gitweb.avatar::
+gitweb.blame::
+gitweb.grep::
+gitweb.highlight::
+gitweb.patches::
+gitweb.pickaxe::
+gitweb.remote_heads::
+gitweb.showsizes::
+gitweb.snapshot::
+ See linkgit:gitweb.conf[5] for description.
+
grep.lineNumber::
If set to true, enable '-n' option by default.
@@ -1198,6 +1231,14 @@ http.proxy::
environment variable (see linkgit:curl[1]). This can be overridden
on a per-remote basis; see remote.<name>.proxy
+http.cookiefile::
+ File containing previously stored cookie lines which should be used
+ in the git http session, if they match the server. The file format
+ of the file to read cookies from should be plain HTTP headers or
+ the Netscape/Mozilla cookie file format (see linkgit:curl[1]).
+ NOTE that the file specified with http.cookiefile is only used as
+ input. No cookies will be stored in the file.
+
http.sslVerify::
Whether to verify the SSL certificate when fetching or pushing
over HTTPS. Can be overridden by the 'GIT_SSL_NO_VERIFY' environment
@@ -1445,7 +1486,8 @@ notes.rewriteRef::
You may also specify this configuration several times.
+
Does not have a default value; you must configure this variable to
-enable note rewriting.
+enable note rewriting. Set it to `refs/notes/commits` to enable
+rewriting for the default commit notes.
+
This setting can be overridden with the `GIT_NOTES_REWRITE_REF`
environment variable, which must be a colon separated list of refs or
@@ -1597,7 +1639,8 @@ receive.fsckObjects::
If it is set to true, git-receive-pack will check all received
objects. It will abort in the case of a malformed object or a
broken link. The result of an abort are only dangling objects.
- Defaults to false.
+ Defaults to false. If not set, the value of `transfer.fsckObjects`
+ is used instead.
receive.unpackLimit::
If the number of objects received in a push is below this
@@ -1832,6 +1875,11 @@ tar.umask::
archiving user's umask will be used instead. See umask(2) and
linkgit:git-archive[1].
+transfer.fsckObjects::
+ When `fetch.fsckObjects` or `receive.fsckObjects` are
+ not set, the value of this variable is used instead.
+ Defaults to false.
+
transfer.unpackLimit::
When `fetch.unpackLimit` or `receive.unpackLimit` are
not set, the value of this variable is used instead.
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 24f189f..9f7cba2 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -45,14 +45,24 @@ ifndef::git-format-patch[]
Synonym for `-p --raw`.
endif::git-format-patch[]
+--minimal::
+ Spend extra time to make sure the smallest possible
+ diff is produced.
+
--patience::
Generate a diff using the "patience diff" algorithm.
---stat[=<width>[,<name-width>]]::
+--stat[=<width>[,<name-width>[,<count>]]]::
Generate a diffstat. You can override the default
output width for 80-column terminal by `--stat=<width>`.
The width of the filename part can be controlled by
giving another width to it separated by a comma.
+ By giving a third parameter `<count>`, you can limit the
+ output to the first `<count>` lines, followed by
+ `...` if there are more.
++
+These parameters can also be set individually with `--stat-width=<width>`,
+`--stat-name-width=<name-width>` and `--stat-count=<count>`.
--numstat::
Similar to `\--stat`, but shows number of added and
@@ -398,7 +408,12 @@ endif::git-format-patch[]
Show the context between diff hunks, up to the specified number
of lines, thereby fusing hunks that are close to each other.
+-W::
+--function-context::
+ Show whole surrounding functions of changes.
+
ifndef::git-format-patch[]
+ifndef::git-log[]
--exit-code::
Make the program exit with codes similar to diff(1).
That is, it exits with 1 if there were differences and
@@ -406,6 +421,7 @@ ifndef::git-format-patch[]
--quiet::
Disable all output of the program. Implies `--exit-code`.
+endif::git-log[]
endif::git-format-patch[]
--ext-diff::
@@ -416,6 +432,17 @@ endif::git-format-patch[]
--no-ext-diff::
Disallow external diff drivers.
+--textconv::
+--no-textconv::
+ Allow (or disallow) external text conversion filters to be run
+ when comparing binary files. See linkgit:gitattributes[5] for
+ details. Because textconv filters are typically a one-way
+ conversion, the resulting diff is suitable for human
+ consumption, but cannot be applied. For this reason, textconv
+ filters are enabled by default only for linkgit:git-diff[1] and
+ linkgit:git-log[1], but not for linkgit:git-format-patch[1] or
+ diff plumbing commands.
+
--ignore-submodules[=<when>]::
Ignore changes to submodules in the diff generation. <when> can be
either "none", "untracked", "dirty" or "all", which is the default
diff --git a/Documentation/git-am.txt b/Documentation/git-am.txt
index 6b1b5af..887466d 100644
--- a/Documentation/git-am.txt
+++ b/Documentation/git-am.txt
@@ -13,7 +13,8 @@ SYNOPSIS
[--3way] [--interactive] [--committer-date-is-author-date]
[--ignore-date] [--ignore-space-change | --ignore-whitespace]
[--whitespace=<option>] [-C<n>] [-p<n>] [--directory=<dir>]
- [--reject] [-q | --quiet] [--scissors | --no-scissors]
+ [--exclude=<path>] [--reject] [-q | --quiet]
+ [--scissors | --no-scissors]
[(<mbox> | <Maildir>)...]
'git am' (--continue | --skip | --abort)
@@ -87,6 +88,7 @@ default. You can use `--no-utf8` to override this.
-C<n>::
-p<n>::
--directory=<dir>::
+--exclude=<path>::
--reject::
These flags are passed to the 'git apply' (see linkgit:git-apply[1])
program that applies
diff --git a/Documentation/git-annotate.txt b/Documentation/git-annotate.txt
index 9eb75c3..05fd482 100644
--- a/Documentation/git-annotate.txt
+++ b/Documentation/git-annotate.txt
@@ -7,6 +7,7 @@ git-annotate - Annotate file lines with commit information
SYNOPSIS
--------
+[verse]
'git annotate' [options] file [revision]
DESCRIPTION
diff --git a/Documentation/git-archive.txt b/Documentation/git-archive.txt
index 9c750e2..ac7006e 100644
--- a/Documentation/git-archive.txt
+++ b/Documentation/git-archive.txt
@@ -101,6 +101,25 @@ tar.umask::
details. If `--remote` is used then only the configuration of
the remote repository takes effect.
+tar.<format>.command::
+ This variable specifies a shell command through which the tar
+ output generated by `git archive` should be piped. The command
+ is executed using the shell with the generated tar file on its
+ standard input, and should produce the final output on its
+ standard output. Any compression-level options will be passed
+ to the command (e.g., "-9"). An output file with the same
+ extension as `<format>` will be use this format if no other
+ format is given.
++
+The "tar.gz" and "tgz" formats are defined automatically and default to
+`gzip -cn`. You may override them with custom commands.
+
+tar.<format>.remote::
+ If true, enable `<format>` for use by remote clients via
+ linkgit:git-upload-archive[1]. Defaults to false for
+ user-defined formats, but true for the "tar.gz" and "tgz"
+ formats.
+
ATTRIBUTES
----------
@@ -123,32 +142,46 @@ while archiving any tree in your `$GIT_DIR/info/attributes` file.
EXAMPLES
--------
-git archive --format=tar --prefix=junk/ HEAD | (cd /var/tmp/ && tar xf -)::
+`git archive --format=tar --prefix=junk/ HEAD | (cd /var/tmp/ && tar xf -)`::
Create a tar archive that contains the contents of the
latest commit on the current branch, and extract it in the
`/var/tmp/junk` directory.
-git archive --format=tar --prefix=git-1.4.0/ v1.4.0 | gzip >git-1.4.0.tar.gz::
+`git archive --format=tar --prefix=git-1.4.0/ v1.4.0 | gzip >git-1.4.0.tar.gz`::
Create a compressed tarball for v1.4.0 release.
-git archive --format=tar --prefix=git-1.4.0/ v1.4.0{caret}\{tree\} | gzip >git-1.4.0.tar.gz::
+`git archive --format=tar.gz --prefix=git-1.4.0/ v1.4.0 >git-1.4.0.tar.gz`::
+
+ Same as above, but using the builtin tar.gz handling.
+
+`git archive --prefix=git-1.4.0/ -o git-1.4.0.tar.gz v1.4.0`::
+
+ Same as above, but the format is inferred from the output file.
+
+`git archive --format=tar --prefix=git-1.4.0/ v1.4.0{caret}\{tree\} | gzip >git-1.4.0.tar.gz`::
Create a compressed tarball for v1.4.0 release, but without a
global extended pax header.
-git archive --format=zip --prefix=git-docs/ HEAD:Documentation/ > git-1.4.0-docs.zip::
+`git archive --format=zip --prefix=git-docs/ HEAD:Documentation/ > git-1.4.0-docs.zip`::
Put everything in the current head's Documentation/ directory
into 'git-1.4.0-docs.zip', with the prefix 'git-docs/'.
-git archive -o latest.zip HEAD::
+`git archive -o latest.zip HEAD`::
Create a Zip archive that contains the contents of the latest
commit on the current branch. Note that the output format is
inferred by the extension of the output file.
+`git config tar.tar.xz.command "xz -c"`::
+
+ Configure a "tar.xz" format for making LZMA-compressed tarfiles.
+ You can use it specifying `--format=tar.xz`, or by creating an
+ output file like `-o foo.tar.xz`.
+
SEE ALSO
--------
diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt
index 7b7bafb..e4f46bc 100644
--- a/Documentation/git-bisect.txt
+++ b/Documentation/git-bisect.txt
@@ -8,6 +8,7 @@ git-bisect - Find by binary search the change that introduced a bug
SYNOPSIS
--------
+[verse]
'git bisect' <subcommand> <options>
DESCRIPTION
@@ -16,7 +17,7 @@ The command takes various subcommands, and different options depending
on the subcommand:
git bisect help
- git bisect start [<bad> [<good>...]] [--] [<paths>...]
+ git bisect start [--no-checkout] [<bad> [<good>...]] [--] [<paths>...]
git bisect bad [<rev>]
git bisect good [<rev>...]
git bisect skip [(<rev>|<range>)...]
@@ -262,6 +263,19 @@ rewind the tree to the pristine state. Finally the script should exit
with the status of the real test to let the "git bisect run" command loop
determine the eventual outcome of the bisect session.
+OPTIONS
+-------
+--no-checkout::
++
+Do not checkout the new working tree at each iteration of the bisection
+process. Instead just update a special reference named 'BISECT_HEAD' to make
+it point to the commit that should be tested.
++
+This option may be useful when the test you would perform in each step
+does not require a checked out tree.
++
+If the repository is bare, `--no-checkout` is assumed.
+
EXAMPLES
--------
@@ -342,6 +356,25 @@ $ git bisect run sh -c "make || exit 125; ~/check_test_case.sh"
This shows that you can do without a run script if you write the test
on a single line.
+* Locate a good region of the object graph in a damaged repository
++
+------------
+$ git bisect start HEAD <known-good-commit> [ <boundary-commit> ... ] --no-checkout
+$ git bisect run sh -c '
+ GOOD=$(git for-each-ref "--format=%(objectname)" refs/bisect/good-*) &&
+ git rev-list --objects BISECT_HEAD --not $GOOD >tmp.$$ &&
+ git pack-objects --stdout >/dev/null <tmp.$$
+ rc=$?
+ rm -f tmp.$$
+ test $rc = 0'
+
+------------
++
+In this case, when 'git bisect run' finishes, bisect/bad will refer to a commit that
+has at least one parent whose reachable graph is fully traversable in the sense
+required by 'git pack objects'.
+
+
SEE ALSO
--------
link:git-bisect-lk2009.html[Fighting regressions with git bisect],
diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index c50f189..f46013c 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -9,8 +9,8 @@ SYNOPSIS
--------
[verse]
'git branch' [--color[=<when>] | --no-color] [-r | -a]
- [-v [--abbrev=<length> | --no-abbrev]]
- [(--merged | --no-merged | --contains) [<commit>]]
+ [--list] [-v [--abbrev=<length> | --no-abbrev]]
+ [(--merged | --no-merged | --contains) [<commit>]] [<pattern>...]
'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]
'git branch' (-m | -M) [<oldbranch>] <newbranch>
'git branch' (-d | -D) [-r] <branchname>...
@@ -20,7 +20,11 @@ DESCRIPTION
With no arguments, existing branches are listed and the current branch will
be highlighted with an asterisk. Option `-r` causes the remote-tracking
-branches to be listed, and option `-a` shows both.
+branches to be listed, and option `-a` shows both. This list mode is also
+activated by the `--list` option (see below).
+<pattern> restricts the output to matching branches, the pattern is a shell
+wildcard (i.e., matched using fnmatch(3))
+Multiple patterns may be given; if any of them matches, the tag is shown.
With `--contains`, shows only the branches that contain the named commit
(in other words, the branches whose tip commits are descendants of the
@@ -64,6 +68,7 @@ way to clean up all obsolete remote-tracking branches.
OPTIONS
-------
-d::
+--delete::
Delete a branch. The branch must be fully merged in its
upstream branch, or in `HEAD` if no upstream was set with
`--track` or `--set-upstream`.
@@ -72,6 +77,7 @@ OPTIONS
Delete a branch irrespective of its merged status.
-l::
+--create-reflog::
Create the branch's reflog. This activates recording of
all changes made to the branch ref, enabling use of date
based sha1 expressions such as "<branchname>@\{yesterday}".
@@ -84,6 +90,7 @@ OPTIONS
already. Without `-f` 'git branch' refuses to change an existing branch.
-m::
+--move::
Move/rename a branch and the corresponding reflog.
-M::
@@ -100,20 +107,28 @@ OPTIONS
Same as `--color=never`.
-r::
+--remotes::
List or delete (if used with -d) the remote-tracking branches.
-a::
+--all::
List both remote-tracking branches and local branches.
+--list::
+ Activate the list mode. `git branch <pattern>` would try to create a branch,
+ use `git branch --list <pattern>` to list matching branches.
+
-v::
--verbose::
- Show sha1 and commit subject line for each head, along with
+ When in list mode,
+ show sha1 and commit subject line for each head, along with
relationship to upstream branch (if any). If given twice, print
the name of the upstream branch, as well.
--abbrev=<length>::
Alter the sha1's minimum display length in the output listing.
- The default value is 7.
+ The default value is 7 and can be overridden by the `core.abbrev`
+ config option.
--no-abbrev::
Display the full sha1s in the output listing rather than abbreviating them.
diff --git a/Documentation/git-check-attr.txt b/Documentation/git-check-attr.txt
index 30eca6c..5abdbaa 100644
--- a/Documentation/git-check-attr.txt
+++ b/Documentation/git-check-attr.txt
@@ -9,8 +9,8 @@ git-check-attr - Display gitattributes information
SYNOPSIS
--------
[verse]
-'git check-attr' attr... [--] pathname...
-'git check-attr' --stdin [-z] attr... < <list-of-paths>
+'git check-attr' [-a | --all | attr...] [--] pathname...
+'git check-attr' --stdin [-z] [-a | --all | attr...] < <list-of-paths>
DESCRIPTION
-----------
@@ -19,6 +19,14 @@ For every pathname, this command will list if each attribute is 'unspecified',
OPTIONS
-------
+-a, --all::
+ List all attributes that are associated with the specified
+ paths. If this option is used, then 'unspecified' attributes
+ will not be included in the output.
+
+--cached::
+ Consider `.gitattributes` in the index only, ignoring the working tree.
+
--stdin::
Read file names from stdin instead of from the command-line.
@@ -28,8 +36,11 @@ OPTIONS
\--::
Interpret all preceding arguments as attributes and all following
- arguments as path names. If not supplied, only the first argument will
- be treated as an attribute.
+ arguments as path names.
+
+If none of `--stdin`, `--all`, or `--` is used, the first argument
+will be treated as an attribute and the rest of the arguments as
+pathnames.
OUTPUT
------
@@ -69,6 +80,13 @@ org/example/MyClass.java: diff: java
org/example/MyClass.java: myAttr: set
---------------
+* Listing all attributes for a file:
+---------------
+$ git check-attr --all -- org/example/MyClass.java
+org/example/MyClass.java: diff: java
+org/example/MyClass.java: myAttr: set
+---------------
+
* Listing an attribute for multiple files:
---------------
$ git check-attr myAttr -- org/example/MyClass.java org/example/NoMyAttr.java
diff --git a/Documentation/git-check-ref-format.txt b/Documentation/git-check-ref-format.txt
index 205d83d..103e7b1 100644
--- a/Documentation/git-check-ref-format.txt
+++ b/Documentation/git-check-ref-format.txt
@@ -8,8 +8,9 @@ git-check-ref-format - Ensures that a reference name is well formed
SYNOPSIS
--------
[verse]
-'git check-ref-format' <refname>
-'git check-ref-format' --print <refname>
+'git check-ref-format' [--normalize]
+ [--[no-]allow-onelevel] [--refspec-pattern]
+ <refname>
'git check-ref-format' --branch <branchname-shorthand>
DESCRIPTION
@@ -18,29 +19,38 @@ Checks if a given 'refname' is acceptable, and exits with a non-zero
status if it is not.
A reference is used in git to specify branches and tags. A
-branch head is stored under the `$GIT_DIR/refs/heads` directory, and
-a tag is stored under the `$GIT_DIR/refs/tags` directory (or, if refs
-are packed by `git gc`, as entries in the `$GIT_DIR/packed-refs` file).
+branch head is stored in the `refs/heads` hierarchy, while
+a tag is stored in the `refs/tags` hierarchy of the ref namespace
+(typically in `$GIT_DIR/refs/heads` and `$GIT_DIR/refs/tags`
+directories or, as entries in file `$GIT_DIR/packed-refs`
+if refs are packed by `git gc`).
+
git imposes the following rules on how references are named:
. They can include slash `/` for hierarchical (directory)
grouping, but no slash-separated component can begin with a
- dot `.`.
+ dot `.` or end with the sequence `.lock`.
. They must contain at least one `/`. This enforces the presence of a
category like `heads/`, `tags/` etc. but the actual names are not
- restricted.
+ restricted. If the `--allow-onelevel` option is used, this rule
+ is waived.
. They cannot have two consecutive dots `..` anywhere.
. They cannot have ASCII control characters (i.e. bytes whose
values are lower than \040, or \177 `DEL`), space, tilde `~`,
- caret `{caret}`, colon `:`, question-mark `?`, asterisk `*`,
- or open bracket `[` anywhere.
+ caret `{caret}`, or colon `:` anywhere.
+
+. They cannot have question-mark `?`, asterisk `{asterisk}`, or open
+ bracket `[` anywhere. See the `--refspec-pattern` option below for
+ an exception to this rule.
-. They cannot end with a slash `/` nor a dot `.`.
+. They cannot begin or end with a slash `/` or contain multiple
+ consecutive slashes (see the `--normalize` option below for an
+ exception to this rule)
-. They cannot end with the sequence `.lock`.
+. They cannot end with a dot `.`.
. They cannot contain a sequence `@{`.
@@ -65,16 +75,36 @@ reference name expressions (see linkgit:gitrevisions[7]):
. at-open-brace `@{` is used as a notation to access a reflog entry.
-With the `--print` option, if 'refname' is acceptable, it prints the
-canonicalized name of a hypothetical reference with that name. That is,
-it prints 'refname' with any extra `/` characters removed.
-
With the `--branch` option, it expands the ``previous branch syntax''
`@{-n}`. For example, `@{-1}` is a way to refer the last branch you
were on. This option should be used by porcelains to accept this
syntax anywhere a branch name is expected, so they can act as if you
typed the branch name.
+OPTIONS
+-------
+--allow-onelevel::
+--no-allow-onelevel::
+ Controls whether one-level refnames are accepted (i.e.,
+ refnames that do not contain multiple `/`-separated
+ components). The default is `--no-allow-onelevel`.
+
+--refspec-pattern::
+ Interpret <refname> as a reference name pattern for a refspec
+ (as used with remote repositories). If this option is
+ enabled, <refname> is allowed to contain a single `{asterisk}`
+ in place of a one full pathname component (e.g.,
+ `foo/{asterisk}/bar` but not `foo/bar{asterisk}`).
+
+--normalize::
+ Normalize 'refname' by removing any leading slash (`/`)
+ characters and collapsing runs of adjacent slashes between
+ name components into a single slash. Iff the normalized
+ refname is valid then print it to standard output and exit
+ with a status of 0. (`--print` is a deprecated way to spell
+ `--normalize`.)
+
+
EXAMPLES
--------
@@ -87,7 +117,7 @@ $ git check-ref-format --branch @{-1}
* Determine the reference name to use for a new branch:
+
------------
-$ ref=$(git check-ref-format --print "refs/heads/$newbranch") ||
+$ ref=$(git check-ref-format --normalize "refs/heads/$newbranch") ||
die "we do not like '$newbranch' as a branch name."
------------
diff --git a/Documentation/git-cherry-pick.txt b/Documentation/git-cherry-pick.txt
index 9d8fe0d..fed5097 100644
--- a/Documentation/git-cherry-pick.txt
+++ b/Documentation/git-cherry-pick.txt
@@ -7,7 +7,11 @@ git-cherry-pick - Apply the changes introduced by some existing commits
SYNOPSIS
--------
+[verse]
'git cherry-pick' [--edit] [-n] [-m parent-number] [-s] [-x] [--ff] <commit>...
+'git cherry-pick' --continue
+'git cherry-pick' --quit
+'git cherry-pick' --abort
DESCRIPTION
-----------
@@ -109,33 +113,37 @@ effect to your index in a row.
Pass the merge strategy-specific option through to the
merge strategy. See linkgit:git-merge[1] for details.
+SEQUENCER SUBCOMMANDS
+---------------------
+include::sequencer.txt[]
+
EXAMPLES
--------
-git cherry-pick master::
+`git cherry-pick master`::
Apply the change introduced by the commit at the tip of the
master branch and create a new commit with this change.
-git cherry-pick ..master::
-git cherry-pick ^HEAD master::
+`git cherry-pick ..master`::
+`git cherry-pick ^HEAD master`::
Apply the changes introduced by all commits that are ancestors
of master but not of HEAD to produce new commits.
-git cherry-pick master{tilde}4 master{tilde}2::
+`git cherry-pick master{tilde}4 master{tilde}2`::
Apply the changes introduced by the fifth and third last
commits pointed to by master and create 2 new commits with
these changes.
-git cherry-pick -n master~1 next::
+`git cherry-pick -n master~1 next`::
Apply to the working tree and the index the changes introduced
by the second last commit pointed to by master and by the last
commit pointed to by next, but do not create any commit with
these changes.
-git cherry-pick --ff ..next::
+`git cherry-pick --ff ..next`::
If history is linear and HEAD is an ancestor of next, update
the working tree and advance the HEAD pointer to match next.
@@ -143,7 +151,7 @@ git cherry-pick --ff ..next::
are in next but not HEAD to the current branch, creating a new
commit for each new change.
-git rev-list --reverse master \-- README | git cherry-pick -n --stdin::
+`git rev-list --reverse master \-- README | git cherry-pick -n --stdin`::
Apply the changes introduced by all commits on the master
branch that touched README to the working tree and index,
diff --git a/Documentation/git-cherry.txt b/Documentation/git-cherry.txt
index 79448c5..f6c19c7 100644
--- a/Documentation/git-cherry.txt
+++ b/Documentation/git-cherry.txt
@@ -7,6 +7,7 @@ git-cherry - Find commits not merged upstream
SYNOPSIS
--------
+[verse]
'git cherry' [-v] [<upstream> [<head> [<limit>]]]
DESCRIPTION
diff --git a/Documentation/git-citool.txt b/Documentation/git-citool.txt
index 6e5c812..c7a11c3 100644
--- a/Documentation/git-citool.txt
+++ b/Documentation/git-citool.txt
@@ -7,6 +7,7 @@ git-citool - Graphical alternative to git-commit
SYNOPSIS
--------
+[verse]
'git citool'
DESCRIPTION
diff --git a/Documentation/git-clean.txt b/Documentation/git-clean.txt
index 974e04e..79fb984 100644
--- a/Documentation/git-clean.txt
+++ b/Documentation/git-clean.txt
@@ -47,12 +47,14 @@ OPTIONS
-e <pattern>::
--exclude=<pattern>::
- Specify special exceptions to not be cleaned. Each <pattern> is
- the same form as in $GIT_DIR/info/excludes and this option can be
- given multiple times.
+ In addition to those found in .gitignore (per directory) and
+ $GIT_DIR/info/exclude, also consider these patterns to be in the
+ set of the ignore rules in effect.
-x::
- Don't use the ignore rules. This allows removing all untracked
+ Don't use the standard ignore rules read from .gitignore (per
+ directory) and $GIT_DIR/info/exclude, but do still use the ignore
+ rules given with `-e` options. This allows removing all untracked
files, including build products. This can be used (possibly in
conjunction with 'git reset') to create a pristine
working directory to test a clean build.
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index b093e45..4b8b26b 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -159,6 +159,17 @@ objects from the source repository into a pack in the cloned repository.
Specify the directory from which templates will be used;
(See the "TEMPLATE DIRECTORY" section of linkgit:git-init[1].)
+--config <key>=<value>::
+-c <key>=<value>::
+ Set a configuration variable in the newly-created repository;
+ this takes effect immediately after the repository is
+ initialized, but before the remote history is fetched or any
+ files checked out. The key is in the same format as expected by
+ linkgit:git-config[1] (e.g., `core.eol=true`). If multiple
+ values are given for the same key, each value will be written to
+ the config file. This makes it safe, for example, to add
+ additional fetch refspecs to the origin remote.
+
--depth <depth>::
Create a 'shallow' clone with a history truncated to the
specified number of revisions. A shallow repository has a
diff --git a/Documentation/git-commit-tree.txt b/Documentation/git-commit-tree.txt
index f524d76..02133d5 100644
--- a/Documentation/git-commit-tree.txt
+++ b/Documentation/git-commit-tree.txt
@@ -8,6 +8,7 @@ git-commit-tree - Create a new commit object
SYNOPSIS
--------
+[verse]
'git commit-tree' <tree> [(-p <parent commit>)...] < changelog
DESCRIPTION
@@ -67,7 +68,9 @@ if set:
In case (some of) these environment variables are not set, the information
is taken from the configuration items user.name and user.email, or, if not
-present, system user name and fully qualified hostname.
+present, system user name and the hostname used for outgoing mail (taken
+from `/etc/mailname` and falling back to the fully qualified hostname when
+that file does not exist).
A commit comment is read from stdin. If a changelog
entry is not provided via "<" redirection, 'git commit-tree' will just wait
@@ -89,6 +92,10 @@ Discussion
include::i18n.txt[]
+FILES
+-----
+/etc/mailname
+
SEE ALSO
--------
linkgit:git-write-tree[1]
diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt
index 7951cb7..5cc84a1 100644
--- a/Documentation/git-commit.txt
+++ b/Documentation/git-commit.txt
@@ -284,7 +284,7 @@ When recording your own work, the contents of modified files in
your working tree are temporarily stored to a staging area
called the "index" with 'git add'. A file can be
reverted back, only in the index but not in the working tree,
-to that of the last commit with `git reset HEAD -- <file>`,
+to that of the last commit with `git reset HEAD \-- <file>`,
which effectively reverts 'git add' and prevents the changes to
this file from participating in the next commit. After building
the state to be committed incrementally with these commands,
diff --git a/Documentation/git-count-objects.txt b/Documentation/git-count-objects.txt
index a73933a..23c80ce 100644
--- a/Documentation/git-count-objects.txt
+++ b/Documentation/git-count-objects.txt
@@ -7,6 +7,7 @@ git-count-objects - Count unpacked number of objects and their disk consumption
SYNOPSIS
--------
+[verse]
'git count-objects' [-v]
DESCRIPTION
diff --git a/Documentation/git-cvsexportcommit.txt b/Documentation/git-cvsexportcommit.txt
index ad93a3e..7f79cec 100644
--- a/Documentation/git-cvsexportcommit.txt
+++ b/Documentation/git-cvsexportcommit.txt
@@ -8,6 +8,7 @@ git-cvsexportcommit - Export a single commit to a CVS checkout
SYNOPSIS
--------
+[verse]
'git cvsexportcommit' [-h] [-u] [-v] [-c] [-P] [-p] [-a] [-d cvsroot]
[-w cvsworkdir] [-W] [-f] [-m msgprefix] [PARENTCOMMIT] COMMITID
diff --git a/Documentation/git-daemon.txt b/Documentation/git-daemon.txt
index ebd13be..31b28fc 100644
--- a/Documentation/git-daemon.txt
+++ b/Documentation/git-daemon.txt
@@ -93,14 +93,14 @@ OPTIONS
Listen on an alternative port. Incompatible with '--inetd' option.
--init-timeout=<n>::
- Timeout between the moment the connection is established and the
- client request is received (typically a rather low value, since
+ Timeout (in seconds) between the moment the connection is established
+ and the client request is received (typically a rather low value, since
that should be basically immediate).
--timeout=<n>::
- Timeout for specific client sub-requests. This includes the time
- it takes for the server to process the sub-request and the time spent
- waiting for the next client's request.
+ Timeout (in seconds) for specific client sub-requests. This includes
+ the time it takes for the server to process the sub-request and the
+ time spent waiting for the next client's request.
--max-connections=<n>::
Maximum number of concurrent clients, defaults to 32. Set it to
@@ -161,6 +161,16 @@ the facility of inet daemon to achieve the same before spawning
repository configuration. By default, all the services
are overridable.
+--informative-errors::
+--no-informative-errors::
+ When informative errors are turned on, git-daemon will report
+ more verbose errors to the client, differentiating conditions
+ like "no such repository" from "repository not exported". This
+ is more convenient for clients, but may leak information about
+ the existence of unexported repositories. When informative
+ errors are not enabled, all errors report "access denied" to the
+ client. The default is --no-informative-errors.
+
<directory>::
A directory to add to the whitelist of allowed directories. Unless
--strict-paths is specified this will also include subdirectories
diff --git a/Documentation/git-diff-files.txt b/Documentation/git-diff-files.txt
index 8d48194..906774f 100644
--- a/Documentation/git-diff-files.txt
+++ b/Documentation/git-diff-files.txt
@@ -8,6 +8,7 @@ git-diff-files - Compares files in the working tree and the index
SYNOPSIS
--------
+[verse]
'git diff-files' [-q] [-0|-1|-2|-3|-c|--cc] [<common diff options>] [<path>...]
DESCRIPTION
diff --git a/Documentation/git-diff-index.txt b/Documentation/git-diff-index.txt
index 2ea22ab..c0b7c58 100644
--- a/Documentation/git-diff-index.txt
+++ b/Documentation/git-diff-index.txt
@@ -8,6 +8,7 @@ git-diff-index - Compares content and mode of blobs between the index and reposi
SYNOPSIS
--------
+[verse]
'git diff-index' [-m] [--cached] [<common diff options>] <tree-ish> [<path>...]
DESCRIPTION
diff --git a/Documentation/git-difftool.txt b/Documentation/git-difftool.txt
index 590f410..19d473c 100644
--- a/Documentation/git-difftool.txt
+++ b/Documentation/git-difftool.txt
@@ -7,6 +7,7 @@ git-difftool - Show changes using common diff tools
SYNOPSIS
--------
+[verse]
'git difftool' [<options>] [<commit> [<commit>]] [--] [<path>...]
DESCRIPTION
@@ -30,7 +31,7 @@ OPTIONS
-t <tool>::
--tool=<tool>::
Use the diff tool specified by <tool>.
- Valid merge tools are:
+ Valid diff tools are:
araxis, bc3, diffuse, emerge, ecmerge, gvimdiff, kdiff3,
kompare, meld, opendiff, p4merge, tkdiff, vimdiff and xxdiff.
+
diff --git a/Documentation/git-fast-export.txt b/Documentation/git-fast-export.txt
index 781bd6e..f37eada 100644
--- a/Documentation/git-fast-export.txt
+++ b/Documentation/git-fast-export.txt
@@ -8,6 +8,7 @@ git-fast-export - Git data exporter
SYNOPSIS
--------
+[verse]
'git fast-export [options]' | 'git fast-import'
DESCRIPTION
@@ -82,6 +83,10 @@ marks the same across runs.
allow that. So fake a tagger to be able to fast-import the
output.
+--use-done-feature::
+ Start the stream with a 'feature done' stanza, and terminate
+ it with a 'done' command.
+
--no-data::
Skip output of blob objects and instead refer to blobs via
their original SHA-1 hash. This is useful when rewriting the
diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt
index 249249a..ec6ef31 100644
--- a/Documentation/git-fast-import.txt
+++ b/Documentation/git-fast-import.txt
@@ -8,6 +8,7 @@ git-fast-import - Backend for fast Git data importers
SYNOPSIS
--------
+[verse]
frontend | 'git fast-import' [options]
DESCRIPTION
@@ -101,6 +102,12 @@ OPTIONS
when the `cat-blob` command is encountered in the stream.
The default behaviour is to write to `stdout`.
+--done::
+ Require a `done` command at the end of the stream.
+ This option might be useful for detecting errors that
+ cause the frontend to terminate before it has started to
+ write a stream.
+
--export-pack-edges=<file>::
After creating a packfile, print a line of data to
<file> listing the filename of the packfile and the last
@@ -330,6 +337,11 @@ and control the current import process. More detailed discussion
standard output. This command is optional and is not needed
to perform an import.
+`done`::
+ Marks the end of the stream. This command is optional
+ unless the `done` feature was requested using the
+ `--done` command line option or `feature done` command.
+
`cat-blob`::
Causes fast-import to print a blob in 'cat-file --batch'
format to the file descriptor set with `--cat-blob-fd` or
@@ -413,8 +425,8 @@ Here `<name>` is the person's display name (for example
(``cm@example.com''). `LT` and `GT` are the literal less-than (\x3c)
and greater-than (\x3e) symbols. These are required to delimit
the email address from the other fields in the line. Note that
-`<name>` is free-form and may contain any sequence of bytes, except
-`LT` and `LF`. It is typically UTF-8 encoded.
+`<name>` and `<email>` are free-form and may contain any sequence
+of bytes, except `LT`, `GT` and `LF`. `<name>` is typically UTF-8 encoded.
The time of the change is specified by `<when>` using the date format
that was selected by the \--date-format=<fmt> command line option.
@@ -648,9 +660,14 @@ paths for a commit are encouraged to do so.
`notemodify`
^^^^^^^^^^^^
-Included in a `commit` command to add a new note (annotating a given
-commit) or change the content of an existing note. This command has
-two different means of specifying the content of the note.
+Included in a `commit` `<notes_ref>` command to add a new note
+annotating a `<committish>` or change this annotation contents.
+Internally it is similar to filemodify 100644 on `<committish>`
+path (maybe split into subdirectories). It's not advised to
+use any other commands to write to the `<notes_ref>` tree except
+`filedeleteall` to delete all existing notes in this tree.
+This command has two different means of specifying the content
+of the note.
External data format::
The data content for the note was already supplied by a prior
@@ -995,10 +1012,14 @@ force::
(see OPTIONS, above).
import-marks::
+import-marks-if-exists::
Like --import-marks except in two respects: first, only one
- "feature import-marks" command is allowed per stream;
- second, an --import-marks= command-line option overrides
- any "feature import-marks" command in the stream.
+ "feature import-marks" or "feature import-marks-if-exists"
+ command is allowed per stream; second, an --import-marks=
+ or --import-marks-if-exists command-line option overrides
+ any of these "feature" commands in the stream; third,
+ "feature import-marks-if-exists" like a corresponding
+ command-line option silently skips a nonexistent file.
cat-blob::
ls::
@@ -1015,6 +1036,11 @@ notes::
Versions of fast-import not supporting notes will exit
with a message indicating so.
+done::
+ Error out if the stream ends without a 'done' command.
+ Without this feature, errors causing the frontend to end
+ abruptly at a convenient point in the stream can go
+ undetected.
`option`
~~~~~~~~
@@ -1044,6 +1070,15 @@ not be passed as option:
* cat-blob-fd
* force
+`done`
+~~~~~~
+If the `done` feature is not in use, treated as if EOF was read.
+This can be used to tell fast-import to finish early.
+
+If the `--done` command line option or `feature done` command is
+in use, the `done` command is mandatory and marks the end of the
+stream.
+
Crash Reports
-------------
If fast-import is supplied invalid input it will terminate with a
diff --git a/Documentation/git-fetch-pack.txt b/Documentation/git-fetch-pack.txt
index 48d4bf6..ed1bdaa 100644
--- a/Documentation/git-fetch-pack.txt
+++ b/Documentation/git-fetch-pack.txt
@@ -8,6 +8,7 @@ git-fetch-pack - Receive missing objects from another repository
SYNOPSIS
--------
+[verse]
'git fetch-pack' [--all] [--quiet|-q] [--keep|-k] [--thin] [--include-tag] [--upload-pack=<git-upload-pack>] [--depth=<n>] [--no-progress] [-v] [<host>:]<directory> [<refs>...]
DESCRIPTION
diff --git a/Documentation/git-fetch.txt b/Documentation/git-fetch.txt
index 60ac8d2..b41d7c1 100644
--- a/Documentation/git-fetch.txt
+++ b/Documentation/git-fetch.txt
@@ -8,12 +8,10 @@ git-fetch - Download objects and refs from another repository
SYNOPSIS
--------
+[verse]
'git fetch' [<options>] [<repository> [<refspec>...]]
-
'git fetch' [<options>] <group>
-
'git fetch' --multiple [<options>] [(<repository> | <group>)...]
-
'git fetch' --all [<options>]
diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt
index 9dc1f2a..0f2f117 100644
--- a/Documentation/git-filter-branch.txt
+++ b/Documentation/git-filter-branch.txt
@@ -32,8 +32,9 @@ changes, which would normally have no effect. Nevertheless, this may be
useful in the future for compensating for some git bugs or such,
therefore such a usage is permitted.
-*NOTE*: This command honors `.git/info/grafts`. If you have any grafts
-defined, running this command will make them permanent.
+*NOTE*: This command honors `.git/info/grafts` and `.git/refs/replace/`.
+If you have any grafts or replacement refs defined, running this command
+will make them permanent.
*WARNING*! The rewritten history will have different object names for all
the objects and will not converge with the original branch. You will not
diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt
index 152e695..c872b88 100644
--- a/Documentation/git-for-each-ref.txt
+++ b/Documentation/git-for-each-ref.txt
@@ -101,9 +101,10 @@ Fields that have name-email-date tuple as its value (`author`,
`committer`, and `tagger`) can be suffixed with `name`, `email`,
and `date` to extract the named component.
-The first line of the message in a commit and tag object is
-`subject`, the remaining lines are `body`. The whole message
-is `contents`.
+The complete message in a commit and tag object is `contents`.
+Its first line is `contents:subject`, the remaining lines
+are `contents:body` and the optional GPG signature
+is `contents:signature`.
For sorting purposes, fields with numeric values sort in numeric
order (`objectsize`, `authordate`, `committerdate`, `taggerdate`).
diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt
index d13c9b2..6ea9be7 100644
--- a/Documentation/git-format-patch.txt
+++ b/Documentation/git-format-patch.txt
@@ -166,15 +166,22 @@ will want to ensure that threading is disabled for `git send-email`.
--to=<email>::
Add a `To:` header to the email headers. This is in addition
to any configured headers, and may be used multiple times.
+ The negated form `--no-to` discards all `To:` headers added so
+ far (from config or command line).
--cc=<email>::
Add a `Cc:` header to the email headers. This is in addition
to any configured headers, and may be used multiple times.
+ The negated form `--no-cc` discards all `Cc:` headers added so
+ far (from config or command line).
--add-header=<header>::
Add an arbitrary header to the email headers. This is in addition
to any configured headers, and may be used multiple times.
- For example, `--add-header="Organization: git-foo"`
+ For example, `--add-header="Organization: git-foo"`.
+ The negated form `--no-add-header` discards *all* (`To:`,
+ `Cc:`, and custom) headers added so far from config or command
+ line.
--cover-letter::
In addition to the patches, generate a cover letter file
diff --git a/Documentation/git-fsck-objects.txt b/Documentation/git-fsck-objects.txt
index 90ebb8a..eec4bdb 100644
--- a/Documentation/git-fsck-objects.txt
+++ b/Documentation/git-fsck-objects.txt
@@ -8,6 +8,7 @@ git-fsck-objects - Verifies the connectivity and validity of the objects in the
SYNOPSIS
--------
+[verse]
'git fsck-objects' ...
DESCRIPTION
diff --git a/Documentation/git-fsck.txt b/Documentation/git-fsck.txt
index a2a508d..0a17b42 100644
--- a/Documentation/git-fsck.txt
+++ b/Documentation/git-fsck.txt
@@ -10,7 +10,8 @@ SYNOPSIS
--------
[verse]
'git fsck' [--tags] [--root] [--unreachable] [--cache] [--no-reflogs]
- [--[no-]full] [--strict] [--verbose] [--lost-found] [<object>*]
+ [--[no-]full] [--strict] [--verbose] [--lost-found]
+ [--[no-]progress] [<object>*]
DESCRIPTION
-----------
@@ -72,6 +73,14 @@ index file, all SHA1 references in .git/refs/*, and all reflogs (unless
a blob, the contents are written into the file, rather than
its object name.
+--progress::
+--no-progress::
+ Progress status is reported on the standard error stream by
+ default when it is attached to a terminal, unless
+ --no-progress or --verbose is specified. --progress forces
+ progress status even if the standard error stream is not
+ directed to a terminal.
+
It tests SHA1 and general object sanity, and it does full tracking of
the resulting reachability and everything else. It prints out any
corruption it finds (missing or bad objects), and if you use the
diff --git a/Documentation/git-gc.txt b/Documentation/git-gc.txt
index 4966cb5..815afcb 100644
--- a/Documentation/git-gc.txt
+++ b/Documentation/git-gc.txt
@@ -8,6 +8,7 @@ git-gc - Cleanup unnecessary files and optimize the local repository
SYNOPSIS
--------
+[verse]
'git gc' [--aggressive] [--auto] [--quiet] [--prune=<date> | --no-prune]
DESCRIPTION
diff --git a/Documentation/git-get-tar-commit-id.txt b/Documentation/git-get-tar-commit-id.txt
index 8035736..1e2a20d 100644
--- a/Documentation/git-get-tar-commit-id.txt
+++ b/Documentation/git-get-tar-commit-id.txt
@@ -8,6 +8,7 @@ git-get-tar-commit-id - Extract commit ID from an archive created using git-arch
SYNOPSIS
--------
+[verse]
'git get-tar-commit-id' < <tarfile>
diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt
index e150c77..15d6711 100644
--- a/Documentation/git-grep.txt
+++ b/Documentation/git-grep.txt
@@ -23,7 +23,7 @@ SYNOPSIS
[-A <post-context>] [-B <pre-context>] [-C <context>]
[-f <file>] [-e] <pattern>
[--and|--or|--not|(|)|-e <pattern>...]
- [--cached | --no-index | <tree>...]
+ [ [--exclude-standard] [--cached | --no-index | --untracked] | <tree>...]
[--] [<pathspec>...]
DESCRIPTION
@@ -49,7 +49,20 @@ OPTIONS
blobs registered in the index file.
--no-index::
- Search files in the current directory, not just those tracked by git.
+ Search files in the current directory that is not managed by git.
+
+--untracked::
+ In addition to searching in the tracked files in the working
+ tree, search also in untracked files.
+
+--no-exclude-standard::
+ Also search in ignored files by not honoring the `.gitignore`
+ mechanism. Only useful with `--untracked`.
+
+--exclude-standard::
+ Do not pay attention to ignored files specified via the `.gitignore`
+ mechanism. Only useful when searching files in the current directory
+ with `--no-index`.
-a::
--text::
@@ -148,14 +161,12 @@ OPTIONS
gives the default to color output.
Same as `--color=never`.
--[ABC] <context>::
- Show `context` trailing (`A` -- after), or leading (`B`
- -- before), or both (`C` -- context) lines, and place a
- line containing `--` between contiguous groups of
- matches.
+--break::
+ Print an empty line between matches from different files.
--<num>::
- A shortcut for specifying `-C<num>`.
+--heading::
+ Show the filename above the matches in that file instead of
+ at the start of each shown line.
-p::
--show-function::
@@ -165,6 +176,29 @@ OPTIONS
patch hunk headers (see 'Defining a custom hunk-header' in
linkgit:gitattributes[5]).
+-<num>::
+-C <num>::
+--context <num>::
+ Show <num> leading and trailing lines, and place a line
+ containing `--` between contiguous groups of matches.
+
+-A <num>::
+--after-context <num>::
+ Show <num> trailing lines, and place a line containing
+ `--` between contiguous groups of matches.
+
+-B <num>::
+--before-context <num>::
+ Show <num> leading lines, and place a line containing
+ `--` between contiguous groups of matches.
+
+-W::
+--function-context::
+ Show the surrounding text from the previous line containing a
+ function name up to the one before the next function name,
+ effectively showing the whole function in which the match was
+ found.
+
-f <file>::
Read patterns from <file>, one per line.
@@ -208,15 +242,15 @@ OPTIONS
Examples
--------
-git grep {apostrophe}time_t{apostrophe} \-- {apostrophe}*.[ch]{apostrophe}::
+`git grep {apostrophe}time_t{apostrophe} \-- {apostrophe}*.[ch]{apostrophe}`::
Looks for `time_t` in all tracked .c and .h files in the working
directory and its subdirectories.
-git grep -e {apostrophe}#define{apostrophe} --and \( -e MAX_PATH -e PATH_MAX \)::
+`git grep -e {apostrophe}#define{apostrophe} --and \( -e MAX_PATH -e PATH_MAX \)`::
Looks for a line that has `#define` and either `MAX_PATH` or
`PATH_MAX`.
-git grep --all-match -e NODE -e Unexpected::
+`git grep --all-match -e NODE -e Unexpected`::
Looks for a line that has `NODE` or `Unexpected` in
files that have lines that match both.
diff --git a/Documentation/git-gui.txt b/Documentation/git-gui.txt
index 32a833e..0041994 100644
--- a/Documentation/git-gui.txt
+++ b/Documentation/git-gui.txt
@@ -7,6 +7,7 @@ git-gui - A portable graphical interface to Git
SYNOPSIS
--------
+[verse]
'git gui' [<command>] [arguments]
DESCRIPTION
@@ -49,7 +50,7 @@ version::
Examples
--------
-git gui blame Makefile::
+`git gui blame Makefile`::
Show the contents of the file 'Makefile' in the current
working directory, and provide annotations for both the
@@ -58,41 +59,41 @@ git gui blame Makefile::
uncommitted changes (if any) are explicitly attributed to
'Not Yet Committed'.
-git gui blame v0.99.8 Makefile::
+`git gui blame v0.99.8 Makefile`::
Show the contents of 'Makefile' in revision 'v0.99.8'
and provide annotations for each line. Unlike the above
example the file is read from the object database and not
the working directory.
-git gui blame --line=100 Makefile::
+`git gui blame --line=100 Makefile`::
Loads annotations as described above and automatically
scrolls the view to center on line '100'.
-git gui citool::
+`git gui citool`::
Make one commit and return to the shell when it is complete.
This command returns a non-zero exit code if the window was
closed in any way other than by making a commit.
-git gui citool --amend::
+`git gui citool --amend`::
Automatically enter the 'Amend Last Commit' mode of
the interface.
-git gui citool --nocommit::
+`git gui citool --nocommit`::
Behave as normal citool, but instead of making a commit
simply terminate with a zero exit code. It still checks
that the index does not contain any unmerged entries, so
you can use it as a GUI version of linkgit:git-mergetool[1]
-git citool::
+`git citool`::
Same as `git gui citool` (above).
-git gui browser maint::
+`git gui browser maint`::
Show a browser for the tree of the 'maint' branch. Files
selected in the browser can be viewed with the internal
diff --git a/Documentation/git-help.txt b/Documentation/git-help.txt
index 42aa2b0..9e0b3f6 100644
--- a/Documentation/git-help.txt
+++ b/Documentation/git-help.txt
@@ -7,6 +7,7 @@ git-help - display help information about git
SYNOPSIS
--------
+[verse]
'git help' [-a|--all|-i|--info|-m|--man|-w|--web] [COMMAND]
DESCRIPTION
diff --git a/Documentation/git-http-backend.txt b/Documentation/git-http-backend.txt
index 277d9e1..f4e0741 100644
--- a/Documentation/git-http-backend.txt
+++ b/Documentation/git-http-backend.txt
@@ -119,6 +119,14 @@ ScriptAliasMatch \
ScriptAlias /git/ /var/www/cgi-bin/gitweb.cgi/
----------------------------------------------------------------
++
+To serve multiple repositories from different linkgit:gitnamespaces[7] in a
+single repository:
++
+----------------------------------------------------------------
+SetEnvIf Request_URI "^/git/([^/]*)" GIT_NAMESPACE=$1
+ScriptAliasMatch ^/git/[^/]*(.*) /usr/libexec/git-core/git-http-backend/storage.git$1
+----------------------------------------------------------------
Accelerated static Apache 2.x::
Similar to the above, but Apache can be used to return static
diff --git a/Documentation/git-http-fetch.txt b/Documentation/git-http-fetch.txt
index fefa752..070cd1e 100644
--- a/Documentation/git-http-fetch.txt
+++ b/Documentation/git-http-fetch.txt
@@ -8,12 +8,16 @@ git-http-fetch - Download from a remote git repository via HTTP
SYNOPSIS
--------
+[verse]
'git http-fetch' [-c] [-t] [-a] [-d] [-v] [-w filename] [--recover] [--stdin] <commit> <url>
DESCRIPTION
-----------
Downloads a remote git repository via HTTP.
+*NOTE*: use of this command without -a is deprecated. The -a
+behaviour will become the default in a future release.
+
OPTIONS
-------
commit-id::
diff --git a/Documentation/git-http-push.txt b/Documentation/git-http-push.txt
index 82ae34b..2e67362 100644
--- a/Documentation/git-http-push.txt
+++ b/Documentation/git-http-push.txt
@@ -8,6 +8,7 @@ git-http-push - Push objects over HTTP/DAV to another repository
SYNOPSIS
--------
+[verse]
'git http-push' [--all] [--dry-run] [--force] [--verbose] <url> <ref> [<ref>...]
DESCRIPTION
diff --git a/Documentation/git-imap-send.txt b/Documentation/git-imap-send.txt
index 4e09708..875d283 100644
--- a/Documentation/git-imap-send.txt
+++ b/Documentation/git-imap-send.txt
@@ -8,6 +8,7 @@ git-imap-send - Send a collection of patches from stdin to an IMAP folder
SYNOPSIS
--------
+[verse]
'git imap-send'
diff --git a/Documentation/git-init-db.txt b/Documentation/git-init-db.txt
index 9f97f5a..a21e346 100644
--- a/Documentation/git-init-db.txt
+++ b/Documentation/git-init-db.txt
@@ -8,6 +8,7 @@ git-init-db - Creates an empty git repository
SYNOPSIS
--------
+[verse]
'git init-db' [-q | --quiet] [--bare] [--template=<template_directory>] [--separate-git-dir <git dir>] [--shared[=<permissions>]]
diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
index f2777a7..9ac2bba 100644
--- a/Documentation/git-init.txt
+++ b/Documentation/git-init.txt
@@ -8,6 +8,7 @@ git-init - Create an empty git repository or reinitialize an existing one
SYNOPSIS
--------
+[verse]
'git init' [-q | --quiet] [--bare] [--template=<template_directory>]
[--separate-git-dir <git dir>]
[--shared[=<permissions>]] [directory]
diff --git a/Documentation/git-instaweb.txt b/Documentation/git-instaweb.txt
index 08f85ba..f3eef51 100644
--- a/Documentation/git-instaweb.txt
+++ b/Documentation/git-instaweb.txt
@@ -51,8 +51,8 @@ OPTIONS
start::
--start::
- Start the httpd instance and exit. This does not generate
- any of the configuration files for spawning a new instance.
+ Start the httpd instance and exit. Regenerate configuration files
+ as necessary for spawning a new instance.
stop::
--stop::
@@ -62,8 +62,8 @@ stop::
restart::
--restart::
- Restart the httpd instance and exit. This does not generate
- any of the configuration files for spawning a new instance.
+ Restart the httpd instance and exit. Regenerate configuration files
+ as necessary for spawning a new instance.
CONFIGURATION
-------------
@@ -84,6 +84,10 @@ If the configuration variable 'instaweb.browser' is not set,
'web.browser' will be used instead if it is defined. See
linkgit:git-web{litdd}browse[1] for more information about this.
+SEE ALSO
+--------
+linkgit:gitweb[1]
+
GIT
---
Part of the linkgit:git[1] suite
diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt
index de5c0d3..249fc87 100644
--- a/Documentation/git-log.txt
+++ b/Documentation/git-log.txt
@@ -8,6 +8,7 @@ git-log - Show commit logs
SYNOPSIS
--------
+[verse]
'git log' [<options>] [<since>..<until>] [[\--] <path>...]
DESCRIPTION
@@ -68,10 +69,13 @@ produced by --stat etc.
its size is not included.
[\--] <path>...::
- Show only commits that affect any of the specified paths. To
- prevent confusion with options and branch names, paths may need
- to be prefixed with "\-- " to separate them from options or
- refnames.
+ Show only commits that are enough to explain how the files
+ that match the specified paths came to be. See "History
+ Simplification" below for details and other simplification
+ modes.
++
+To prevent confusion with options and branch names, paths may need to
+be prefixed with "\-- " to separate them from options or refnames.
include::rev-list-options.txt[]
@@ -87,45 +91,45 @@ include::diff-generate-patch.txt[]
Examples
--------
-git log --no-merges::
+`git log --no-merges`::
Show the whole commit history, but skip any merges
-git log v2.6.12.. include/scsi drivers/scsi::
+`git log v2.6.12.. include/scsi drivers/scsi`::
Show all commits since version 'v2.6.12' that changed any file
in the include/scsi or drivers/scsi subdirectories
-git log --since="2 weeks ago" \-- gitk::
+`git log --since="2 weeks ago" \-- gitk`::
Show the changes during the last two weeks to the file 'gitk'.
The "--" is necessary to avoid confusion with the *branch* named
'gitk'
-git log --name-status release..test::
+`git log --name-status release..test`::
Show the commits that are in the "test" branch but not yet
in the "release" branch, along with the list of paths
each commit modifies.
-git log --follow builtin-rev-list.c::
+`git log --follow builtin-rev-list.c`::
Shows the commits that changed builtin-rev-list.c, including
those commits that occurred before the file was given its
present name.
-git log --branches --not --remotes=origin::
+`git log --branches --not --remotes=origin`::
Shows all commits that are in any of local branches but not in
any of remote-tracking branches for 'origin' (what you have that
origin doesn't).
-git log master --not --remotes=*/master::
+`git log master --not --remotes=*/master`::
Shows all commits that are in local master but not in any remote
repository master branches.
-git log -p -m --first-parent::
+`git log -p -m --first-parent`::
Shows the history including change diffs, but only from the
"main branch" perspective, skipping commits that come from merged
diff --git a/Documentation/git-lost-found.txt b/Documentation/git-lost-found.txt
index adf7e1c..c406a11 100644
--- a/Documentation/git-lost-found.txt
+++ b/Documentation/git-lost-found.txt
@@ -7,6 +7,7 @@ git-lost-found - Recover lost refs that luckily have not yet been pruned
SYNOPSIS
--------
+[verse]
'git lost-found'
DESCRIPTION
diff --git a/Documentation/git-mailinfo.txt b/Documentation/git-mailinfo.txt
index ed45662..51dc325 100644
--- a/Documentation/git-mailinfo.txt
+++ b/Documentation/git-mailinfo.txt
@@ -8,6 +8,7 @@ git-mailinfo - Extracts patch and authorship from a single e-mail message
SYNOPSIS
--------
+[verse]
'git mailinfo' [-k|-b] [-u | --encoding=<encoding> | -n] [--scissors] <msg> <patch>
diff --git a/Documentation/git-mailsplit.txt b/Documentation/git-mailsplit.txt
index 9b2049d..4d1b871 100644
--- a/Documentation/git-mailsplit.txt
+++ b/Documentation/git-mailsplit.txt
@@ -7,6 +7,7 @@ git-mailsplit - Simple UNIX mbox splitter program
SYNOPSIS
--------
+[verse]
'git mailsplit' [-b] [-f<nn>] [-d<prec>] [--keep-cr] -o<directory> [--] [(<mbox>|<Maildir>)...]
DESCRIPTION
diff --git a/Documentation/git-merge-file.txt b/Documentation/git-merge-file.txt
index 635c669..d7db2a3 100644
--- a/Documentation/git-merge-file.txt
+++ b/Documentation/git-merge-file.txt
@@ -76,12 +76,12 @@ OPTIONS
EXAMPLES
--------
-git merge-file README.my README README.upstream::
+`git merge-file README.my README README.upstream`::
combines the changes of README.my and README.upstream since README,
tries to merge them and writes the result into README.my.
-git merge-file -L a -L b -L c tmp/a123 tmp/b234 tmp/c345::
+`git merge-file -L a -L b -L c tmp/a123 tmp/b234 tmp/c345`::
merges tmp/a123 and tmp/c345 with the base tmp/b234, but uses labels
`a` and `c` instead of `tmp/a123` and `tmp/c345`.
diff --git a/Documentation/git-merge-index.txt b/Documentation/git-merge-index.txt
index 6ce5467..e0df1b3 100644
--- a/Documentation/git-merge-index.txt
+++ b/Documentation/git-merge-index.txt
@@ -8,6 +8,7 @@ git-merge-index - Run a merge for files needing merging
SYNOPSIS
--------
+[verse]
'git merge-index' [-o] [-q] <merge-program> (-a | [--] <file>*)
DESCRIPTION
diff --git a/Documentation/git-merge-one-file.txt b/Documentation/git-merge-one-file.txt
index ee059de..04e803d 100644
--- a/Documentation/git-merge-one-file.txt
+++ b/Documentation/git-merge-one-file.txt
@@ -8,6 +8,7 @@ git-merge-one-file - The standard helper program to use with git-merge-index
SYNOPSIS
--------
+[verse]
'git merge-one-file'
DESCRIPTION
diff --git a/Documentation/git-merge-tree.txt b/Documentation/git-merge-tree.txt
index 3bfa7b4..c5f84b6 100644
--- a/Documentation/git-merge-tree.txt
+++ b/Documentation/git-merge-tree.txt
@@ -8,6 +8,7 @@ git-merge-tree - Show three-way merge without touching index
SYNOPSIS
--------
+[verse]
'git merge-tree' <base-tree> <branch1> <branch2>
DESCRIPTION
diff --git a/Documentation/git-mergetool--lib.txt b/Documentation/git-mergetool--lib.txt
index 63edede..f98a41b 100644
--- a/Documentation/git-mergetool--lib.txt
+++ b/Documentation/git-mergetool--lib.txt
@@ -7,7 +7,8 @@ git-mergetool--lib - Common git merge tool shell scriptlets
SYNOPSIS
--------
-'TOOL_MODE=(diff|merge) . "$(git --exec-path)/git-mergetool--lib"'
+[verse]
+'TOOL_MODE=(diff|merge) . "$(git --exec-path)/git-mergetool{litdd}lib"'
DESCRIPTION
-----------
diff --git a/Documentation/git-mergetool.txt b/Documentation/git-mergetool.txt
index 8c79ae8..2a49de7 100644
--- a/Documentation/git-mergetool.txt
+++ b/Documentation/git-mergetool.txt
@@ -7,6 +7,7 @@ git-mergetool - Run merge conflict resolution tools to resolve merge conflicts
SYNOPSIS
--------
+[verse]
'git mergetool' [--tool=<tool>] [-y|--no-prompt|--prompt] [<file>...]
DESCRIPTION
@@ -16,9 +17,10 @@ Use `git mergetool` to run one of several merge utilities to resolve
merge conflicts. It is typically run after 'git merge'.
If one or more <file> parameters are given, the merge tool program will
-be run to resolve differences on each file. If no <file> names are
-specified, 'git mergetool' will run the merge tool program on every file
-with merge conflicts.
+be run to resolve differences on each file (skipping those without
+conflicts). Specifying a directory will include all unresolved files in
+that path. If no <file> names are specified, 'git mergetool' will run
+the merge tool program on every file with merge conflicts.
OPTIONS
-------
diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
index 037ab10..65e167a 100644
--- a/Documentation/git-mktag.txt
+++ b/Documentation/git-mktag.txt
@@ -8,6 +8,7 @@ git-mktag - Creates a tag object
SYNOPSIS
--------
+[verse]
'git mktag' < signature_file
DESCRIPTION
diff --git a/Documentation/git-mktree.txt b/Documentation/git-mktree.txt
index afe21be..5c6ebdf 100644
--- a/Documentation/git-mktree.txt
+++ b/Documentation/git-mktree.txt
@@ -8,6 +8,7 @@ git-mktree - Build a tree-object from ls-tree formatted text
SYNOPSIS
--------
+[verse]
'git mktree' [-z] [--missing] [--batch]
DESCRIPTION
diff --git a/Documentation/git-mv.txt b/Documentation/git-mv.txt
index db0e030..b8db373 100644
--- a/Documentation/git-mv.txt
+++ b/Documentation/git-mv.txt
@@ -8,6 +8,7 @@ git-mv - Move or rename a file, a directory, or a symlink
SYNOPSIS
--------
+[verse]
'git mv' <options>... <args>...
DESCRIPTION
diff --git a/Documentation/git-notes.txt b/Documentation/git-notes.txt
index 6a187f2..e8319ea 100644
--- a/Documentation/git-notes.txt
+++ b/Documentation/git-notes.txt
@@ -142,8 +142,9 @@ OPTIONS
-C <object>::
--reuse-message=<object>::
- Take the note message from the given blob object (for
- example, another note).
+ Take the given blob object (for example, another note) as the
+ note message. (Use `git notes copy <object>` instead to
+ copy notes between objects.)
-c <object>::
--reedit-message=<object>::
@@ -285,6 +286,8 @@ $ blob=$(git hash-object -w a.out)
$ git notes --ref=built add -C "$blob" HEAD
------------
+(You cannot simply use `git notes --ref=built add -F a.out HEAD`
+because that is not binary-safe.)
Of course, it doesn't make much sense to display non-text-format notes
with 'git log', so if you use such notes, you'll probably need to write
some special-purpose tools to do something useful with them.
diff --git a/Documentation/git-pack-redundant.txt b/Documentation/git-pack-redundant.txt
index db9f0f7..f2869da 100644
--- a/Documentation/git-pack-redundant.txt
+++ b/Documentation/git-pack-redundant.txt
@@ -8,6 +8,7 @@ git-pack-redundant - Find redundant pack files
SYNOPSIS
--------
+[verse]
'git pack-redundant' [ --verbose ] [ --alt-odb ] < --all | .pack filename ... >
DESCRIPTION
diff --git a/Documentation/git-pack-refs.txt b/Documentation/git-pack-refs.txt
index 54b9253..a3c6677 100644
--- a/Documentation/git-pack-refs.txt
+++ b/Documentation/git-pack-refs.txt
@@ -7,6 +7,7 @@ git-pack-refs - Pack heads and tags for efficient repository access
SYNOPSIS
--------
+[verse]
'git pack-refs' [--all] [--no-prune]
DESCRIPTION
diff --git a/Documentation/git-parse-remote.txt b/Documentation/git-parse-remote.txt
index 02217f6..a45ea1e 100644
--- a/Documentation/git-parse-remote.txt
+++ b/Documentation/git-parse-remote.txt
@@ -8,6 +8,7 @@ git-parse-remote - Routines to help parsing remote repository access parameters
SYNOPSIS
--------
+[verse]
'. "$(git --exec-path)/git-parse-remote"'
DESCRIPTION
diff --git a/Documentation/git-patch-id.txt b/Documentation/git-patch-id.txt
index 50e26f4..90268f0 100644
--- a/Documentation/git-patch-id.txt
+++ b/Documentation/git-patch-id.txt
@@ -7,6 +7,7 @@ git-patch-id - Compute unique ID for a patch
SYNOPSIS
--------
+[verse]
'git patch-id' < <patch>
DESCRIPTION
diff --git a/Documentation/git-peek-remote.txt b/Documentation/git-peek-remote.txt
index a34d62f..87ea3fb 100644
--- a/Documentation/git-peek-remote.txt
+++ b/Documentation/git-peek-remote.txt
@@ -8,6 +8,7 @@ git-peek-remote - List the references in a remote repository
SYNOPSIS
--------
+[verse]
'git peek-remote' [--upload-pack=<git-upload-pack>] [<host>:]<directory>
DESCRIPTION
diff --git a/Documentation/git-prune-packed.txt b/Documentation/git-prune-packed.txt
index 9e6202c..80dc022 100644
--- a/Documentation/git-prune-packed.txt
+++ b/Documentation/git-prune-packed.txt
@@ -8,6 +8,7 @@ git-prune-packed - Remove extra objects that are already in pack files
SYNOPSIS
--------
+[verse]
'git prune-packed' [-n|--dry-run] [-q|--quiet]
diff --git a/Documentation/git-prune.txt b/Documentation/git-prune.txt
index f616a73..80d01b0 100644
--- a/Documentation/git-prune.txt
+++ b/Documentation/git-prune.txt
@@ -8,6 +8,7 @@ git-prune - Prune all unreachable objects from the object database
SYNOPSIS
--------
+[verse]
'git prune' [-n] [-v] [--expire <expire>] [--] [<head>...]
DESCRIPTION
diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt
index 756909c..0f18ec8 100644
--- a/Documentation/git-pull.txt
+++ b/Documentation/git-pull.txt
@@ -8,6 +8,7 @@ git-pull - Fetch from and merge with another repository or a local branch
SYNOPSIS
--------
+[verse]
'git pull' [options] [<repository> [<refspec>...]]
diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index 88acfcd..aede488 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -162,6 +162,12 @@ useful if you write an alias or script around 'git push'.
is specified. This flag forces progress status even if the
standard error stream is not directed to a terminal.
+--recurse-submodules=check::
+ Check whether all submodule commits used by the revisions to be
+ pushed are available on a remote tracking branch. Otherwise the
+ push will be aborted and the command will exit with non-zero status.
+
+
include::urls-remotes.txt[]
OUTPUT
@@ -327,12 +333,12 @@ a case where you do mean to lose history.
Examples
--------
-git push::
+`git push`::
Works like `git push <remote>`, where <remote> is the
current branch's remote (or `origin`, if no remote is
configured for the current branch).
-git push origin::
+`git push origin`::
Without additional configuration, works like
`git push origin :`.
+
@@ -344,45 +350,45 @@ use `git config remote.origin.push HEAD`. Any valid <refspec> (like
the ones in the examples below) can be configured as the default for
`git push origin`.
-git push origin :::
+`git push origin :`::
Push "matching" branches to `origin`. See
<refspec> in the <<OPTIONS,OPTIONS>> section above for a
description of "matching" branches.
-git push origin master::
+`git push origin master`::
Find a ref that matches `master` in the source repository
(most likely, it would find `refs/heads/master`), and update
the same ref (e.g. `refs/heads/master`) in `origin` repository
with it. If `master` did not exist remotely, it would be
created.
-git push origin HEAD::
+`git push origin HEAD`::
A handy way to push the current branch to the same name on the
remote.
-git push origin master:satellite/master dev:satellite/dev::
+`git push origin master:satellite/master dev:satellite/dev`::
Use the source ref that matches `master` (e.g. `refs/heads/master`)
to update the ref that matches `satellite/master` (most probably
`refs/remotes/satellite/master`) in the `origin` repository, then
do the same for `dev` and `satellite/dev`.
-git push origin HEAD:master::
+`git push origin HEAD:master`::
Push the current branch to the remote ref matching `master` in the
`origin` repository. This form is convenient to push the current
branch without thinking about its local name.
-git push origin master:refs/heads/experimental::
+`git push origin master:refs/heads/experimental`::
Create the branch `experimental` in the `origin` repository
by copying the current `master` branch. This form is only
needed to create a new branch or tag in the remote repository when
the local name and the remote name are different; otherwise,
the ref name on its own will work.
-git push origin :experimental::
+`git push origin :experimental`::
Find a ref that matches `experimental` in the `origin` repository
(e.g. `refs/heads/experimental`), and delete it.
-git push origin {plus}dev:master::
+`git push origin {plus}dev:master`::
Update the origin repository's master branch with the dev branch,
allowing non-fast-forward updates. *This can leave unreferenced
commits dangling in the origin repository.* Consider the
diff --git a/Documentation/git-read-tree.txt b/Documentation/git-read-tree.txt
index 46a96f2..5375549 100644
--- a/Documentation/git-read-tree.txt
+++ b/Documentation/git-read-tree.txt
@@ -8,6 +8,7 @@ git-read-tree - Reads tree information into the index
SYNOPSIS
--------
+[verse]
'git read-tree' [[-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>]
[-u [--exclude-per-directory=<gitignore>] | -i]]
[--index-output=<file>] [--no-sparse-checkout]
@@ -46,7 +47,7 @@ OPTIONS
-i::
Usually a merge requires the index file as well as the
- files in the working tree are up to date with the
+ files in the working tree to be up to date with the
current head commit, in order not to lose local
changes. This flag disables the check with the working
tree and is meant to be used when creating a merge of
@@ -70,21 +71,21 @@ OPTIONS
--aggressive::
Usually a three-way merge by 'git read-tree' resolves
the merge for really trivial cases and leaves other
- cases unresolved in the index, so that Porcelains can
+ cases unresolved in the index, so that porcelains can
implement different merge policies. This flag makes the
- command to resolve a few more cases internally:
+ command resolve a few more cases internally:
+
* when one side removes a path and the other side leaves the path
unmodified. The resolution is to remove that path.
* when both sides remove a path. The resolution is to remove that path.
-* when both sides adds a path identically. The resolution
+* when both sides add a path identically. The resolution
is to add that path.
--prefix=<prefix>/::
Keep the current index contents, and read the contents
- of named tree-ish under directory at `<prefix>`. The
+ of the named tree-ish under the directory at `<prefix>`. The
original index file cannot have anything at the path
- `<prefix>` itself, and have nothing in `<prefix>/`
+ `<prefix>` itself, nor anything in the `<prefix>/`
directory. Note that the `<prefix>/` value must end
with a slash.
@@ -378,45 +379,45 @@ have finished your work-in-progress), attempt the merge again.
Sparse checkout
---------------
-"Sparse checkout" allows to sparsely populate working directory.
-It uses skip-worktree bit (see linkgit:git-update-index[1]) to tell
-Git whether a file on working directory is worth looking at.
+"Sparse checkout" allows populating the working directory sparsely.
+It uses the skip-worktree bit (see linkgit:git-update-index[1]) to tell
+Git whether a file in the working directory is worth looking at.
-"git read-tree" and other merge-based commands ("git merge", "git
-checkout"...) can help maintaining skip-worktree bitmap and working
+'git read-tree' and other merge-based commands ('git merge', 'git
+checkout'...) can help maintaining the skip-worktree bitmap and working
directory update. `$GIT_DIR/info/sparse-checkout` is used to
-define the skip-worktree reference bitmap. When "git read-tree" needs
-to update working directory, it will reset skip-worktree bit in index
+define the skip-worktree reference bitmap. When 'git read-tree' needs
+to update the working directory, it resets the skip-worktree bit in the index
based on this file, which uses the same syntax as .gitignore files.
-If an entry matches a pattern in this file, skip-worktree will be
-set on that entry. Otherwise, skip-worktree will be unset.
+If an entry matches a pattern in this file, skip-worktree will not be
+set on that entry. Otherwise, skip-worktree will be set.
Then it compares the new skip-worktree value with the previous one. If
-skip-worktree turns from unset to set, it will add the corresponding
-file back. If it turns from set to unset, that file will be removed.
+skip-worktree turns from set to unset, it will add the corresponding
+file back. If it turns from unset to set, that file will be removed.
While `$GIT_DIR/info/sparse-checkout` is usually used to specify what
-files are in. You can also specify what files are _not_ in, using
-negate patterns. For example, to remove file "unwanted":
+files are in, you can also specify what files are _not_ in, using
+negate patterns. For example, to remove the file `unwanted`:
----------------
-*
+/*
!unwanted
----------------
-Another tricky thing is fully repopulating working directory when you
+Another tricky thing is fully repopulating the working directory when you
no longer want sparse checkout. You cannot just disable "sparse
-checkout" because skip-worktree are still in the index and you working
-directory is still sparsely populated. You should re-populate working
+checkout" because skip-worktree bits are still in the index and your working
+directory is still sparsely populated. You should re-populate the working
directory with the `$GIT_DIR/info/sparse-checkout` file content as
follows:
----------------
-*
+/*
----------------
-Then you can disable sparse checkout. Sparse checkout support in "git
-read-tree" and similar commands is disabled by default. You need to
+Then you can disable sparse checkout. Sparse checkout support in 'git
+read-tree' and similar commands is disabled by default. You need to
turn `core.sparseCheckout` on in order to have sparse checkout
support.
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 9a075bc..504945c 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -12,7 +12,6 @@ SYNOPSIS
[<upstream>] [<branch>]
'git rebase' [-i | --interactive] [options] --onto <newbase>
--root [<branch>]
-
'git rebase' --continue | --skip | --abort
DESCRIPTION
@@ -46,7 +45,7 @@ with a different commit message or timestamp will be skipped).
It is possible that a merge failure will prevent this process from being
completely automatic. You will have to resolve any such merge failure
and run `git rebase --continue`. Another option is to bypass the commit
-that caused the merge failure with `git rebase --skip`. To restore the
+that caused the merge failure with `git rebase --skip`. To check out the
original <branch> and remove the .git/rebase-apply working files, use the
command `git rebase --abort` instead.
@@ -233,7 +232,11 @@ leave out at most one of A and B, in which case it defaults to HEAD.
Restart the rebasing process after having resolved a merge conflict.
--abort::
- Restore the original branch and abort the rebase operation.
+ Abort the rebase operation and reset HEAD to the original
+ branch. If <branch> was provided when the rebase operation was
+ started, then HEAD will be reset to <branch>. Otherwise HEAD
+ will be reset to where it was when the rebase operation was
+ started.
--skip::
Restart the rebasing process by skipping the current patch.
diff --git a/Documentation/git-receive-pack.txt b/Documentation/git-receive-pack.txt
index f34e0ae..b1f7dc6 100644
--- a/Documentation/git-receive-pack.txt
+++ b/Documentation/git-receive-pack.txt
@@ -8,6 +8,7 @@ git-receive-pack - Receive what is pushed into the repository
SYNOPSIS
--------
+[verse]
'git-receive-pack' <directory>
DESCRIPTION
@@ -149,7 +150,7 @@ if the repository is packed and is served via a dumb transport.
SEE ALSO
--------
-linkgit:git-send-pack[1]
+linkgit:git-send-pack[1], linkgit:gitnamespaces[7]
GIT
---
diff --git a/Documentation/git-reflog.txt b/Documentation/git-reflog.txt
index 09057bf..976dc14 100644
--- a/Documentation/git-reflog.txt
+++ b/Documentation/git-reflog.txt
@@ -8,6 +8,7 @@ git-reflog - Manage reflog information
SYNOPSIS
--------
+[verse]
'git reflog' <subcommand> <options>
DESCRIPTION
diff --git a/Documentation/git-relink.txt b/Documentation/git-relink.txt
index 9893376..3b33c99 100644
--- a/Documentation/git-relink.txt
+++ b/Documentation/git-relink.txt
@@ -7,6 +7,7 @@ git-relink - Hardlink common objects in local repositories
SYNOPSIS
--------
+[verse]
'git relink' [--safe] <dir>... <master_dir>
DESCRIPTION
diff --git a/Documentation/git-remote-ext.txt b/Documentation/git-remote-ext.txt
index 68263a6..8a8e1d7 100644
--- a/Documentation/git-remote-ext.txt
+++ b/Documentation/git-remote-ext.txt
@@ -7,6 +7,7 @@ git-remote-ext - Bridge smart transport to external command.
SYNOPSIS
--------
+[verse]
git remote add <nick> "ext::<command>[ <arguments>...]"
DESCRIPTION
diff --git a/Documentation/git-remote-fd.txt b/Documentation/git-remote-fd.txt
index 4aecd4d..f095d57 100644
--- a/Documentation/git-remote-fd.txt
+++ b/Documentation/git-remote-fd.txt
@@ -35,19 +35,19 @@ GIT_TRANSLOOP_DEBUG::
EXAMPLES
--------
-git fetch fd::17 master::
+`git fetch fd::17 master`::
Fetch master, using file descriptor #17 to communicate with
git-upload-pack.
-git fetch fd::17/foo master::
+`git fetch fd::17/foo master`::
Same as above.
-git push fd::7,8 master (as URL)::
+`git push fd::7,8 master (as URL)`::
Push master, using file descriptor #7 to read data from
git-receive-pack and file descriptor #8 to write data to
same service.
-git push fd::7,8/bar master::
+`git push fd::7,8/bar master`::
Same as above.
Documentation
diff --git a/Documentation/git-remote-helpers.txt b/Documentation/git-remote-helpers.txt
index 58f6ad4..674797c 100644
--- a/Documentation/git-remote-helpers.txt
+++ b/Documentation/git-remote-helpers.txt
@@ -7,6 +7,7 @@ git-remote-helpers - Helper programs to interact with remote repositories
SYNOPSIS
--------
+[verse]
'git remote-<transport>' <repository> [<URL>]
DESCRIPTION
@@ -23,22 +24,141 @@ output. Because a remote helper runs as an independent process from
git, there is no need to re-link git to add a new helper, nor any
need to link the helper with the implementation of git.
-Every helper must support the "capabilities" command, which git will
-use to determine what other commands the helper will accept. Other
-commands generally concern facilities like discovering and updating
-remote refs, transporting objects between the object database and
-the remote repository, and updating the local object store.
-
-Helpers supporting the 'fetch' capability can discover refs from the
-remote repository and transfer objects reachable from those refs to
-the local object store. Helpers supporting the 'push' capability can
-transfer local objects to the remote repository and update remote refs.
+Every helper must support the "capabilities" command, which git
+uses to determine what other commands the helper will accept. Those
+other commands can be used to discover and update remote refs,
+transport objects between the object database and the remote repository,
+and update the local object store.
Git comes with a "curl" family of remote helpers, that handle various
transport protocols, such as 'git-remote-http', 'git-remote-https',
'git-remote-ftp' and 'git-remote-ftps'. They implement the capabilities
'fetch', 'option', and 'push'.
+INPUT FORMAT
+------------
+
+Git sends the remote helper a list of commands on standard input, one
+per line. The first command is always the 'capabilities' command, in
+response to which the remote helper must print a list of the
+capabilities it supports (see below) followed by a blank line. The
+response to the capabilities command determines what commands Git uses
+in the remainder of the command stream.
+
+The command stream is terminated by a blank line. In some cases
+(indicated in the documentation of the relevant commands), this blank
+line is followed by a payload in some other protocol (e.g., the pack
+protocol), while in others it indicates the end of input.
+
+Capabilities
+~~~~~~~~~~~~
+
+Each remote helper is expected to support only a subset of commands.
+The operations a helper supports are declared to git in the response
+to the `capabilities` command (see COMMANDS, below).
+
+'option'::
+ For specifying settings like `verbosity` (how much output to
+ write to stderr) and `depth` (how much history is wanted in the
+ case of a shallow clone) that affect how other commands are
+ carried out.
+
+'connect'::
+ For fetching and pushing using git's native packfile protocol
+ that requires a bidirectional, full-duplex connection.
+
+'push'::
+ For listing remote refs and pushing specified objects from the
+ local object store to remote refs.
+
+'fetch'::
+ For listing remote refs and fetching the associated history to
+ the local object store.
+
+'import'::
+ For listing remote refs and fetching the associated history as
+ a fast-import stream.
+
+'refspec' <refspec>::
+ This modifies the 'import' capability, allowing the produced
+ fast-import stream to modify refs in a private namespace
+ instead of writing to refs/heads or refs/remotes directly.
+ It is recommended that all importers providing the 'import'
+ capability use this.
++
+A helper advertising the capability
+`refspec refs/heads/{asterisk}:refs/svn/origin/branches/{asterisk}`
+is saying that, when it is asked to `import refs/heads/topic`, the
+stream it outputs will update the `refs/svn/origin/branches/topic`
+ref.
++
+This capability can be advertised multiple times. The first
+applicable refspec takes precedence. The left-hand of refspecs
+advertised with this capability must cover all refs reported by
+the list command. If no 'refspec' capability is advertised,
+there is an implied `refspec {asterisk}:{asterisk}`.
+
+Capabilities for Pushing
+~~~~~~~~~~~~~~~~~~~~~~~~
+'connect'::
+ Can attempt to connect to 'git receive-pack' (for pushing),
+ 'git upload-pack', etc for communication using the
+ packfile protocol.
++
+Supported commands: 'connect'.
+
+'push'::
+ Can discover remote refs and push local commits and the
+ history leading up to them to new or existing remote refs.
++
+Supported commands: 'list for-push', 'push'.
+
+If a helper advertises both 'connect' and 'push', git will use
+'connect' if possible and fall back to 'push' if the helper requests
+so when connecting (see the 'connect' command under COMMANDS).
+
+Capabilities for Fetching
+~~~~~~~~~~~~~~~~~~~~~~~~~
+'connect'::
+ Can try to connect to 'git upload-pack' (for fetching),
+ 'git receive-pack', etc for communication using the
+ packfile protocol.
++
+Supported commands: 'connect'.
+
+'fetch'::
+ Can discover remote refs and transfer objects reachable from
+ them to the local object store.
++
+Supported commands: 'list', 'fetch'.
+
+'import'::
+ Can discover remote refs and output objects reachable from
+ them as a stream in fast-import format.
++
+Supported commands: 'list', 'import'.
+
+If a helper advertises 'connect', git will use it if possible and
+fall back to another capability if the helper requests so when
+connecting (see the 'connect' command under COMMANDS).
+When choosing between 'fetch' and 'import', git prefers 'fetch'.
+Other frontends may have some other order of preference.
+
+'refspec' <refspec>::
+ This modifies the 'import' capability.
++
+A helper advertising
+`refspec refs/heads/{asterisk}:refs/svn/origin/branches/{asterisk}`
+in its capabilities is saying that, when it handles
+`import refs/heads/topic`, the stream it outputs will update the
+`refs/svn/origin/branches/topic` ref.
++
+This capability can be advertised multiple times. The first
+applicable refspec takes precedence. The left-hand of refspecs
+advertised with this capability must cover all refs reported by
+the list command. If no 'refspec' capability is advertised,
+there is an implied `refspec {asterisk}:{asterisk}`.
+
INVOCATION
----------
@@ -47,6 +167,9 @@ arguments. The first argument specifies a remote repository as in git;
it is either the name of a configured remote or a URL. The second
argument specifies a URL; it is usually of the form
'<transport>://<address>', but any arbitrary string is possible.
+The 'GIT_DIR' environment variable is set up for the remote helper
+and can be used to determine where to store additional data or from
+which directory to invoke auxiliary git commands.
When git encounters a URL of the form '<transport>://<address>', where
'<transport>' is a protocol that it cannot handle natively, it
@@ -118,7 +241,22 @@ Supported if the helper has the "fetch" capability.
'push' +<src>:<dst>::
Pushes the given local <src> commit or branch to the
remote branch described by <dst>. A batch sequence of
- one or more push commands is terminated with a blank line.
+ one or more 'push' commands is terminated with a blank line
+ (if there is only one reference to push, a single 'push' command
+ is followed by a blank line). For example, the following would
+ be two batches of 'push', the first asking the remote-helper
+ to push the local ref 'master' to the remote ref 'master' and
+ the local 'HEAD' to the remote 'branch', and the second
+ asking to push ref 'foo' to ref 'bar' (forced update requested
+ by the '+').
++
+------------
+push refs/heads/master:refs/heads/master
+push HEAD:refs/heads/branch
+\n
+push +refs/heads/foo:refs/heads/bar
+\n
+------------
+
Zero or more protocol options may be entered after the last 'push'
command, before the batch's terminating blank line.
@@ -143,6 +281,11 @@ Supported if the helper has the "push" capability.
Especially useful for interoperability with a foreign versioning
system.
+
+Just like 'push', a batch sequence of one or more 'import' is
+terminated with a blank line. For each batch of 'import', the remote
+helper should produce a fast-import stream terminated by a 'done'
+command.
++
Supported if the helper has the "import" capability.
'connect' <service>::
@@ -167,26 +310,6 @@ completing a valid response for the current command.
Additional commands may be supported, as may be determined from
capabilities reported by the helper.
-CAPABILITIES
-------------
-
-'fetch'::
-'option'::
-'push'::
-'import'::
-'connect'::
- This helper supports the corresponding command with the same name.
-
-'refspec' 'spec'::
- When using the import command, expect the source ref to have
- been written to the destination ref. The earliest applicable
- refspec takes precedence. For example
- "refs/heads/{asterisk}:refs/svn/origin/branches/{asterisk}" means
- that, after an "import refs/heads/name", the script has written to
- refs/svn/origin/branches/name. If this capability is used at
- all, it must cover all refs reported by the list command; if
- it is not used, it is effectively "{asterisk}:{asterisk}"
-
REF LIST ATTRIBUTES
-------------------
@@ -239,6 +362,8 @@ SEE ALSO
--------
linkgit:git-remote[1]
+linkgit:git-remote-testgit[1]
+
GIT
---
Part of the linkgit:git[1] suite
diff --git a/Documentation/git-remote-testgit.txt b/Documentation/git-remote-testgit.txt
new file mode 100644
index 0000000..2a67d45
--- /dev/null
+++ b/Documentation/git-remote-testgit.txt
@@ -0,0 +1,30 @@
+git-remote-testgit(1)
+=====================
+
+NAME
+----
+git-remote-testgit - Example remote-helper
+
+
+SYNOPSIS
+--------
+[verse]
+git clone testgit::<source-repo> [<destination>]
+
+DESCRIPTION
+-----------
+
+This command is a simple remote-helper, that is used both as a
+testcase for the remote-helper functionality, and as an example to
+show remote-helper authors one possible implementation.
+
+The best way to learn more is to read the comments and source code in
+'git-remote-testgit.py'.
+
+SEE ALSO
+--------
+linkgit:git-remote-helpers[1]
+
+GIT
+---
+Part of the linkgit:git[1] suite
diff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt
index 528f34a..5a8c506 100644
--- a/Documentation/git-remote.txt
+++ b/Documentation/git-remote.txt
@@ -60,11 +60,11 @@ the remote repository.
+
With `-t <branch>` option, instead of the default glob
refspec for the remote to track all branches under
-`$GIT_DIR/remotes/<name>/`, a refspec to track only `<branch>`
+the `refs/remotes/<name>/` namespace, a refspec to track only `<branch>`
is created. You can give more than one `-t <branch>` to track
multiple branches without grabbing all branches.
+
-With `-m <master>` option, `$GIT_DIR/remotes/<name>/HEAD` is set
+With `-m <master>` option, a symbolic-ref `refs/remotes/<name>/HEAD` is set
up to point at remote's `<master>` branch. See also the set-head command.
+
When a fetch mirror is created with `\--mirror=fetch`, the refs will not
@@ -92,24 +92,25 @@ configuration settings for the remote are removed.
'set-head'::
-Sets or deletes the default branch (`$GIT_DIR/remotes/<name>/HEAD`) for
+Sets or deletes the default branch (i.e. the target of the
+symbolic-ref `refs/remotes/<name>/HEAD`) for
the named remote. Having a default branch for a remote is not required,
but allows the name of the remote to be specified in lieu of a specific
branch. For example, if the default branch for `origin` is set to
`master`, then `origin` may be specified wherever you would normally
specify `origin/master`.
+
-With `-d`, `$GIT_DIR/remotes/<name>/HEAD` is deleted.
+With `-d`, the symbolic ref `refs/remotes/<name>/HEAD` is deleted.
+
-With `-a`, the remote is queried to determine its `HEAD`, then
-`$GIT_DIR/remotes/<name>/HEAD` is set to the same branch. e.g., if the remote
+With `-a`, the remote is queried to determine its `HEAD`, then the
+symbolic-ref `refs/remotes/<name>/HEAD` is set to the same branch. e.g., if the remote
`HEAD` is pointed at `next`, "`git remote set-head origin -a`" will set
-`$GIT_DIR/refs/remotes/origin/HEAD` to `refs/remotes/origin/next`. This will
+the symbolic-ref `refs/remotes/origin/HEAD` to `refs/remotes/origin/next`. This will
only work if `refs/remotes/origin/next` already exists; if not it must be
fetched first.
+
-Use `<branch>` to set `$GIT_DIR/remotes/<name>/HEAD` explicitly. e.g., "git
-remote set-head origin master" will set `$GIT_DIR/refs/remotes/origin/HEAD` to
+Use `<branch>` to set the symbolic-ref `refs/remotes/<name>/HEAD` explicitly. e.g., "git
+remote set-head origin master" will set the symbolic-ref `refs/remotes/origin/HEAD` to
`refs/remotes/origin/master`. This will only work if
`refs/remotes/origin/master` already exists; if not it must be fetched first.
+
diff --git a/Documentation/git-repack.txt b/Documentation/git-repack.txt
index 0decee2..40af321 100644
--- a/Documentation/git-repack.txt
+++ b/Documentation/git-repack.txt
@@ -8,6 +8,7 @@ git-repack - Pack unpacked objects in a repository
SYNOPSIS
--------
+[verse]
'git repack' [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [--window=<n>] [--depth=<n>]
DESCRIPTION
diff --git a/Documentation/git-repo-config.txt b/Documentation/git-repo-config.txt
index a0d1fa6..9ec115b 100644
--- a/Documentation/git-repo-config.txt
+++ b/Documentation/git-repo-config.txt
@@ -8,6 +8,7 @@ git-repo-config - Get and set repository or global options
SYNOPSIS
--------
+[verse]
'git repo-config' ...
diff --git a/Documentation/git-request-pull.txt b/Documentation/git-request-pull.txt
index 3521d8e..b99681c 100644
--- a/Documentation/git-request-pull.txt
+++ b/Documentation/git-request-pull.txt
@@ -7,6 +7,7 @@ git-request-pull - Generates a summary of pending changes
SYNOPSIS
--------
+[verse]
'git request-pull' [-p] <start> <url> [<end>]
DESCRIPTION
diff --git a/Documentation/git-rerere.txt b/Documentation/git-rerere.txt
index 52db1d8..a6253ba 100644
--- a/Documentation/git-rerere.txt
+++ b/Documentation/git-rerere.txt
@@ -7,6 +7,7 @@ git-rerere - Reuse recorded resolution of conflicted merges
SYNOPSIS
--------
+[verse]
'git rerere' ['clear'|'forget' <pathspec>|'diff'|'status'|'gc']
DESCRIPTION
diff --git a/Documentation/git-reset.txt b/Documentation/git-reset.txt
index b2832fc..b674866 100644
--- a/Documentation/git-reset.txt
+++ b/Documentation/git-reset.txt
@@ -9,8 +9,8 @@ SYNOPSIS
--------
[verse]
'git reset' [-q] [<commit>] [--] <paths>...
-'git reset' [--patch|-p] [<commit>] [--] [<paths>...]
-'git reset' [--soft | --mixed | --hard | --merge | --keep] [-q] [<commit>]
+'git reset' (--patch | -p) [<commit>] [--] [<paths>...]
+'git reset' (--soft | --mixed | --hard | --merge | --keep) [-q] [<commit>]
DESCRIPTION
-----------
@@ -34,7 +34,7 @@ Alternatively, using linkgit:git-checkout[1] and specifying a commit, you
can copy the contents of a path out of a commit to the index and to the
working tree in one go.
-'git reset' --patch|-p [<commit>] [--] [<paths>...]::
+'git reset' (--patch | -p) [<commit>] [--] [<paths>...]::
Interactively select hunks in the difference between the index
and <commit> (defaults to HEAD). The chosen hunks are applied
in reverse to the index.
@@ -43,7 +43,7 @@ This means that `git reset -p` is the opposite of `git add -p`, i.e.
you can use it to selectively reset hunks. See the ``Interactive Mode''
section of linkgit:git-add[1] to learn how to operate the `\--patch` mode.
-'git reset' [--<mode>] [<commit>]::
+'git reset' --<mode> [<commit>]::
This form resets the current branch head to <commit> and
possibly updates the index (resetting it to the tree of <commit>) and
the working tree depending on <mode>, which
diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index 02c44c9..8023dc0 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -8,6 +8,7 @@ git-rev-parse - Pick out and massage parameters
SYNOPSIS
--------
+[verse]
'git rev-parse' [ --option ] <args>...
DESCRIPTION
@@ -179,6 +180,10 @@ print a message to stderr and exit with nonzero status.
<args>...::
Flags and parameters to be parsed.
+--resolve-git-dir <path>::
+ Check if <path> is a valid git-dir or a git-file pointing to a valid
+ git-dir. If <path> is a valid git-dir the resolved path to git-dir will
+ be printed.
include::revisions.txt[]
diff --git a/Documentation/git-revert.txt b/Documentation/git-revert.txt
index ac10cfb..b699a34 100644
--- a/Documentation/git-revert.txt
+++ b/Documentation/git-revert.txt
@@ -7,7 +7,11 @@ git-revert - Revert some existing commits
SYNOPSIS
--------
+[verse]
'git revert' [--edit | --no-edit] [-n] [-m parent-number] [-s] <commit>...
+'git revert' --continue
+'git revert' --quit
+'git revert' --abort
DESCRIPTION
-----------
@@ -23,7 +27,7 @@ throw away all uncommitted changes in your working directory, you
should see linkgit:git-reset[1], particularly the '--hard' option. If
you want to extract specific files as they were in another commit, you
should see linkgit:git-checkout[1], specifically the `git checkout
-<commit> -- <filename>` syntax. Take care with these alternatives as
+<commit> \-- <filename>` syntax. Take care with these alternatives as
both will discard uncommitted changes in your working directory.
OPTIONS
@@ -90,14 +94,18 @@ effect to your index in a row.
Pass the merge strategy-specific option through to the
merge strategy. See linkgit:git-merge[1] for details.
+SEQUENCER SUBCOMMANDS
+---------------------
+include::sequencer.txt[]
+
EXAMPLES
--------
-git revert HEAD~3::
+`git revert HEAD~3`::
Revert the changes specified by the fourth last commit in HEAD
and create a new commit with the reverted changes.
-git revert -n master{tilde}5..master{tilde}2::
+`git revert -n master{tilde}5..master{tilde}2`::
Revert the changes done by commits from the fifth last commit
in master (included) to the third last commit in master
diff --git a/Documentation/git-rm.txt b/Documentation/git-rm.txt
index 8c0554f..665ad4d 100644
--- a/Documentation/git-rm.txt
+++ b/Documentation/git-rm.txt
@@ -7,6 +7,7 @@ git-rm - Remove files from the working tree and from the index
SYNOPSIS
--------
+[verse]
'git rm' [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch] [--quiet] [--] <file>...
DESCRIPTION
@@ -136,7 +137,7 @@ git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached
EXAMPLES
--------
-git rm Documentation/\*.txt::
+`git rm Documentation/\*.txt`::
Removes all `*.txt` files from the index that are under the
`Documentation` directory and any of its subdirectories.
+
@@ -144,7 +145,7 @@ Note that the asterisk `*` is quoted from the shell in this
example; this lets git, and not the shell, expand the pathnames
of files and subdirectories under the `Documentation/` directory.
-git rm -f git-*.sh::
+`git rm -f git-*.sh`::
Because this example lets the shell expand the asterisk
(i.e. you are listing the files explicitly), it
does not remove `subdir/git-foo.sh`.
diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt
index 5a168cf..327233c 100644
--- a/Documentation/git-send-email.txt
+++ b/Documentation/git-send-email.txt
@@ -8,6 +8,7 @@ git-send-email - Send a collection of patches as emails
SYNOPSIS
--------
+[verse]
'git send-email' [options] <file|directory|rev-list options>...
diff --git a/Documentation/git-send-pack.txt b/Documentation/git-send-pack.txt
index 17f8f55..bd3eaa6 100644
--- a/Documentation/git-send-pack.txt
+++ b/Documentation/git-send-pack.txt
@@ -8,6 +8,7 @@ git-send-pack - Push objects over git protocol to another repository
SYNOPSIS
--------
+[verse]
'git send-pack' [--all] [--dry-run] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [<host>:]<directory> [<ref>...]
DESCRIPTION
diff --git a/Documentation/git-sh-i18n--envsubst.txt b/Documentation/git-sh-i18n--envsubst.txt
index 61e4c08..5c3ec32 100644
--- a/Documentation/git-sh-i18n--envsubst.txt
+++ b/Documentation/git-sh-i18n--envsubst.txt
@@ -1,5 +1,5 @@
-git-sh-i18n--envsubst(1)
-========================
+git-sh-i18n{litdd}envsubst(1)
+=============================
NAME
----
@@ -10,8 +10,8 @@ SYNOPSIS
[verse]
eval_gettext () {
printf "%s" "$1" | (
- export PATH $('git sh-i18n--envsubst' --variables "$1");
- 'git sh-i18n--envsubst' "$1"
+ export PATH $('git sh-i18n{litdd}envsubst' --variables "$1");
+ 'git sh-i18n{litdd}envsubst' "$1"
)
}
@@ -22,7 +22,7 @@ This is not a command the end user would want to run. Ever.
This documentation is meant for people who are studying the
plumbing scripts and/or are writing new ones.
-git-sh-i18n--envsubst is Git's stripped-down copy of the GNU
+'git sh-i18n{litdd}envsubst' is Git's stripped-down copy of the GNU
`envsubst(1)` program that comes with the GNU gettext package. It's
used internally by linkgit:git-sh-i18n[1] to interpolate the variables
passed to the the `eval_gettext` function.
diff --git a/Documentation/git-sh-i18n.txt b/Documentation/git-sh-i18n.txt
index 3b1f7ac..60cf49c 100644
--- a/Documentation/git-sh-i18n.txt
+++ b/Documentation/git-sh-i18n.txt
@@ -7,6 +7,7 @@ git-sh-i18n - Git's i18n setup code for shell scripts
SYNOPSIS
--------
+[verse]
'. "$(git --exec-path)/git-sh-i18n"'
DESCRIPTION
@@ -34,7 +35,7 @@ gettext::
eval_gettext::
Currently a dummy fall-through function implemented as a wrapper
around `printf(1)` with variables expanded by the
- linkgit:git-sh-i18n--envsubst[1] helper. Will be replaced by a
+ linkgit:git-sh-i18n{litdd}envsubst[1] helper. Will be replaced by a
real gettext implementation in a later version.
GIT
diff --git a/Documentation/git-sh-setup.txt b/Documentation/git-sh-setup.txt
index 27fd8ba..a2f346c 100644
--- a/Documentation/git-sh-setup.txt
+++ b/Documentation/git-sh-setup.txt
@@ -7,6 +7,7 @@ git-sh-setup - Common git shell script setup code
SYNOPSIS
--------
+[verse]
'. "$(git --exec-path)/git-sh-setup"'
DESCRIPTION
diff --git a/Documentation/git-shell.txt b/Documentation/git-shell.txt
index d7d4b92..9b92506 100644
--- a/Documentation/git-shell.txt
+++ b/Documentation/git-shell.txt
@@ -8,6 +8,7 @@ git-shell - Restricted login shell for Git-only SSH access
SYNOPSIS
--------
+[verse]
'git shell' [-c <command> <argument>]
DESCRIPTION
diff --git a/Documentation/git-show-branch.txt b/Documentation/git-show-branch.txt
index ee4559b..a8e77b5 100644
--- a/Documentation/git-show-branch.txt
+++ b/Documentation/git-show-branch.txt
@@ -13,7 +13,6 @@ SYNOPSIS
[--more=<n> | --list | --independent | --merge-base]
[--no-name | --sha1-name] [--topics]
[(<rev> | <glob>)...]
-
'git show-branch' (-g|--reflog)[=<n>[,<base>]] [--list] [<ref>]
DESCRIPTION
diff --git a/Documentation/git-show-index.txt b/Documentation/git-show-index.txt
index c4d99f1..2dcbbb2 100644
--- a/Documentation/git-show-index.txt
+++ b/Documentation/git-show-index.txt
@@ -8,6 +8,7 @@ git-show-index - Show packed archive index
SYNOPSIS
--------
+[verse]
'git show-index' < idx-file
diff --git a/Documentation/git-show.txt b/Documentation/git-show.txt
index 7f075e8..1e38819 100644
--- a/Documentation/git-show.txt
+++ b/Documentation/git-show.txt
@@ -8,6 +8,7 @@ git-show - Show various types of objects
SYNOPSIS
--------
+[verse]
'git show' [options] <object>...
DESCRIPTION
@@ -47,23 +48,23 @@ include::pretty-formats.txt[]
EXAMPLES
--------
-git show v1.0.0::
+`git show v1.0.0`::
Shows the tag `v1.0.0`, along with the object the tags
points at.
-git show v1.0.0^\{tree\}::
+`git show v1.0.0^\{tree\}`::
Shows the tree pointed to by the tag `v1.0.0`.
-git show -s --format=%s v1.0.0^\{commit\}::
+`git show -s --format=%s v1.0.0^\{commit\}`::
Shows the subject of the commit pointed to by the
tag `v1.0.0`.
-git show next~10:Documentation/README::
+`git show next~10:Documentation/README`::
Shows the contents of the file `Documentation/README` as
they were current in the 10th last commit of the branch
`next`.
-git show master:Makefile master:t/Makefile::
+`git show master:Makefile master:t/Makefile`::
Concatenates the contents of said Makefiles in the head
of the branch `master`.
diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt
index 15f051f..43af38a 100644
--- a/Documentation/git-stash.txt
+++ b/Documentation/git-stash.txt
@@ -13,7 +13,8 @@ SYNOPSIS
'git stash' drop [-q|--quiet] [<stash>]
'git stash' ( pop | apply ) [--index] [-q|--quiet] [<stash>]
'git stash' branch <branchname> [<stash>]
-'git stash' [save [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet] [<message>]]
+'git stash' [save [--patch] [-k|--[no-]keep-index] [-q|--quiet]
+ [-u|--include-untracked] [-a|--all] [<message>]]
'git stash' clear
'git stash' create
@@ -42,7 +43,7 @@ is also possible).
OPTIONS
-------
-save [-p|--patch] [--[no-]keep-index] [-q|--quiet] [<message>]::
+save [-p|--patch] [--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [<message>]::
Save your local modifications to a new 'stash', and run `git reset
--hard` to revert them. The <message> part is optional and gives
@@ -54,6 +55,11 @@ save [-p|--patch] [--[no-]keep-index] [-q|--quiet] [<message>]::
If the `--keep-index` option is used, all changes already added to the
index are left intact.
+
+If the `--include-untracked` option is used, all untracked files are also
+stashed and then cleaned up with `git clean`, leaving the working directory
+in a very clean state. If the `--all` option is used instead then the
+ignored files are stashed and cleaned in addition to the untracked files.
++
With `--patch`, you can interactively select hunks from the diff
between HEAD and the working tree to be stashed. The stash entry is
constructed such that its index state is the same as the index state
diff --git a/Documentation/git-status.txt b/Documentation/git-status.txt
index 38cb741..3d51717 100644
--- a/Documentation/git-status.txt
+++ b/Documentation/git-status.txt
@@ -8,6 +8,7 @@ git-status - Show the working tree status
SYNOPSIS
--------
+[verse]
'git status' [<options>...] [--] [<pathspec>...]
DESCRIPTION
@@ -69,6 +70,9 @@ configuration variable documented in linkgit:git-config[1].
(and suppresses the output of submodule summaries when the config option
`status.submodulesummary` is set).
+--ignored::
+ Show ignored files as well.
+
-z::
Terminate entries with NUL, instead of LF. This implies
the `--porcelain` output format if no other format is given.
@@ -119,7 +123,8 @@ codes can be interpreted as follows:
* 'C' = copied
* 'U' = updated but unmerged
-Ignored files are not listed.
+Ignored files are not listed, unless `--ignored` option is in effect,
+in which case `XY` are `!!`.
X Y Meaning
-------------------------------------------------
@@ -142,6 +147,7 @@ Ignored files are not listed.
U U unmerged, both modified
-------------------------------------------------
? ? untracked
+ ! ! ignored
-------------------------------------------------
If -b is used the short-format status is preceded by a line
diff --git a/Documentation/git-stripspace.txt b/Documentation/git-stripspace.txt
index 10509cc..b78f031 100644
--- a/Documentation/git-stripspace.txt
+++ b/Documentation/git-stripspace.txt
@@ -8,6 +8,7 @@ git-stripspace - Filter out empty lines
SYNOPSIS
--------
+[verse]
'git stripspace' [-s | --strip-comments] < <stream>
DESCRIPTION
diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index 5e7a413..6ec3fef 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt
@@ -15,7 +15,8 @@ SYNOPSIS
'git submodule' [--quiet] init [--] [<path>...]
'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--rebase]
[--reference <repository>] [--merge] [--recursive] [--] [<path>...]
-'git submodule' [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
+'git submodule' [--quiet] summary [--cached|--files] [(-n|--summary-limit) <n>]
+ [commit] [--] [<path>...]
'git submodule' [--quiet] foreach [--recursive] <command>
'git submodule' [--quiet] sync [--] [<path>...]
@@ -78,7 +79,9 @@ to exist in the superproject. If <path> is not given, the
<repository> is the URL of the new submodule's origin repository.
This may be either an absolute URL, or (if it begins with ./
or ../), the location relative to the superproject's origin
-repository.
+repository. If the superproject doesn't have an origin configured
+the superproject is its own authoritative upstream and the current
+working directory is used instead.
+
<path> is the relative location for the cloned submodule to
exist in the superproject. If <path> does not exist, then the
@@ -106,12 +109,19 @@ status::
repository and `U` if the submodule has merge conflicts.
This command is the default command for 'git submodule'.
+
-If '--recursive' is specified, this command will recurse into nested
+If `--recursive` is specified, this command will recurse into nested
submodules, and show their status as well.
++
+If you are only interested in changes of the currently initialized
+submodules with respect to the commit recorded in the index or the HEAD,
+linkgit:git-status[1] and linkgit:git-diff[1] will provide that information
+too (and can also report changes to a submodule's work tree).
init::
Initialize the submodules, i.e. register each submodule name
and url found in .gitmodules into .git/config.
+ It will also copy the value of `submodule.$name.update` into
+ .git/config.
The key used in .git/config is `submodule.$name.url`.
This command does not alter existing information in .git/config.
You can then customize the submodule clone URLs in .git/config
@@ -123,26 +133,33 @@ init::
update::
Update the registered submodules, i.e. clone missing submodules and
checkout the commit specified in the index of the containing repository.
- This will make the submodules HEAD be detached unless '--rebase' or
- '--merge' is specified or the key `submodule.$name.update` is set to
- `rebase` or `merge`.
+ This will make the submodules HEAD be detached unless `--rebase` or
+ `--merge` is specified or the key `submodule.$name.update` is set to
+ `rebase`, `merge` or `none`.
+
If the submodule is not yet initialized, and you just want to use the
setting as stored in .gitmodules, you can automatically initialize the
-submodule with the --init option.
+submodule with the `--init` option.
+
-If '--recursive' is specified, this command will recurse into the
+If `--recursive` is specified, this command will recurse into the
registered submodules, and update any nested submodules within.
++
+If the configuration key `submodule.$name.update` is set to `none` the
+submodule with name `$name` will not be updated by default. This can be
+overriden by adding `--checkout` to the command.
summary::
Show commit summary between the given commit (defaults to HEAD) and
working tree/index. For a submodule in question, a series of commits
in the submodule between the given super project commit and the
- index or working tree (switched by --cached) are shown. If the option
- --files is given, show the series of commits in the submodule between
+ index or working tree (switched by `--cached`) are shown. If the option
+ `--files` is given, show the series of commits in the submodule between
the index of the super project and the working tree of the submodule
- (this option doesn't allow to use the --cached option or to provide an
+ (this option doesn't allow to use the `--cached` option or to provide an
explicit commit).
++
+Using the `--submodule=log` option with linkgit:git-diff[1] will provide that
+information too.
foreach::
Evaluates an arbitrary shell command in each checked out submodule.
@@ -153,9 +170,9 @@ foreach::
superproject, $sha1 is the commit as recorded in the superproject,
and $toplevel is the absolute path to the top-level of the superproject.
Any submodules defined in the superproject but not checked out are
- ignored by this command. Unless given --quiet, foreach prints the name
+ ignored by this command. Unless given `--quiet`, foreach prints the name
of each submodule before evaluating the command.
- If --recursive is given, submodules are traversed recursively (i.e.
+ If `--recursive` is given, submodules are traversed recursively (i.e.
the given shell command is evaluated in nested submodules as well).
A non-zero return from the command in any submodule causes
the processing to terminate. This can be overridden by adding '|| :'
@@ -167,12 +184,14 @@ commit for each submodule.
sync::
Synchronizes submodules' remote URL configuration setting
- to the value specified in .gitmodules. This is useful when
+ to the value specified in .gitmodules. It will only affect those
+ submodules which already have an url entry in .git/config (that is the
+ case when they are initialized or freshly added). This is useful when
submodule URLs change upstream and you need to update your local
repositories accordingly.
+
"git submodule sync" synchronizes all submodules while
-"git submodule sync -- A" synchronizes submodule "A" only.
+"git submodule sync \-- A" synchronizes submodule "A" only.
OPTIONS
-------
@@ -233,13 +252,18 @@ OPTIONS
If the key `submodule.$name.update` is set to `rebase`, this option is
implicit.
+--init::
+ This option is only valid for the update command.
+ Initialize all submodules for which "git submodule init" has not been
+ called so far before updating.
+
--reference <repository>::
This option is only valid for add and update commands. These
commands sometimes need to clone a remote repository. In this case,
this option will be passed to the linkgit:git-clone[1] command.
+
*NOTE*: Do *not* use this option unless you have read the note
-for linkgit:git-clone[1]'s --reference and --shared options carefully.
+for linkgit:git-clone[1]'s `--reference` and `--shared` options carefully.
--recursive::
This option is only valid for foreach, update and status commands.
diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt
index 713e523..34ee785 100644
--- a/Documentation/git-svn.txt
+++ b/Documentation/git-svn.txt
@@ -7,6 +7,7 @@ git-svn - Bidirectional operation between a Subversion repository and git
SYNOPSIS
--------
+[verse]
'git svn' <command> [options] [arguments]
DESCRIPTION
@@ -156,6 +157,17 @@ Skip "branches" and "tags" of first level directories;;
affecting the working tree; and the 'rebase' command will be
able to update the working tree with the latest changes.
+--preserve-empty-dirs;;
+ Create a placeholder file in the local Git repository for each
+ empty directory fetched from Subversion. This includes directories
+ that become empty by removing all entries in the Subversion
+ repository (but not the directory itself). The placeholder files
+ are also tracked and removed when no longer necessary.
+
+--placeholder-filename=<filename>;;
+ Set the name of placeholder files created by --preserve-empty-dirs.
+ Default: ".gitignore"
+
'rebase'::
This fetches revisions from the SVN parent of the current HEAD
and rebases the current (uncommitted to SVN) work against it.
@@ -210,8 +222,25 @@ discouraged.
Add the given merge information during the dcommit
(e.g. `--mergeinfo="/branches/foo:1-10"`). All svn server versions can
store this information (as a property), and svn clients starting from
- version 1.5 can make use of it. 'git svn' currently does not use it
- and does not set it automatically.
+ version 1.5 can make use of it. To specify merge information from multiple
+ branches, use a single space character between the branches
+ (`--mergeinfo="/branches/foo:1-10 /branches/bar:3,5-6,8"`)
++
+[verse]
+config key: svn.pushmergeinfo
++
+This option will cause git-svn to attempt to automatically populate the
+svn:mergeinfo property in the SVN repository when possible. Currently, this can
+only be done when dcommitting non-fast-forward merges where all parents but the
+first have already been pushed into SVN.
+
+--interactive;;
+ Ask the user to confirm that a patch set should actually be sent to SVN.
+ For each patch, one may answer "yes" (accept this patch), "no" (discard this
+ patch), "all" (accept all patches), or "quit".
+ +
+ 'git svn dcommit' returns immediately if answer if "no" or "quit", without
+ commiting anything to SVN.
'branch'::
Create a branch in the SVN repository.
@@ -297,7 +326,7 @@ Any other arguments are passed directly to 'git log'
Show what revision and author last modified each line of a file. The
output of this mode is format-compatible with the output of
`svn blame' by default. Like the SVN blame command,
- local uncommitted changes in the working copy are ignored;
+ local uncommitted changes in the working tree are ignored;
the version of the file in the HEAD revision is annotated. Unknown
arguments are passed directly to 'git blame'.
+
diff --git a/Documentation/git-symbolic-ref.txt b/Documentation/git-symbolic-ref.txt
index d7795ed..a45d4c4 100644
--- a/Documentation/git-symbolic-ref.txt
+++ b/Documentation/git-symbolic-ref.txt
@@ -7,6 +7,7 @@ git-symbolic-ref - Read and modify symbolic refs
SYNOPSIS
--------
+[verse]
'git symbolic-ref' [-q] [-m <reason>] <name> [<ref>]
DESCRIPTION
@@ -42,12 +43,9 @@ In the past, `.git/HEAD` was a symbolic link pointing at
`refs/heads/master`. When we wanted to switch to another branch,
we did `ln -sf refs/heads/newbranch .git/HEAD`, and when we wanted
to find out which branch we are on, we did `readlink .git/HEAD`.
-This was fine, and internally that is what still happens by
-default, but on platforms that do not have working symlinks,
-or that do not have the `readlink(1)` command, this was a bit
-cumbersome. On some platforms, `ln -sf` does not even work as
-advertised (horrors). Therefore symbolic links are now deprecated
-and symbolic refs are used by default.
+But symbolic links are not entirely portable, so they are now
+deprecated and symbolic refs (as described above) are used by
+default.
'git symbolic-ref' will exit with status 0 if the contents of the
symbolic ref were printed correctly, with status 1 if the requested
diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt
index d82f621..c83cb13 100644
--- a/Documentation/git-tag.txt
+++ b/Documentation/git-tag.txt
@@ -12,7 +12,7 @@ SYNOPSIS
'git tag' [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>]
<tagname> [<commit> | <object>]
'git tag' -d <tagname>...
-'git tag' [-n[<num>]] -l [--contains <commit>] [<pattern>]
+'git tag' [-n[<num>]] -l [--contains <commit>] [<pattern>...]
'git tag' -v <tagname>...
DESCRIPTION
@@ -43,12 +43,15 @@ GnuPG key for signing.
OPTIONS
-------
-a::
+--annotate::
Make an unsigned, annotated tag object
-s::
+--sign::
Make a GPG-signed tag, using the default e-mail address's key
-u <key-id>::
+--local-user=<key-id>::
Make a GPG-signed tag, using the given key
-f::
@@ -56,9 +59,11 @@ OPTIONS
Replace an existing tag with the given name (instead of failing)
-d::
+--delete::
Delete existing tags with the given names.
-v::
+--verify::
Verify the gpg signature of the given tag names.
-n<num>::
@@ -69,13 +74,18 @@ OPTIONS
If the tag is not annotated, the commit message is displayed instead.
-l <pattern>::
- List tags with names that match the given pattern (or all if no pattern is given).
- Typing "git tag" without arguments, also lists all tags.
+--list <pattern>::
+ List tags with names that match the given pattern (or all if no
+ pattern is given). Running "git tag" without arguments also
+ lists all tags. The pattern is a shell wildcard (i.e., matched
+ using fnmatch(3)). Multiple patterns may be given; if any of
+ them matches, the tag is shown.
--contains <commit>::
Only list tags which contain the specified commit.
-m <msg>::
+--message=<msg>::
Use the given tag message (instead of prompting).
If multiple `-m` options are given, their values are
concatenated as separate paragraphs.
@@ -83,6 +93,7 @@ OPTIONS
is given.
-F <file>::
+--file=<file>::
Take the tag message from the given file. Use '-' to
read the message from the standard input.
Implies `-a` if none of `-a`, `-s`, or `-u <key-id>`
diff --git a/Documentation/git-tar-tree.txt b/Documentation/git-tar-tree.txt
index 5f15754..346e7a2 100644
--- a/Documentation/git-tar-tree.txt
+++ b/Documentation/git-tar-tree.txt
@@ -8,6 +8,7 @@ git-tar-tree - Create a tar archive of the files in the named tree object
SYNOPSIS
--------
+[verse]
'git tar-tree' [--remote=<repo>] <tree-ish> [ <base> ]
DESCRIPTION
@@ -52,26 +53,26 @@ tar.umask::
EXAMPLES
--------
-git tar-tree HEAD junk | (cd /var/tmp/ && tar xf -)::
+`git tar-tree HEAD junk | (cd /var/tmp/ && tar xf -)`::
Create a tar archive that contains the contents of the
latest commit on the current branch, and extracts it in
`/var/tmp/junk` directory.
-git tar-tree v1.4.0 git-1.4.0 | gzip >git-1.4.0.tar.gz::
+`git tar-tree v1.4.0 git-1.4.0 | gzip >git-1.4.0.tar.gz`::
Create a tarball for v1.4.0 release.
-git tar-tree v1.4.0{caret}\{tree\} git-1.4.0 | gzip >git-1.4.0.tar.gz::
+`git tar-tree v1.4.0{caret}\{tree\} git-1.4.0 | gzip >git-1.4.0.tar.gz`::
Create a tarball for v1.4.0 release, but without a
global extended pax header.
-git tar-tree --remote=example.com:git.git v1.4.0 >git-1.4.0.tar::
+`git tar-tree --remote=example.com:git.git v1.4.0 >git-1.4.0.tar`::
Get a tarball v1.4.0 from example.com.
-git tar-tree HEAD:Documentation/ git-docs > git-1.4.0-docs.tar::
+`git tar-tree HEAD:Documentation/ git-docs > git-1.4.0-docs.tar`::
Put everything in the current head's Documentation/ directory
into 'git-1.4.0-docs.tar', with the prefix 'git-docs/'.
diff --git a/Documentation/git-unpack-file.txt b/Documentation/git-unpack-file.txt
index c49d727..e9f148a 100644
--- a/Documentation/git-unpack-file.txt
+++ b/Documentation/git-unpack-file.txt
@@ -9,6 +9,7 @@ git-unpack-file - Creates a temporary file with a blob's contents
SYNOPSIS
--------
+[verse]
'git unpack-file' <blob>
DESCRIPTION
diff --git a/Documentation/git-unpack-objects.txt b/Documentation/git-unpack-objects.txt
index dd77990..ff23494 100644
--- a/Documentation/git-unpack-objects.txt
+++ b/Documentation/git-unpack-objects.txt
@@ -8,6 +8,7 @@ git-unpack-objects - Unpack objects from a packed archive
SYNOPSIS
--------
+[verse]
'git unpack-objects' [-n] [-q] [-r] [--strict] <pack-file
diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt
index d393129..a3081f4 100644
--- a/Documentation/git-update-index.txt
+++ b/Documentation/git-update-index.txt
@@ -264,7 +264,9 @@ tree files, you have to explicitly tell git about it by dropping
"assume unchanged" bit, either before or after you modify them.
In order to set "assume unchanged" bit, use `--assume-unchanged`
-option. To unset, use `--no-assume-unchanged`.
+option. To unset, use `--no-assume-unchanged`. To see which files
+have the "assume unchanged" bit set, use `git ls-files -v`
+(see linkgit:git-ls-files[1]).
The command looks at `core.ignorestat` configuration variable. When
this is true, paths updated with `git update-index paths...` and
@@ -363,7 +365,8 @@ ctime for marking files processed) (see linkgit:git-config[1]).
SEE ALSO
--------
linkgit:git-config[1],
-linkgit:git-add[1]
+linkgit:git-add[1],
+linkgit:git-ls-files[1]
GIT
---
diff --git a/Documentation/git-update-ref.txt b/Documentation/git-update-ref.txt
index e25a65a..d377a35 100644
--- a/Documentation/git-update-ref.txt
+++ b/Documentation/git-update-ref.txt
@@ -7,6 +7,7 @@ git-update-ref - Update the object name stored in a ref safely
SYNOPSIS
--------
+[verse]
'git update-ref' [-m <reason>] (-d <ref> [<oldvalue>] | [--no-deref] <ref> <newvalue> [<oldvalue>])
DESCRIPTION
@@ -60,8 +61,9 @@ still contains <oldvalue>.
Logging Updates
---------------
-If config parameter "core.logAllRefUpdates" is true or the file
-"$GIT_DIR/logs/<ref>" exists then `git update-ref` will append
+If config parameter "core.logAllRefUpdates" is true and the ref is one under
+"refs/heads/", "refs/remotes/", "refs/notes/", or the symbolic ref HEAD; or
+the file "$GIT_DIR/logs/<ref>" exists then `git update-ref` will append
a line to the log file "$GIT_DIR/logs/<ref>" (dereferencing all
symbolic refs before creating the log name) describing the change
in ref value. Log lines are formatted as:
diff --git a/Documentation/git-update-server-info.txt b/Documentation/git-update-server-info.txt
index 775024d..bd0e364 100644
--- a/Documentation/git-update-server-info.txt
+++ b/Documentation/git-update-server-info.txt
@@ -8,6 +8,7 @@ git-update-server-info - Update auxiliary info file to help dumb servers
SYNOPSIS
--------
+[verse]
'git update-server-info' [--force]
DESCRIPTION
diff --git a/Documentation/git-upload-archive.txt b/Documentation/git-upload-archive.txt
index acbf634..4d52d38 100644
--- a/Documentation/git-upload-archive.txt
+++ b/Documentation/git-upload-archive.txt
@@ -8,6 +8,7 @@ git-upload-archive - Send archive back to git-archive
SYNOPSIS
--------
+[verse]
'git upload-archive' <directory>
DESCRIPTION
diff --git a/Documentation/git-upload-pack.txt b/Documentation/git-upload-pack.txt
index 4c0ca9d..71f1608 100644
--- a/Documentation/git-upload-pack.txt
+++ b/Documentation/git-upload-pack.txt
@@ -8,6 +8,7 @@ git-upload-pack - Send objects packed back to git-fetch-pack
SYNOPSIS
--------
+[verse]
'git-upload-pack' [--strict] [--timeout=<n>] <directory>
DESCRIPTION
@@ -33,6 +34,10 @@ OPTIONS
<directory>::
The repository to sync from.
+SEE ALSO
+--------
+linkgit:gitnamespaces[7]
+
GIT
---
Part of the linkgit:git[1] suite
diff --git a/Documentation/git-var.txt b/Documentation/git-var.txt
index 6498f7c..5317cc2 100644
--- a/Documentation/git-var.txt
+++ b/Documentation/git-var.txt
@@ -8,6 +8,7 @@ git-var - Show a git logical variable
SYNOPSIS
--------
+[verse]
'git var' ( -l | <variable> )
DESCRIPTION
diff --git a/Documentation/git-verify-pack.txt b/Documentation/git-verify-pack.txt
index 7c2428d..cd23076 100644
--- a/Documentation/git-verify-pack.txt
+++ b/Documentation/git-verify-pack.txt
@@ -8,6 +8,7 @@ git-verify-pack - Validate packed git archive files
SYNOPSIS
--------
+[verse]
'git verify-pack' [-v|--verbose] [-s|--stat-only] [--] <pack>.idx ...
diff --git a/Documentation/git-verify-tag.txt b/Documentation/git-verify-tag.txt
index 8c9a718..5ff76e8 100644
--- a/Documentation/git-verify-tag.txt
+++ b/Documentation/git-verify-tag.txt
@@ -7,6 +7,7 @@ git-verify-tag - Check the GPG signature of tags
SYNOPSIS
--------
+[verse]
'git verify-tag' <tag>...
DESCRIPTION
diff --git a/Documentation/git-web--browse.txt b/Documentation/git-web--browse.txt
index 69d92fa..c2bc87b 100644
--- a/Documentation/git-web--browse.txt
+++ b/Documentation/git-web--browse.txt
@@ -7,6 +7,7 @@ git-web--browse - git helper script to launch a web browser
SYNOPSIS
--------
+[verse]
'git web{litdd}browse' [OPTIONS] URL/FILE ...
DESCRIPTION
@@ -68,7 +69,7 @@ browser.<tool>.path
You can explicitly provide a full path to your preferred browser by
setting the configuration variable 'browser.<tool>.path'. For example,
you can configure the absolute path to firefox by setting
-'browser.firefox.path'. Otherwise, 'git web--browse' assumes the tool
+'browser.firefox.path'. Otherwise, 'git web{litdd}browse' assumes the tool
is available in PATH.
browser.<tool>.cmd
diff --git a/Documentation/git-whatchanged.txt b/Documentation/git-whatchanged.txt
index 31f3663..76c7f7e 100644
--- a/Documentation/git-whatchanged.txt
+++ b/Documentation/git-whatchanged.txt
@@ -8,6 +8,7 @@ git-whatchanged - Show logs with difference each commit introduces
SYNOPSIS
--------
+[verse]
'git whatchanged' <option>...
DESCRIPTION
@@ -52,12 +53,12 @@ include::pretty-formats.txt[]
Examples
--------
-git whatchanged -p v2.6.12.. include/scsi drivers/scsi::
+`git whatchanged -p v2.6.12.. include/scsi drivers/scsi`::
Show as patches the commits since version 'v2.6.12' that changed
any file in the include/scsi or drivers/scsi subdirectories
-git whatchanged --since="2 weeks ago" \-- gitk::
+`git whatchanged --since="2 weeks ago" \-- gitk`::
Show the changes during the last two weeks to the file 'gitk'.
The "--" is necessary to avoid confusion with the *branch* named
diff --git a/Documentation/git-write-tree.txt b/Documentation/git-write-tree.txt
index e8c94c1..f22041a 100644
--- a/Documentation/git-write-tree.txt
+++ b/Documentation/git-write-tree.txt
@@ -8,6 +8,7 @@ git-write-tree - Create a tree object from the current index
SYNOPSIS
--------
+[verse]
'git write-tree' [--missing-ok] [--prefix=<prefix>/]
DESCRIPTION
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 3c7a832..e869032 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -10,8 +10,8 @@ SYNOPSIS
--------
[verse]
'git' [--version] [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
- [-p|--paginate|--no-pager] [--no-replace-objects]
- [--bare] [--git-dir=<path>] [--work-tree=<path>]
+ [-p|--paginate|--no-pager] [--no-replace-objects] [--bare]
+ [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
[-c <name>=<value>]
[--help] <command> [<args>]
@@ -44,9 +44,24 @@ unreleased) version of git, that is available from 'master'
branch of the `git.git` repository.
Documentation for older releases are available here:
-* link:v1.7.6/git.html[documentation for release 1.7.6]
+* link:v1.7.8/git.html[documentation for release 1.7.8]
* release notes for
+ link:RelNotes/1.7.8.txt[1.7.8].
+
+* link:v1.7.7.1/git.html[documentation for release 1.7.7.1]
+
+* release notes for
+ link:RelNotes/1.7.7.1.txt[1.7.7.1],
+ link:RelNotes/1.7.7.txt[1.7.7].
+
+* link:v1.7.6.4/git.html[documentation for release 1.7.6.4]
+
+* release notes for
+ link:RelNotes/1.7.6.4.txt[1.7.6.4],
+ link:RelNotes/1.7.6.3.txt[1.7.6.3],
+ link:RelNotes/1.7.6.2.txt[1.7.6.2],
+ link:RelNotes/1.7.6.1.txt[1.7.6.1],
link:RelNotes/1.7.6.txt[1.7.6].
* link:v1.7.5.4/git.html[documentation for release 1.7.5.4]
@@ -330,6 +345,11 @@ help ...`.
variable (see core.worktree in linkgit:git-config[1] for a
more detailed discussion).
+--namespace=<path>::
+ Set the git namespace. See linkgit:gitnamespaces[7] for more
+ details. Equivalent to setting the `GIT_NAMESPACE` environment
+ variable.
+
--bare::
Treat the repository as a bare repository. If GIT_DIR
environment is not set, it is set to the current working
@@ -523,16 +543,15 @@ Any git command accepting any <object> can also use the following
symbolic notation:
HEAD::
- indicates the head of the current branch (i.e. the
- contents of `$GIT_DIR/HEAD`).
+ indicates the head of the current branch.
<tag>::
a valid tag 'name'
- (i.e. the contents of `$GIT_DIR/refs/tags/<tag>`).
+ (i.e. a `refs/tags/<tag>` reference).
<head>::
a valid head 'name'
- (i.e. the contents of `$GIT_DIR/refs/heads/<head>`).
+ (i.e. a `refs/heads/<head>` reference).
For a more complete list of ways to spell object names, see
"SPECIFYING REVISIONS" section in linkgit:gitrevisions[7].
@@ -594,6 +613,10 @@ git so take care if using Cogito etc.
This can also be controlled by the '--work-tree' command line
option and the core.worktree configuration variable.
+'GIT_NAMESPACE'::
+ Set the git namespace; see linkgit:gitnamespaces[7] for details.
+ The '--namespace' command-line option also sets this value.
+
'GIT_CEILING_DIRECTORIES'::
This should be a colon-separated list of absolute paths.
If set, it is a list of directories that git should not chdir
diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt
index 412c55b..a85b187 100644
--- a/Documentation/gitattributes.txt
+++ b/Documentation/gitattributes.txt
@@ -79,7 +79,7 @@ Attributes for all users on a system should be placed in the
`$(prefix)/etc/gitattributes` file.
Sometimes you would need to override an setting of an attribute
-for a path to `unspecified` state. This can be done by listing
+for a path to `Unspecified` state. This can be done by listing
the name of the attribute prefixed with an exclamation point `!`.
@@ -500,6 +500,8 @@ patterns are available:
- `java` suitable for source code in the Java language.
+- `matlab` suitable for source code in the MATLAB language.
+
- `objc` suitable for source code in the Objective-C language.
- `pascal` suitable for source code in the Pascal/Delphi language.
@@ -868,7 +870,7 @@ If this attribute is not set or has an invalid value, the value of the
(See linkgit:git-config[1]).
-USING ATTRIBUTE MACROS
+USING MACRO ATTRIBUTES
----------------------
You do not want any end-of-line conversions applied to, nor textual diffs
@@ -879,24 +881,27 @@ produced for, any binary file you track. You would need to specify e.g.
------------
but that may become cumbersome, when you have many attributes. Using
-attribute macros, you can specify groups of attributes set or unset at
-the same time. The system knows a built-in attribute macro, `binary`:
+macro attributes, you can define an attribute that, when set, also
+sets or unsets a number of other attributes at the same time. The
+system knows a built-in macro attribute, `binary`:
------------
*.jpg binary
------------
-which is equivalent to the above. Note that the attribute macros can only
-be "Set" (see the above example that sets "binary" macro as if it were an
-ordinary attribute --- setting it in turn unsets "text" and "diff").
+Setting the "binary" attribute also unsets the "text" and "diff"
+attributes as above. Note that macro attributes can only be "Set",
+though setting one might have the effect of setting or unsetting other
+attributes or even returning other attributes to the "Unspecified"
+state.
-DEFINING ATTRIBUTE MACROS
+DEFINING MACRO ATTRIBUTES
-------------------------
-Custom attribute macros can be defined only in the `.gitattributes` file
-at the toplevel (i.e. not in any subdirectory). The built-in attribute
-macro "binary" is equivalent to:
+Custom macro attributes can be defined only in the `.gitattributes`
+file at the toplevel (i.e. not in any subdirectory). The built-in
+macro attribute "binary" is equivalent to:
------------
[attr]binary -diff -text
@@ -952,6 +957,9 @@ frotz unspecified
----------------------------------------------------------------
+SEE ALSO
+--------
+linkgit:git-check-attr[1].
GIT
---
diff --git a/Documentation/gitcvs-migration.txt b/Documentation/gitcvs-migration.txt
index d861ec4..aeb0cdc 100644
--- a/Documentation/gitcvs-migration.txt
+++ b/Documentation/gitcvs-migration.txt
@@ -7,7 +7,8 @@ gitcvs-migration - git for CVS users
SYNOPSIS
--------
-git cvsimport *
+[verse]
+'git cvsimport' *
DESCRIPTION
-----------
diff --git a/Documentation/gitdiffcore.txt b/Documentation/gitdiffcore.txt
index 6af29a4..370624c 100644
--- a/Documentation/gitdiffcore.txt
+++ b/Documentation/gitdiffcore.txt
@@ -7,6 +7,7 @@ gitdiffcore - Tweaking diff output
SYNOPSIS
--------
+[verse]
'git diff' *
DESCRIPTION
diff --git a/Documentation/gitk.txt b/Documentation/gitk.txt
index e10ac58..a17a354 100644
--- a/Documentation/gitk.txt
+++ b/Documentation/gitk.txt
@@ -7,6 +7,7 @@ gitk - The git repository browser
SYNOPSIS
--------
+[verse]
'gitk' [<option>...] [<revs>] [--] [<path>...]
DESCRIPTION
diff --git a/Documentation/gitnamespaces.txt b/Documentation/gitnamespaces.txt
new file mode 100644
index 0000000..c6713cf
--- /dev/null
+++ b/Documentation/gitnamespaces.txt
@@ -0,0 +1,82 @@
+gitnamespaces(7)
+================
+
+NAME
+----
+gitnamespaces - Git namespaces
+
+SYNOPSIS
+--------
+[verse]
+GIT_NAMESPACE=<namespace> 'git upload-pack'
+GIT_NAMESPACE=<namespace> 'git receive-pack'
+
+
+DESCRIPTION
+-----------
+
+Git supports dividing the refs of a single repository into multiple
+namespaces, each of which has its own branches, tags, and HEAD. Git can
+expose each namespace as an independent repository to pull from and push
+to, while sharing the object store, and exposing all the refs to
+operations such as linkgit:git-gc[1].
+
+Storing multiple repositories as namespaces of a single repository
+avoids storing duplicate copies of the same objects, such as when
+storing multiple branches of the same source. The alternates mechanism
+provides similar support for avoiding duplicates, but alternates do not
+prevent duplication between new objects added to the repositories
+without ongoing maintenance, while namespaces do.
+
+To specify a namespace, set the `GIT_NAMESPACE` environment variable to
+the namespace. For each ref namespace, git stores the corresponding
+refs in a directory under `refs/namespaces/`. For example,
+`GIT_NAMESPACE=foo` will store refs under `refs/namespaces/foo/`. You
+can also specify namespaces via the `--namespace` option to
+linkgit:git[1].
+
+Note that namespaces which include a `/` will expand to a hierarchy of
+namespaces; for example, `GIT_NAMESPACE=foo/bar` will store refs under
+`refs/namespaces/foo/refs/namespaces/bar/`. This makes paths in
+`GIT_NAMESPACE` behave hierarchically, so that cloning with
+`GIT_NAMESPACE=foo/bar` produces the same result as cloning with
+`GIT_NAMESPACE=foo` and cloning from that repo with `GIT_NAMESPACE=bar`. It
+also avoids ambiguity with strange namespace paths such as `foo/refs/heads/`,
+which could otherwise generate directory/file conflicts within the `refs`
+directory.
+
+linkgit:git-upload-pack[1] and linkgit:git-receive-pack[1] rewrite the
+names of refs as specified by `GIT_NAMESPACE`. git-upload-pack and
+git-receive-pack will ignore all references outside the specified
+namespace.
+
+The smart HTTP server, linkgit:git-http-backend[1], will pass
+GIT_NAMESPACE through to the backend programs; see
+linkgit:git-http-backend[1] for sample configuration to expose
+repository namespaces as repositories.
+
+For a simple local test, you can use linkgit:git-remote-ext[1]:
+
+----------
+git clone ext::'git --namespace=foo %s /tmp/prefixed.git'
+----------
+
+SECURITY
+--------
+
+Anyone with access to any namespace within a repository can potentially
+access objects from any other namespace stored in the same repository.
+You can't directly say "give me object ABCD" if you don't have a ref to
+it, but you can do some other sneaky things like:
+
+. Claiming to push ABCD, at which point the server will optimize out the
+ need for you to actually send it. Now you have a ref to ABCD and can
+ fetch it (claiming not to have it, of course).
+
+. Requesting other refs, claiming that you have ABCD, at which point the
+ server may generate deltas against ABCD.
+
+None of this causes a problem if you only host public repositories, or
+if everyone who may read one namespace may also read everything in every
+other namespace (for instance, if everyone in an organization has read
+permission to every repository).
diff --git a/Documentation/gitrepository-layout.txt b/Documentation/gitrepository-layout.txt
index eb3d040..5c891f1 100644
--- a/Documentation/gitrepository-layout.txt
+++ b/Documentation/gitrepository-layout.txt
@@ -23,32 +23,25 @@ objects::
Object store associated with this repository. Usually
an object store is self sufficient (i.e. all the objects
that are referred to by an object found in it are also
- found in it), but there are couple of ways to violate
- it.
+ found in it), but there are a few ways to violate it.
+
-. You could populate the repository by running a commit walker
-without `-a` option. Depending on which options are given, you
-could have only commit objects without associated blobs and
-trees this way, for example. A repository with this kind of
-incomplete object store is not suitable to be published to the
-outside world but sometimes useful for private repository.
-. You also could have an incomplete but locally usable repository
-by cloning shallowly. See linkgit:git-clone[1].
-. You can be using `objects/info/alternates` mechanism, or
-`$GIT_ALTERNATE_OBJECT_DIRECTORIES` mechanism to 'borrow'
+. You could have an incomplete but locally usable repository
+by creating a shallow clone. See linkgit:git-clone[1].
+. You could be using the `objects/info/alternates` or
+`$GIT_ALTERNATE_OBJECT_DIRECTORIES` mechanisms to 'borrow'
objects from other object stores. A repository with this kind
of incomplete object store is not suitable to be published for
use with dumb transports but otherwise is OK as long as
-`objects/info/alternates` points at the right object stores
-it borrows from.
+`objects/info/alternates` points at the object stores it
+borrows from.
objects/[0-9a-f][0-9a-f]::
- Traditionally, each object is stored in its own file.
- They are split into 256 subdirectories using the first
- two letters from its object name to keep the number of
- directory entries `objects` directory itself needs to
- hold. Objects found here are often called 'unpacked'
- (or 'loose') objects.
+ A newly created object is stored in its own file.
+ The objects are splayed over 256 subdirectories using
+ the first two characters of the sha1 object name to
+ keep the number of directory entries in `objects`
+ itself to a manageable number. Objects found
+ here are often called 'unpacked' (or 'loose') objects.
objects/pack::
Packs (files that store many object in compressed form,
@@ -85,7 +78,7 @@ objects/info/http-alternates::
refs::
References are stored in subdirectories of this
- directory. The 'git prune' command knows to keep
+ directory. The 'git prune' command knows to preserve
objects reachable from refs found in this directory and
its subdirectories.
@@ -119,16 +112,17 @@ HEAD::
+
HEAD can also record a specific commit directly, instead of
being a symref to point at the current branch. Such a state
-is often called 'detached HEAD', and almost all commands work
-identically as normal. See linkgit:git-checkout[1] for
-details.
+is often called 'detached HEAD.' See linkgit:git-checkout[1]
+for details.
branches::
A slightly deprecated way to store shorthands to be used
- to specify URL to 'git fetch', 'git pull' and 'git push'
- commands is to store a file in `branches/<name>` and
- give 'name' to these commands in place of 'repository'
- argument.
+ to specify a URL to 'git fetch', 'git pull' and 'git push'.
+ A file can be stored as `branches/<name>` and then
+ 'name' can be given to these commands in place of
+ 'repository' argument. See the REMOTES section in
+ linkgit:git-fetch[1] for details. This mechanism is legacy
+ and not likely to be found in modern repositories.
hooks::
Hooks are customization scripts used by various git
@@ -173,9 +167,11 @@ info/exclude::
at it. See also: linkgit:gitignore[5].
remotes::
- Stores shorthands to be used to give URL and default
- refnames to interact with remote repository to
- 'git fetch', 'git pull' and 'git push' commands.
+ Stores shorthands for URL and default refnames for use
+ when interacting with remote repositories via 'git fetch',
+ 'git pull' and 'git push' commands. See the REMOTES section
+ in linkgit:git-fetch[1] for details. This mechanism is legacy
+ and not likely to be found in modern repositories.
logs::
Records of changes made to refs are stored in this
diff --git a/Documentation/gittutorial-2.txt b/Documentation/gittutorial-2.txt
index 7fe5848..f1e4422 100644
--- a/Documentation/gittutorial-2.txt
+++ b/Documentation/gittutorial-2.txt
@@ -7,6 +7,7 @@ gittutorial-2 - A tutorial introduction to git: part two
SYNOPSIS
--------
+[verse]
git *
DESCRIPTION
diff --git a/Documentation/gittutorial.txt b/Documentation/gittutorial.txt
index 0982f74..dee0505 100644
--- a/Documentation/gittutorial.txt
+++ b/Documentation/gittutorial.txt
@@ -7,6 +7,7 @@ gittutorial - A tutorial introduction to git (for version 1.5.1 or newer)
SYNOPSIS
--------
+[verse]
git *
DESCRIPTION
diff --git a/Documentation/gitweb.conf.txt b/Documentation/gitweb.conf.txt
new file mode 100644
index 0000000..7aba497
--- /dev/null
+++ b/Documentation/gitweb.conf.txt
@@ -0,0 +1,889 @@
+gitweb.conf(5)
+==============
+
+NAME
+----
+gitweb.conf - Gitweb (git web interface) configuration file
+
+SYNOPSIS
+--------
+/etc/gitweb.conf, /etc/gitweb-common.conf, $GITWEBDIR/gitweb_config.perl
+
+DESCRIPTION
+-----------
+
+The gitweb CGI script for viewing Git repositories over the web uses a
+perl script fragment as its configuration file. You can set variables
+using "`our $variable = value`"; text from a "#" character until the
+end of a line is ignored. See *perlsyn*(1) for details.
+
+An example:
+
+ # gitweb configuration file for http://git.example.org
+ #
+ our $projectroot = "/srv/git"; # FHS recommendation
+ our $site_name = 'Example.org >> Repos';
+
+
+The configuration file is used to override the default settings that
+were built into gitweb at the time the 'gitweb.cgi' script was generated.
+
+While one could just alter the configuration settings in the gitweb
+CGI itself, those changes would be lost upon upgrade. Configuration
+settings might also be placed into a file in the same directory as the
+CGI script with the default name 'gitweb_config.perl' -- allowing
+one to have multiple gitweb instances with different configurations by
+the use of symlinks.
+
+Note that some configuration can be controlled on per-repository rather than
+gitweb-wide basis: see "Per-repository gitweb configuration" subsection on
+linkgit:gitweb[1] manpage.
+
+
+DISCUSSION
+----------
+Gitweb reads configuration data from the following sources in the
+following order:
+
+ * built-in values (some set during build stage),
+
+ * common system-wide configuration file (defaults to
+ '/etc/gitweb-common.conf'),
+
+ * either per-instance configuration file (defaults to 'gitweb_config.perl'
+ in the same directory as the installed gitweb), or if it does not exists
+ then fallback system-wide configuration file (defaults to '/etc/gitweb.conf').
+
+Values obtained in later configuration files override values obtained earlier
+in the above sequence.
+
+Locations of the common system-wide configuration file, the fallback
+system-wide configuration file and the per-instance configuration file
+are defined at compile time using build-time Makefile configuration
+variables, respectively `GITWEB_CONFIG_COMMON`, `GITWEB_CONFIG_SYSTEM`
+and `GITWEB_CONFIG`.
+
+You can also override locations of gitweb configuration files during
+runtime by setting the following environment variables:
+`GITWEB_CONFIG_COMMON`, `GITWEB_CONFIG_SYSTEM` and `GITWEB_CONFIG`
+to a non-empty value.
+
+
+The syntax of the configuration files is that of Perl, since these files are
+handled by sourcing them as fragments of Perl code (the language that
+gitweb itself is written in). Variables are typically set using the
+`our` qualifier (as in "`our $variable = <value>;`") to avoid syntax
+errors if a new version of gitweb no longer uses a variable and therefore
+stops declaring it.
+
+You can include other configuration file using read_config_file()
+subroutine. For example, one might want to put gitweb configuration
+related to access control for viewing repositories via Gitolite (one
+of git repository management tools) in a separate file, e.g. in
+'/etc/gitweb-gitolite.conf'. To include it, put
+
+--------------------------------------------------
+read_config_file("/etc/gitweb-gitolite.conf");
+--------------------------------------------------
+
+somewhere in gitweb configuration file used, e.g. in per-installation
+gitweb configuration file. Note that read_config_file() checks itself
+that the file it reads exists, and does nothing if it is not found.
+It also handles errors in included file.
+
+
+The default configuration with no configuration file at all may work
+perfectly well for some installations. Still, a configuration file is
+useful for customizing or tweaking the behavior of gitweb in many ways, and
+some optional features will not be present unless explicitly enabled using
+the configurable `%features` variable (see also "Configuring gitweb
+features" section below).
+
+
+CONFIGURATION VARIABLES
+-----------------------
+Some configuration variables have their default values (embedded in the CGI
+script) set during building gitweb -- if that is the case, this fact is put
+in their description. See gitweb's 'INSTALL' file for instructions on building
+and installing gitweb.
+
+
+Location of repositories
+~~~~~~~~~~~~~~~~~~~~~~~~
+The configuration variables described below control how gitweb finds
+git repositories, and how repositories are displayed and accessed.
+
+See also "Repositories" and later subsections in linkgit:gitweb[1] manpage.
+
+$projectroot::
+ Absolute filesystem path which will be prepended to project path;
+ the path to repository is `$projectroot/$project`. Set to
+ `$GITWEB_PROJECTROOT` during installation. This variable has to be
+ set correctly for gitweb to find repositories.
++
+For example, if `$projectroot` is set to "/srv/git" by putting the following
+in gitweb config file:
++
+----------------------------------------------------------------------------
+our $projectroot = "/srv/git";
+----------------------------------------------------------------------------
++
+then
++
+------------------------------------------------
+http://git.example.com/gitweb.cgi?p=foo/bar.git
+------------------------------------------------
++
+and its path_info based equivalent
++
+------------------------------------------------
+http://git.example.com/gitweb.cgi/foo/bar.git
+------------------------------------------------
++
+will map to the path '/srv/git/foo/bar.git' on the filesystem.
+
+$projects_list::
+ Name of a plain text file listing projects, or a name of directory
+ to be scanned for projects.
++
+Project list files should list one project per line, with each line
+having the following format
++
+-----------------------------------------------------------------------------
+<URI-encoded filesystem path to repository> SP <URI-encoded repository owner>
+-----------------------------------------------------------------------------
++
+The default value of this variable is determined by the `GITWEB_LIST`
+makefile variable at installation time. If this variable is empty, gitweb
+will fall back to scanning the `$projectroot` directory for repositories.
+
+$project_maxdepth::
+ If `$projects_list` variable is unset, gitweb will recursively
+ scan filesystem for git repositories. The `$project_maxdepth`
+ is used to limit traversing depth, relative to `$projectroot`
+ (starting point); it means that directories which are further
+ from `$projectroot` than `$project_maxdepth` will be skipped.
++
+It is purely performance optimization, originally intended for MacOS X,
+where recursive directory traversal is slow. Gitweb follows symbolic
+links, but it detects cycles, ignoring any duplicate files and directories.
++
+The default value of this variable is determined by the build-time
+configuration variable `GITWEB_PROJECT_MAXDEPTH`, which defaults to
+2007.
+
+$export_ok::
+ Show repository only if this file exists (in repository). Only
+ effective if this variable evaluates to true. Can be set when
+ building gitweb by setting `GITWEB_EXPORT_OK`. This path is
+ relative to `GIT_DIR`. git-daemon[1] uses 'git-daemon-export-ok',
+ unless started with `--export-all`. By default this variable is
+ not set, which means that this feature is turned off.
+
+$export_auth_hook::
+ Function used to determine which repositories should be shown.
+ This subroutine should take one parameter, the full path to
+ a project, and if it returns true, that project will be included
+ in the projects list and can be accessed through gitweb as long
+ as it fulfills the other requirements described by $export_ok,
+ $projects_list, and $projects_maxdepth. Example:
++
+----------------------------------------------------------------------------
+our $export_auth_hook = sub { return -e "$_[0]/git-daemon-export-ok"; };
+----------------------------------------------------------------------------
++
+though the above might be done by using `$export_ok` instead
++
+----------------------------------------------------------------------------
+our $export_ok = "git-daemon-export-ok";
+----------------------------------------------------------------------------
++
+If not set (default), it means that this feature is disabled.
++
+See also more involved example in "Controlling access to git repositories"
+subsection on linkgit:gitweb[1] manpage.
+
+$strict_export::
+ Only allow viewing of repositories also shown on the overview page.
+ This for example makes `$gitweb_export_ok` file decide if repository is
+ available and not only if it is shown. If `$gitweb_list` points to
+ file with list of project, only those repositories listed would be
+ available for gitweb. Can be set during building gitweb via
+ `GITWEB_STRICT_EXPORT`. By default this variable is not set, which
+ means that you can directly access those repositories that are hidden
+ from projects list page (e.g. the are not listed in the $projects_list
+ file).
+
+
+Finding files
+~~~~~~~~~~~~~
+The following configuration variables tell gitweb where to find files.
+The values of these variables are paths on the filesystem.
+
+$GIT::
+ Core git executable to use. By default set to `$GIT_BINDIR/git`, which
+ in turn is by default set to `$(bindir)/git`. If you use git installed
+ from a binary package, you should usually set this to "/usr/bin/git".
+ This can just be "git" if your web server has a sensible PATH; from
+ security point of view it is better to use absolute path to git binary.
+ If you have multiple git versions installed it can be used to choose
+ which one to use. Must be (correctly) set for gitweb to be able to
+ work.
+
+$mimetypes_file::
+ File to use for (filename extension based) guessing of MIME types before
+ trying '/etc/mime.types'. *NOTE* that this path, if relative, is taken
+ as relative to the current git repository, not to CGI script. If unset,
+ only '/etc/mime.types' is used (if present on filesystem). If no mimetypes
+ file is found, mimetype guessing based on extension of file is disabled.
+ Unset by default.
+
+$highlight_bin::
+ Path to the highlight executable to use (it must be the one from
+ http://www.andre-simon.de[] due to assumptions about parameters and output).
+ By default set to 'highlight'; set it to full path to highlight
+ executable if it is not installed on your web server's PATH.
+ Note that 'highlight' feature must be set for gitweb to actually
+ use syntax hightlighting.
++
+*NOTE*: if you want to add support for new file type (supported by
+"highlight" but not used by gitweb), you need to modify `%highlight_ext`
+or `%highlight_basename`, depending on whether you detect type of file
+based on extension (for example "sh") or on its basename (for example
+"Makefile"). The keys of these hashes are extension and basename,
+respectively, and value for given key is name of syntax to be passed via
+`--syntax <syntax>` to highlighter.
++
+For example if repositories you are hosting use "phtml" extension for
+PHP files, and you want to have correct syntax-highlighting for those
+files, you can add the following to gitweb configuration:
++
+---------------------------------------------------------
+our %highlight_ext;
+$highlight_ext{'phtml'} = 'php';
+---------------------------------------------------------
+
+
+Links and their targets
+~~~~~~~~~~~~~~~~~~~~~~~
+The configuration variables described below configure some of gitweb links:
+their target and their look (text or image), and where to find page
+prerequisites (stylesheet, favicon, images, scripts). Usually they are left
+at their default values, with the possible exception of `@stylesheets`
+variable.
+
+@stylesheets::
+ List of URIs of stylesheets (relative to the base URI of a page). You
+ might specify more than one stylesheet, for example to use "gitweb.css"
+ as base with site specific modifications in a separate stylesheet
+ to make it easier to upgrade gitweb. For example, you can add
+ a `site` stylesheet by putting
++
+----------------------------------------------------------------------------
+push @stylesheets, "gitweb-site.css";
+----------------------------------------------------------------------------
++
+in the gitweb config file. Those values that are relative paths are
+relative to base URI of gitweb.
++
+This list should contain the URI of gitweb's standard stylesheet. The default
+URI of gitweb stylesheet can be set at build time using the `GITWEB_CSS`
+makefile variable. Its default value is 'static/gitweb.css'
+(or 'static/gitweb.min.css' if the `CSSMIN` variable is defined,
+i.e. if CSS minifier is used during build).
++
+*Note*: there is also a legacy `$stylesheet` configuration variable, which was
+used by older gitweb. If `$stylesheet` variable is defined, only CSS stylesheet
+given by this variable is used by gitweb.
+
+$logo::
+ Points to the location where you put 'git-logo.png' on your web
+ server, or to be more the generic URI of logo, 72x27 size). This image
+ is displayed in the top right corner of each gitweb page and used as
+ a logo for the Atom feed. Relative to the base URI of gitweb (as a path).
+ Can be adjusted when building gitweb using `GITWEB_LOGO` variable
+ By default set to 'static/git-logo.png'.
+
+$favicon::
+ Points to the location where you put 'git-favicon.png' on your web
+ server, or to be more the generic URI of favicon, which will be served
+ as "image/png" type. Web browsers that support favicons (website icons)
+ may display them in the browser's URL bar and next to the site name in
+ bookmarks. Relative to the base URI of gitweb. Can be adjusted at
+ build time using `GITWEB_FAVICON` variable.
+ By default set to 'static/git-favicon.png'.
+
+$javascript::
+ Points to the location where you put 'gitweb.js' on your web server,
+ or to be more generic the URI of JavaScript code used by gitweb.
+ Relative to the base URI of gitweb. Can be set at build time using
+ the `GITWEB_JS` build-time configuration variable.
++
+The default value is either 'static/gitweb.js', or 'static/gitweb.min.js' if
+the `JSMIN` build variable was defined, i.e. if JavaScript minifier was used
+at build time. *Note* that this single file is generated from multiple
+individual JavaScript "modules".
+
+$home_link::
+ Target of the home link on the top of all pages (the first part of view
+ "breadcrumbs"). By default it is set to the absolute URI of a current page
+ (to the value of `$my_uri` variable, or to "/" if `$my_uri` is undefined
+ or is an empty string).
+
+$home_link_str::
+ Label for the "home link" at the top of all pages, leading to `$home_link`
+ (usually the main gitweb page, which contains the projects list). It is
+ used as the first component of gitweb's "breadcrumb trail":
+ `<home link> / <project> / <action>`. Can be set at build time using
+ the `GITWEB_HOME_LINK_STR` variable. By default it is set to "projects",
+ as this link leads to the list of projects. Other popular choice it to
+ set it to the name of site.
+
+$logo_url::
+$logo_label::
+ URI and label (title) for the Git logo link (or your site logo,
+ if you chose to use different logo image). By default, these both
+ refer to git homepage, http://git-scm.com[]; in the past, they pointed
+ to git documentation at http://www.kernel.org[].
+
+
+Changing gitweb's look
+~~~~~~~~~~~~~~~~~~~~~~
+You can adjust how pages generated by gitweb look using the variables described
+below. You can change the site name, add common headers and footers for all
+pages, and add a description of this gitweb installation on its main page
+(which is the projects list page), etc.
+
+$site_name::
+ Name of your site or organization, to appear in page titles. Set it
+ to something descriptive for clearer bookmarks etc. If this variable
+ is not set or is, then gitweb uses the value of the `SERVER_NAME`
+ CGI environment variable, setting site name to "$SERVER_NAME Git",
+ or "Untitled Git" if this variable is not set (e.g. if running gitweb
+ as standalone script).
++
+Can be set using the `GITWEB_SITENAME` at build time. Unset by default.
+
+$site_html_head_string::
+ HTML snippet to be included in the <head> section of each page.
+ Can be set using `GITWEB_SITE_HTML_HEAD_STRING` at build time.
+ No default value.
+
+$site_header::
+ Name of a file with HTML to be included at the top of each page.
+ Relative to the directory containing the 'gitweb.cgi' script.
+ Can be set using `GITWEB_SITE_HEADER` at build time. No default
+ value.
+
+$site_footer::
+ Name of a file with HTML to be included at the bottom of each page.
+ Relative to the directory containing the 'gitweb.cgi' script.
+ Can be set using `GITWEB_SITE_FOOTER` at build time. No default
+ value.
+
+$home_text::
+ Name of a HTML file which, if it exists, is included on the
+ gitweb projects overview page ("projects_list" view). Relative to
+ the directory containing the gitweb.cgi script. Default value
+ can be adjusted during build time using `GITWEB_HOMETEXT` variable.
+ By default set to 'indextext.html'.
+
+$projects_list_description_width::
+ The width (in characters) of the "Description" column of the projects list.
+ Longer descriptions will be truncated (trying to cut at word boundary);
+ the full description is available in the 'title' attribute (usually shown on
+ mouseover). The default is 25, which might be too small if you
+ use long project descriptions.
+
+$default_projects_order::
+ Default value of ordering of projects on projects list page, which
+ means the ordering used if you don't explicitly sort projects list
+ (if there is no "o" CGI query parameter in the URL). Valid values
+ are "none" (unsorted), "project" (projects are by project name,
+ i.e. path to repository relative to `$projectroot`), "descr"
+ (project description), "owner", and "age" (by date of most current
+ commit).
++
+Default value is "project". Unknown value means unsorted.
+
+
+Changing gitweb's behavior
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+These configuration variables control _internal_ gitweb behavior.
+
+$default_blob_plain_mimetype::
+ Default mimetype for the blob_plain (raw) view, if mimetype checking
+ doesn't result in some other type; by default "text/plain".
+ Gitweb guesses mimetype of a file to display based on extension
+ of its filename, using `$mimetypes_file` (if set and file exists)
+ and '/etc/mime.types' files (see *mime.types*(5) manpage; only
+ filename extension rules are supported by gitweb).
+
+$default_text_plain_charset::
+ Default charset for text files. If this is not set, the web server
+ configuration will be used. Unset by default.
+
+$fallback_encoding::
+ Gitweb assumes this charset when a line contains non-UTF-8 characters.
+ The fallback decoding is used without error checking, so it can be even
+ "utf-8". The value must be a valid encoding; see the *Encoding::Supported*(3pm)
+ man page for a list. The default is "latin1", aka. "iso-8859-1".
+
+@diff_opts::
+ Rename detection options for git-diff and git-diff-tree. The default is
+ (\'-M'); set it to (\'-C') or (\'-C', \'-C') to also detect copies,
+ or set it to () i.e. empty list if you don't want to have renames
+ detection.
++
+*Note* that rename and especially copy detection can be quite
+CPU-intensive. Note also that non git tools can have problems with
+patches generated with options mentioned above, especially when they
+involve file copies (\'-C') or criss-cross renames (\'-B').
+
+
+Some optional features and policies
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Most of features are configured via `%feature` hash; however some of extra
+gitweb features can be turned on and configured using variables described
+below. This list beside configuration variables that control how gitweb
+looks does contain variables configuring administrative side of gitweb
+(e.g. cross-site scripting prevention; admittedly this as side effect
+affects how "summary" pages look like, or load limiting).
+
+@git_base_url_list::
+ List of git base URLs. These URLs are used to generate URLs
+ describing from where to fetch a project, which are shown on
+ project summary page. The full fetch URL is "`$git_base_url/$project`",
+ for each element of this list. You can set up multiple base URLs
+ (for example one for `git://` protocol, and one for `http://`
+ protocol).
++
+Note that per repository configuration can be set in '$GIT_DIR/cloneurl'
+file, or as values of multi-value `gitweb.url` configuration variable in
+project config. Per-repository configuration takes precedence over value
+composed from `@git_base_url_list` elements and project name.
++
+You can setup one single value (single entry/item in this list) at build
+time by setting the `GITWEB_BASE_URL` built-time configuration variable.
+By default it is set to (), i.e. an empty list. This means that gitweb
+would not try to create project URL (to fetch) from project name.
+
+$projects_list_group_categories::
+ Whether to enables the grouping of projects by category on the project
+ list page. The category of a project is determined by the
+ `$GIT_DIR/category` file or the `gitweb.category` variable in each
+ repository's configuration. Disabled by default (set to 0).
+
+$project_list_default_category::
+ Default category for projects for which none is specified. If this is
+ set to the empty string, such projects will remain uncategorized and
+ listed at the top, above categorized projects. Used only if project
+ categories are enabled, which means if `$projects_list_group_categories`
+ is true. By default set to "" (empty string).
+
+$prevent_xss::
+ If true, some gitweb features are disabled to prevent content in
+ repositories from launching cross-site scripting (XSS) attacks. Set this
+ to true if you don't trust the content of your repositories.
+ False by default (set to 0).
+
+$maxload::
+ Used to set the maximum load that we will still respond to gitweb queries.
+ If the server load exceeds this value then gitweb will return
+ "503 Service Unavailable" error. The server load is taken to be 0
+ if gitweb cannot determine its value. Currently it works only on Linux,
+ where it uses '/proc/loadavg'; the load there is the number of active
+ tasks on the system -- processes that are actually running -- averaged
+ over the last minute.
++
+Set `$maxload` to undefined value (`undef`) to turn this feature off.
+The default value is 300.
+
+$per_request_config::
+ If this is set to code reference, it will be run once for each request.
+ You can set parts of configuration that change per session this way.
+ For example, one might use the following code in a gitweb configuration
+ file
++
+--------------------------------------------------------------------------------
+our $per_request_config = sub {
+ $ENV{GL_USER} = $cgi->remote_user || "gitweb";
+};
+--------------------------------------------------------------------------------
++
+If `$per_request_config` is not a code reference, it is interpreted as boolean
+value. If it is true gitweb will process config files once per request,
+and if it is false gitweb will process config files only once, each time it
+is executed. True by default (set to 1).
++
+*NOTE*: `$my_url`, `$my_uri`, and `$base_url` are overwritten with their default
+values before every request, so if you want to change them, be sure to set
+this variable to true or a code reference effecting the desired changes.
++
+This variable matters only when using persistent web environments that
+serve multiple requests using single gitweb instance, like mod_perl,
+FastCGI or Plackup.
+
+
+Other variables
+~~~~~~~~~~~~~~~
+Usually you should not need to change (adjust) any of configuration
+variables described below; they should be automatically set by gitweb to
+correct value.
+
+
+$version::
+ Gitweb version, set automatically when creating gitweb.cgi from
+ gitweb.perl. You might want to modify it if you are running modified
+ gitweb, for example
++
+---------------------------------------------------
+our $version .= " with caching";
+---------------------------------------------------
++
+if you run modified version of gitweb with caching support. This variable
+is purely informational, used e.g. in the "generator" meta header in HTML
+header.
+
+$my_url::
+$my_uri::
+ Full URL and absolute URL of the gitweb script;
+ in earlier versions of gitweb you might have need to set those
+ variables, but now there should be no need to do it. See
+ `$per_request_config` if you need to set them still.
+
+$base_url::
+ Base URL for relative URLs in pages generated by gitweb,
+ (e.g. `$logo`, `$favicon`, `@stylesheets` if they are relative URLs),
+ needed and used '<base href="$base_url">' only for URLs with nonempty
+ PATH_INFO. Usually gitweb sets its value correctly,
+ and there is no need to set this variable, e.g. to $my_uri or "/".
+ See `$per_request_config` if you need to override it anyway.
+
+
+CONFIGURING GITWEB FEATURES
+---------------------------
+Many gitweb features can be enabled (or disabled) and configured using the
+`%feature` hash. Names of gitweb features are keys of this hash.
+
+Each `%feature` hash element is a hash reference and has the following
+structure:
+----------------------------------------------------------------------
+"<feature_name>" => {
+ "sub" => <feature-sub (subroutine)>,
+ "override" => <allow-override (boolean)>,
+ "default" => [ <options>... ]
+},
+----------------------------------------------------------------------
+Some features cannot be overridden per project. For those
+features the structure of appropriate `%feature` hash element has a simpler
+form:
+----------------------------------------------------------------------
+"<feature_name>" => {
+ "override" => 0,
+ "default" => [ <options>... ]
+},
+----------------------------------------------------------------------
+As one can see it lacks the \'sub' element.
+
+The meaning of each part of feature configuration is described
+below:
+
+default::
+ List (array reference) of feature parameters (if there are any),
+ used also to toggle (enable or disable) given feature.
++
+Note that it is currently *always* an array reference, even if
+feature doesn't accept any configuration parameters, and \'default'
+is used only to turn it on or off. In such case you turn feature on
+by setting this element to `[1]`, and torn it off by setting it to
+`[0]`. See also the passage about the "blame" feature in the "Examples"
+section.
++
+To disable features that accept parameters (are configurable), you
+need to set this element to empty list i.e. `[]`.
+
+override::
+ If this field has a true value then the given feature is
+ overriddable, which means that it can be configured
+ (or enabled/disabled) on a per-repository basis.
++
+Usually given "<feature>" is configurable via the `gitweb.<feature>`
+config variable in the per-repository git configuration file.
++
+*Note* that no feature is overriddable by default.
+
+sub::
+ Internal detail of implementation. What is important is that
+ if this field is not present then per-repository override for
+ given feature is not supported.
++
+You wouldn't need to ever change it in gitweb config file.
+
+
+Features in `%feature`
+~~~~~~~~~~~~~~~~~~~~~~
+The gitweb features that are configurable via `%feature` hash are listed
+below. This should be a complete list, but ultimately the authoritative
+and complete list is in gitweb.cgi source code, with features described
+in the comments.
+
+blame::
+ Enable the "blame" and "blame_incremental" blob views, showing for
+ each line the last commit that modified it; see linkgit:git-blame[1].
+ This can be very CPU-intensive and is therefore disabled by default.
++
+This feature can be configured on a per-repository basis via
+repository's `gitweb.blame` configuration variable (boolean).
+
+snapshot::
+ Enable and configure the "snapshot" action, which allows user to
+ download a compressed archive of any tree or commit, as produced
+ by linkgit:git-archive[1] and possibly additionally compressed.
+ This can potentially generate high traffic if you have large project.
++
+The value of \'default' is a list of names of snapshot formats,
+defined in `%known_snapshot_formats` hash, that you wish to offer.
+Supported formats include "tgz", "tbz2", "txz" (gzip/bzip2/xz
+compressed tar archive) and "zip"; please consult gitweb sources for
+a definitive list. By default only "tgz" is offered.
++
+This feature can be configured on a per-repository basis via
+repository's `gitweb.blame` configuration variable, which contains
+a comma separated list of formats or "none" to disable snapshots.
+Unknown values are ignored.
+
+grep::
+ Enable grep search, which lists the files in currently selected
+ tree (directory) containing the given string; see linkgit:git-grep[1].
+ This can be potentially CPU-intensive, of course. Enabled by default.
++
+This feature can be configured on a per-repository basis via
+repository's `gitweb.grep` configuration variable (boolean).
+
+pickaxe::
+ Enable the so called pickaxe search, which will list the commits
+ that introduced or removed a given string in a file. This can be
+ practical and quite faster alternative to "blame" action, but it is
+ still potentially CPU-intensive. Enabled by default.
++
+The pickaxe search is described in linkgit:git-log[1] (the
+description of `-S<string>` option, which refers to pickaxe entry in
+linkgit:gitdiffcore[7] for more details).
++
+This feature can be configured on a per-repository basis by setting
+repository's `gitweb.pickaxe` configuration variable (boolean).
+
+show-sizes::
+ Enable showing size of blobs (ordinary files) in a "tree" view, in a
+ separate column, similar to what `ls -l` does; see description of
+ `-l` option in linkgit:git-ls-tree[1] manpage. This costs a bit of
+ I/O. Enabled by default.
++
+This feature can be configured on a per-repository basis via
+repository's `gitweb.showsizes` configuration variable (boolean).
+
+patches::
+ Enable and configure "patches" view, which displays list of commits in email
+ (plain text) output format; see also linkgit:git-format-patch[1].
+ The value is the maximum number of patches in a patchset generated
+ in "patches" view. Set the 'default' field to a list containing single
+ item of or to an empty list to disable patch view, or to a list
+ containing a single negative number to remove any limit.
+ Default value is 16.
++
+This feature can be configured on a per-repository basis via
+repository's `gitweb.patches` configuration variable (integer).
+
+avatar::
+ Avatar support. When this feature is enabled, views such as
+ "shortlog" or "commit" will display an avatar associated with
+ the email of each committer and author.
++
+Currently available providers are *"gravatar"* and *"picon"*.
+Only one provider at a time can be selected ('default' is one element list).
+If an unknown provider is specified, the feature is disabled.
+*Note* that some providers might require extra Perl packages to be
+installed; see 'gitweb/INSTALL' for more details.
++
+This feature can be configured on a per-repository basis via
+repository's `gitweb.avatar` configuration variable.
++
+See also `%avatar_size` with pixel sizes for icons and avatars
+("default" is used for one-line like "log" and "shortlog", "double"
+is used for two-line like "commit", "commitdiff" or "tag"). If the
+default font sizes or lineheights are changed (e.g. via adding extra
+CSS stylesheet in `@stylesheets`), it may be appropriate to change
+these values.
+
+highlight::
+ Server-side syntax highlight support in "blob" view. It requires
+ `$highlight_bin` program to be available (see the description of
+ this variable in the "Configuration variables" section above),
+ and therefore is disabled by default.
++
+This feature can be configured on a per-repository basis via
+repository's `gitweb.highlight` configuration variable (boolean).
+
+remote_heads::
+ Enable displaying remote heads (remote-tracking branches) in the "heads"
+ list. In most cases the list of remote-tracking branches is an
+ unnecessary internal private detail, and this feature is therefore
+ disabled by default. linkgit:git-instaweb[1], which is usually used
+ to browse local repositories, enables and uses this feature.
++
+This feature can be configured on a per-repository basis via
+repository's `gitweb.remote_heads` configuration variable (boolean).
+
+
+The remaining features cannot be overridden on a per project basis.
+
+search::
+ Enable text search, which will list the commits which match author,
+ committer or commit text to a given string; see the description of
+ `--author`, `--committer` and `--grep` options in linkgit:git-log[1]
+ manpage. Enabled by default.
++
+Project specific override is not supported.
+
+forks::
+ If this feature is enabled, gitweb considers projects in
+ subdirectories of project root (basename) to be forks of existing
+ projects. For each project `$projname.git`, projects in the
+ `$projname/` directory and its subdirectories will not be
+ shown in the main projects list. Instead, a \'+' mark is shown
+ next to `$projname`, which links to a "forks" view that lists all
+ the forks (all projects in `$projname/` subdirectory). Additionally
+ a "forks" view for a project is linked from project summary page.
++
+If the project list is taken from a file (`$projects_list` points to a
+file), forks are only recognized if they are listed after the main project
+in that file.
++
+Project specific override is not supported.
+
+actions::
+ Insert custom links to the action bar of all project pages. This
+ allows you to link to third-party scripts integrating into gitweb.
++
+The "default" value consists of a list of triplets in the form
+`("<label>", "<link>", "<position>")` where "position" is the label
+after which to insert the link, "link" is a format string where `%n`
+expands to the project name, `%f` to the project path within the
+filesystem (i.e. "$projectroot/$project"), `%h` to the current hash
+(\'h' gitweb parameter) and `%b` to the current hash base
+(\'hb' gitweb parameter); `%%` expands to \'%'.
++
+For example, at the time this page was written, the http://repo.or.cz[]
+git hosting site set it to the following to enable graphical log
+(using the third party tool *git-browser*):
++
+----------------------------------------------------------------------
+$feature{'actions'}{'default'} =
+ [ ('graphiclog', '/git-browser/by-commit.html?r=%n', 'summary')];
+----------------------------------------------------------------------
++
+This adds a link titled "graphiclog" after the "summary" link, leading to
+`git-browser` script, passing `r=<project>` as a query parameter.
++
+Project specific override is not supported.
+
+timed::
+ Enable displaying how much time and how many git commands it took to
+ generate and display each page in the page footer (at the bottom of
+ page). For example the footer might contain: "This page took 6.53325
+ seconds and 13 git commands to generate." Disabled by default.
++
+Project specific override is not supported.
+
+javascript-timezone::
+ Enable and configure the ability to change a common timezone for dates
+ in gitweb output via JavaScript. Dates in gitweb output include
+ authordate and committerdate in "commit", "commitdiff" and "log"
+ views, and taggerdate in "tag" view. Enabled by default.
++
+The value is a list of three values: a default timezone (for if the client
+hasn't selected some other timezone and saved it in a cookie), a name of cookie
+where to store selected timezone, and a CSS class used to mark up
+dates for manipulation. If you want to turn this feature off, set "default"
+to empty list: `[]`.
++
+Typical gitweb config files will only change starting (default) timezone,
+and leave other elements at their default values:
++
+---------------------------------------------------------------------------
+$feature{'javascript-timezone'}{'default'}[0] = "utc";
+---------------------------------------------------------------------------
++
+The example configuration presented here is guaranteed to be backwards
+and forward compatible.
++
+Timezone values can be "local" (for local timezone that browser uses), "utc"
+(what gitweb uses when JavaScript or this feature is disabled), or numerical
+timezones in the form of "+/-HHMM", such as "+0200".
++
+Project specific override is not supported.
+
+
+EXAMPLES
+--------
+
+To enable blame, pickaxe search, and snapshot support (allowing "tar.gz" and
+"zip" snapshots), while allowing individual projects to turn them off, put
+the following in your GITWEB_CONFIG file:
+
+ $feature{'blame'}{'default'} = [1];
+ $feature{'blame'}{'override'} = 1;
+
+ $feature{'pickaxe'}{'default'} = [1];
+ $feature{'pickaxe'}{'override'} = 1;
+
+ $feature{'snapshot'}{'default'} = ['zip', 'tgz'];
+ $feature{'snapshot'}{'override'} = 1;
+
+If you allow overriding for the snapshot feature, you can specify which
+snapshot formats are globally disabled. You can also add any command line
+options you want (such as setting the compression level). For instance, you
+can disable Zip compressed snapshots and set *gzip*(1) to run at level 6 by
+adding the following lines to your gitweb configuration file:
+
+ $known_snapshot_formats{'zip'}{'disabled'} = 1;
+ $known_snapshot_formats{'tgz'}{'compressor'} = ['gzip','-6'];
+
+ENVIRONMENT
+-----------
+The location of per-instance and system-wide configuration files can be
+overridden using the following environment variables:
+
+GITWEB_CONFIG::
+ Sets location of per-instance configuration file.
+GITWEB_CONFIG_SYSTEM::
+ Sets location of fallback system-wide configuration file.
+ This file is read only if per-instance one does not exist.
+GITWEB_CONFIG_COMMON::
+ Sets location of common system-wide configuration file.
+
+
+FILES
+-----
+gitweb_config.perl::
+ This is default name of per-instance configuration file. The
+ format of this file is described above.
+/etc/gitweb.conf::
+ This is default name of fallback system-wide configuration
+ file. This file is used only if per-instance configuration
+ variable is not found.
+/etc/gitweb-common.conf::
+ This is default name of common system-wide configuration
+ file.
+
+
+SEE ALSO
+--------
+linkgit:gitweb[1], linkgit:git-instaweb[1]
+
+'gitweb/README', 'gitweb/INSTALL'
+
+GIT
+---
+Part of the linkgit:git[1] suite
diff --git a/Documentation/gitweb.txt b/Documentation/gitweb.txt
new file mode 100644
index 0000000..605a085
--- /dev/null
+++ b/Documentation/gitweb.txt
@@ -0,0 +1,704 @@
+gitweb(1)
+=========
+
+NAME
+----
+gitweb - Git web interface (web frontend to Git repositories)
+
+SYNOPSIS
+--------
+To get started with gitweb, run linkgit:git-instaweb[1] from a git repository.
+This would configure and start your web server, and run web browser pointing to
+gitweb.
+
+
+DESCRIPTION
+-----------
+Gitweb provides a web interface to git repositories. It's features include:
+
+* Viewing multiple Git repositories with common root.
+* Browsing every revision of the repository.
+* Viewing the contents of files in the repository at any revision.
+* Viewing the revision log of branches, history of files and directories,
+ see what was changed when, by who.
+* Viewing the blame/annotation details of any file (if enabled).
+* Generating RSS and Atom feeds of commits, for any branch.
+ The feeds are auto-discoverable in modern web browsers.
+* Viewing everything that was changed in a revision, and step through
+ revisions one at a time, viewing the history of the repository.
+* Finding commits which commit messages matches given search term.
+
+See http://git.kernel.org/?p=git/git.git;a=tree;f=gitweb[] or
+http://repo.or.cz/w/git.git/tree/HEAD:/gitweb/[] for gitweb source code,
+browsed using gitweb itself.
+
+
+CONFIGURATION
+-------------
+Various aspects of gitweb's behavior can be controlled through the configuration
+file 'gitweb_config.perl' or '/etc/gitweb.conf'. See the linkgit:gitweb.conf[5]
+for details.
+
+Repositories
+~~~~~~~~~~~~
+Gitweb can show information from one or more Git repositories. These
+repositories have to be all on local filesystem, and have to share common
+repository root, i.e. be all under a single parent repository (but see also
+"Advanced web server setup" section, "Webserver configuration with multiple
+projects' root" subsection).
+
+-----------------------------------------------------------------------
+our $projectroot = '/path/to/parent/directory';
+-----------------------------------------------------------------------
+
+The default value for `$projectroot` is '/pub/git'. You can change it during
+building gitweb via `GITWEB_PROJECTROOT` build configuration variable.
+
+By default all git repositories under `$projectroot` are visible and available
+to gitweb. The list of projects is generated by default by scanning the
+`$projectroot` directory for git repositories (for object databases to be
+more exact; gitweb is not interested in a working area, and is best suited
+to showing "bare" repositories).
+
+The name of repository in gitweb is path to it's `$GIT_DIR` (it's object
+database) relative to `$projectroot`. Therefore the repository $repo can be
+found at "$projectroot/$repo".
+
+
+Projects list file format
+~~~~~~~~~~~~~~~~~~~~~~~~~
+Instead of having gitweb find repositories by scanning filesystem
+starting from $projectroot, you can provide a pre-generated list of
+visible projects by setting `$projects_list` to point to a plain text
+file with a list of projects (with some additional info).
+
+This file uses the following format:
+
+* One record (for project / repository) per line; does not support line
+continuation (newline escaping).
+
+* Leading and trailing whitespace are ignored.
+
+* Whitespace separated fields; any run of whitespace can be used as field
+separator (rules for Perl's "`split(" ", $line)`").
+
+* Fields use modified URI encoding, defined in RFC 3986, section 2.1
+(Percent-Encoding), or rather "Query string encoding" (see
+link:http://en.wikipedia.org/wiki/Query_string#URL_encoding[]), the difference
+being that SP (" ") can be encoded as "{plus}" (and therefore "{plus}" has to be
+also percent-encoded).
++
+Reserved characters are: "%" (used for encoding), "{plus}" (can be used to
+encode SPACE), all whitespace characters as defined in Perl, including SP,
+TAB and LF, (used to separate fields in a record).
+
+* Currently recognized fields are:
+<repository path>::
+ path to repository GIT_DIR, relative to `$projectroot`
+<repository owner>::
+ displayed as repository owner, preferably full name, or email,
+ or both
+
+You can generate the projects list index file using the project_index action
+(the 'TXT' link on projects list page) directly from gitweb; see also
+"Generating projects list using gitweb" section below.
+
+Example contents:
+-----------------------------------------------------------------------
+foo.git Joe+R+Hacker+<joe@example.com>
+foo/bar.git O+W+Ner+<owner@example.org>
+-----------------------------------------------------------------------
+
+
+By default this file controls only which projects are *visible* on projects
+list page (note that entries that do not point to correctly recognized git
+repositories won't be displayed by gitweb). Even if a project is not
+visible on projects list page, you can view it nevertheless by hand-crafting
+a gitweb URL. By setting `$strict_export` configuration variable (see
+linkgit:gitweb.conf[5]) to true value you can allow viewing only of
+repositories also shown on the overview page (i.e. only projects explicitly
+listed in projects list file will be accessible).
+
+
+Generating projects list using gitweb
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We assume that GITWEB_CONFIG has its default Makefile value, namely
+'gitweb_config.perl'. Put the following in 'gitweb_make_index.perl' file:
+----------------------------------------------------------------------------
+read_config_file("gitweb_config.perl");
+$projects_list = $projectroot;
+----------------------------------------------------------------------------
+
+Then create the following script to get list of project in the format
+suitable for GITWEB_LIST build configuration variable (or
+`$projects_list` variable in gitweb config):
+
+----------------------------------------------------------------------------
+#!/bin/sh
+
+export GITWEB_CONFIG="gitweb_make_index.perl"
+export GATEWAY_INTERFACE="CGI/1.1"
+export HTTP_ACCEPT="*/*"
+export REQUEST_METHOD="GET"
+export QUERY_STRING="a=project_index"
+
+perl -- /var/www/cgi-bin/gitweb.cgi
+----------------------------------------------------------------------------
+
+Run this script and save its output to a file. This file could then be used
+as projects list file, which means that you can set `$projects_list` to its
+filename.
+
+
+Controlling access to git repositories
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+By default all git repositories under `$projectroot` are visible and
+available to gitweb. You can however configure how gitweb controls access
+to repositories.
+
+* As described in "Projects list file format" section, you can control which
+projects are *visible* by selectively including repositories in projects
+list file, and setting `$projects_list` gitweb configuration variable to
+point to it. With `$strict_export` set, projects list file can be used to
+control which repositories are *available* as well.
+
+* You can configure gitweb to only list and allow viewing of the explicitly
+exported repositories, via `$export_ok` variable in gitweb config file; see
+linkgit:gitweb.conf[5] manpage. If it evaluates to true, gitweb shows
+repositories only if this file named by `$export_ok` exists in its object
+database (if directory has the magic file named `$export_ok`).
++
+For example linkgit:git-daemon[1] by default (unless `--export-all` option
+is used) allows pulling only for those repositories that have
+'git-daemon-export-ok' file. Adding
++
+--------------------------------------------------------------------------
+our $export_ok = "git-daemon-export-ok";
+--------------------------------------------------------------------------
++
+makes gitweb show and allow access only to those repositories that can be
+fetched from via `git://` protocol.
+
+* Finally, it is possible to specify an arbitrary perl subroutine that will
+be called for each repository to determine if it can be exported. The
+subroutine receives an absolute path to the project (repository) as its only
+parameter (i.e. "$projectroot/$project").
++
+For example, if you use mod_perl to run the script, and have dumb
+HTTP protocol authentication configured for your repositories, you
+can use the following hook to allow access only if the user is
+authorized to read the files:
++
+--------------------------------------------------------------------------
+$export_auth_hook = sub {
+ use Apache2::SubRequest ();
+ use Apache2::Const -compile => qw(HTTP_OK);
+ my $path = "$_[0]/HEAD";
+ my $r = Apache2::RequestUtil->request;
+ my $sub = $r->lookup_file($path);
+ return $sub->filename eq $path
+ && $sub->status == Apache2::Const::HTTP_OK;
+};
+--------------------------------------------------------------------------
+
+
+Per-repository gitweb configuration
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+You can configure individual repositories shown in gitweb by creating file
+in the 'GIT_DIR' of git repository, or by setting some repo configuration
+variable (in 'GIT_DIR/config', see linkgit:git-config[1]).
+
+You can use the following files in repository:
+
+README.html::
+ A html file (HTML fragment) which is included on the gitweb project
+ "summary" page inside `<div>` block element. You can use it for longer
+ description of a project, to provide links (for example to project's
+ homepage), etc. This is recognized only if XSS prevention is off
+ (`$prevent_xss` is false, see linkgit:gitweb.conf[5]); a way to include
+ a README safely when XSS prevention is on may be worked out in the
+ future.
+
+description (or `gitweb.description`)::
+ Short (shortened to `$projects_list_description_width` in the projects
+ list page, which is 25 characters by default; see
+ linkgit:gitweb.conf[5]) single line description of a project (of a
+ repository). Plain text file; HTML will be escaped. By default set to
++
+-------------------------------------------------------------------------------
+Unnamed repository; edit this file to name it for gitweb.
+-------------------------------------------------------------------------------
++
+from the template during repository creation, usually installed in
+'/usr/share/git-core/templates/'. You can use the `gitweb.description` repo
+configuration variable, but the file takes precedence.
+
+category (or `gitweb.category`)::
+ Singe line category of a project, used to group projects if
+ `$projects_list_group_categories` is enabled. By default (file and
+ configuration variable absent), uncategorized projects are put in the
+ `$project_list_default_category` category. You can use the
+ `gitweb.category` repo configuration variable, but the file takes
+ precedence.
++
+The configuration variables `$projects_list_group_categories` and
+`$project_list_default_category` are described in linkgit:gitweb.conf[5]
+
+cloneurl (or multiple-valued `gitweb.url`)::
+ File with repository URL (used for clone and fetch), one per line.
+ Displayed in the project summary page. You can use multiple-valued
+ `gitweb.url` repository configuration variable for that, but the file
+ takes precedence.
++
+This is per-repository enhancement / version of global prefix-based
+`@git_base_url_list` gitweb configuration variable (see
+linkgit:gitweb.conf[5]).
+
+gitweb.owner::
+ You can use the `gitweb.owner` repository configuration variable to set
+ repository's owner. It is displayed in the project list and summary
+ page.
++
+If it's not set, filesystem directory's owner is used (via GECOS field,
+i.e. real name field from *getpwuid*(3)) if `$projects_list` is unset
+(gitweb scans `$projectroot` for repositories); if `$projects_list`
+points to file with list of repositories, then project owner defaults to
+value from this file for given repository.
+
+various `gitweb.*` config variables (in config)::
+ Read description of `%feature` hash for detailed list, and descriptions.
+ See also "Configuring gitweb features" section in linkgit:gitweb.conf[5]
+
+
+ACTIONS, AND URLS
+-----------------
+Gitweb can use path_info (component) based URLs, or it can pass all necessary
+information via query parameters. The typical gitweb URLs are broken down in to
+five components:
+
+-----------------------------------------------------------------------
+.../gitweb.cgi/<repo>/<action>/<revision>:/<path>?<arguments>
+-----------------------------------------------------------------------
+
+repo::
+ The repository the action will be performed on.
++
+All actions except for those that list all available projects,
+in whatever form, require this parameter.
+
+action::
+ The action that will be run. Defaults to 'projects_list' if repo
+ is not set, and to 'summary' otherwise.
+
+revision::
+ Revision shown. Defaults to HEAD.
+
+path::
+ The path within the <repository> that the action is performed on,
+ for those actions that require it.
+
+arguments::
+ Any arguments that control the behaviour of the action.
+
+Some actions require or allow to specify two revisions, and sometimes even two
+pathnames. In most general form such path_info (component) based gitweb URL
+looks like this:
+
+-----------------------------------------------------------------------
+.../gitweb.cgi/<repo>/<action>/<revision_from>:/<path_from>..<revision_to>:/<path_to>?<arguments>
+-----------------------------------------------------------------------
+
+
+Each action is implemented as a subroutine, and must be present in %actions
+hash. Some actions are disabled by default, and must be turned on via feature
+mechanism. For example to enable 'blame' view add the following to gitweb
+configuration file:
+
+-----------------------------------------------------------------------
+$feature{'blame'}{'default'} = [1];
+-----------------------------------------------------------------------
+
+
+Actions:
+~~~~~~~~
+The standard actions are:
+
+project_list::
+ Lists the available Git repositories. This is the default command if no
+ repository is specified in the URL.
+
+summary::
+ Displays summary about given repository. This is the default command if
+ no action is specified in URL, and only repository is specified.
+
+heads::
+remotes::
+ Lists all local or all remote-tracking branches in given repository.
++
+The latter is not available by default, unless configured.
+
+tags::
+ List all tags (lightweight and annotated) in given repository.
+
+blob::
+tree::
+ Shows the files and directories in a given repository path, at given
+ revision. This is default command if no action is specified in the URL,
+ and path is given.
+
+blob_plain::
+ Returns the raw data for the file in given repository, at given path and
+ revision. Links to this action are marked 'raw'.
+
+blobdiff::
+ Shows the difference between two revisions of the same file.
+
+blame::
+blame_incremental::
+ Shows the blame (also called annotation) information for a file. On a
+ per line basis it shows the revision in which that line was last changed
+ and the user that committed the change. The incremental version (which
+ if configured is used automatically when JavaScript is enabled) uses
+ Ajax to incrementally add blame info to the contents of given file.
++
+This action is disabled by default for performance reasons.
+
+commit::
+commitdiff::
+ Shows information about a specific commit in a repository. The 'commit'
+ view shows information about commit in more detail, the 'commitdiff'
+ action shows changeset for given commit.
+
+patch::
+ Returns the commit in plain text mail format, suitable for applying with
+ linkgit:git-am[1].
+
+tag::
+ Display specific annotated tag (tag object).
+
+log::
+shortlog::
+ Shows log information (commit message or just commit subject) for a
+ given branch (starting from given revision).
++
+The 'shortlog' view is more compact; it shows one commit per line.
+
+history::
+ Shows history of the file or directory in a given repository path,
+ starting from given revision (defaults to HEAD, i.e. default branch).
++
+This view is similar to 'shortlog' view.
+
+rss::
+atom::
+ Generates an RSS (or Atom) feed of changes to repository.
+
+
+WEBSERVER CONFIGURATION
+-----------------------
+This section explains how to configure some common webservers to run gitweb. In
+all cases, `/path/to/gitweb` in the examples is the directory you ran installed
+gitweb in, and contains `gitweb_config.perl`.
+
+If you've configured a web server that isn't listed here for gitweb, please send
+in the instructions so they can be included in a future release.
+
+Apache as CGI
+~~~~~~~~~~~~~
+Apache must be configured to support CGI scripts in the directory in
+which gitweb is installed. Let's assume that it is '/var/www/cgi-bin'
+directory.
+
+-----------------------------------------------------------------------
+ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
+
+<Directory "/var/www/cgi-bin">
+ Options Indexes FollowSymlinks ExecCGI
+ AllowOverride None
+ Order allow,deny
+ Allow from all
+</Directory>
+-----------------------------------------------------------------------
+
+With that configuration the full path to browse repositories would be:
+
+ http://server/cgi-bin/gitweb.cgi
+
+Apache with mod_perl, via ModPerl::Registry
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+You can use mod_perl with gitweb. You must install Apache::Registry
+(for mod_perl 1.x) or ModPerl::Registry (for mod_perl 2.x) to enable
+this support.
+
+Assuming that gitweb is installed to '/var/www/perl', the following
+Apache configuration (for mod_perl 2.x) is suitable.
+
+-----------------------------------------------------------------------
+Alias /perl "/var/www/perl"
+
+<Directory "/var/www/perl">
+ SetHandler perl-script
+ PerlResponseHandler ModPerl::Registry
+ PerlOptions +ParseHeaders
+ Options Indexes FollowSymlinks +ExecCGI
+ AllowOverride None
+ Order allow,deny
+ Allow from all
+</Directory>
+-----------------------------------------------------------------------
+
+With that configuration the full path to browse repositories would be:
+
+ http://server/perl/gitweb.cgi
+
+Apache with FastCGI
+~~~~~~~~~~~~~~~~~~~
+Gitweb works with Apache and FastCGI. First you need to rename, copy
+or symlink gitweb.cgi to gitweb.fcgi. Let's assume that gitweb is
+installed in '/usr/share/gitweb' directory. The following Apache
+configuration is suitable (UNTESTED!)
+
+-----------------------------------------------------------------------
+FastCgiServer /usr/share/gitweb/gitweb.cgi
+ScriptAlias /gitweb /usr/share/gitweb/gitweb.cgi
+
+Alias /gitweb/static /usr/share/gitweb/static
+<Directory /usr/share/gitweb/static>
+ SetHandler default-handler
+</Directory>
+-----------------------------------------------------------------------
+
+With that configuration the full path to browse repositories would be:
+
+ http://server/gitweb
+
+
+ADVANCED WEB SERVER SETUP
+-------------------------
+All of those examples use request rewriting, and need `mod_rewrite`
+(or equivalent; examples below are written for Apache).
+
+Single URL for gitweb and for fetching
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+If you want to have one URL for both gitweb and your `http://`
+repositories, you can configure Apache like this:
+
+-----------------------------------------------------------------------
+<VirtualHost *:80>
+ ServerName git.example.org
+ DocumentRoot /pub/git
+ SetEnv GITWEB_CONFIG /etc/gitweb.conf
+
+ # turning on mod rewrite
+ RewriteEngine on
+
+ # make the front page an internal rewrite to the gitweb script
+ RewriteRule ^/$ /cgi-bin/gitweb.cgi
+
+ # make access for "dumb clients" work
+ RewriteRule ^/(.*\.git/(?!/?(HEAD|info|objects|refs)).*)?$ \
+ /cgi-bin/gitweb.cgi%{REQUEST_URI} [L,PT]
+</VirtualHost>
+-----------------------------------------------------------------------
+
+The above configuration expects your public repositories to live under
+'/pub/git' and will serve them as `http://git.domain.org/dir-under-pub-git`,
+both as cloneable GIT URL and as browseable gitweb interface. If you then
+start your linkgit:git-daemon[1] with `--base-path=/pub/git --export-all`
+then you can even use the `git://` URL with exactly the same path.
+
+Setting the environment variable `GITWEB_CONFIG` will tell gitweb to use the
+named file (i.e. in this example '/etc/gitweb.conf') as a configuration for
+gitweb. You don't really need it in above example; it is required only if
+your configuration file is in different place than built-in (during
+compiling gitweb) 'gitweb_config.perl' or '/etc/gitweb.conf'. See
+linkgit:gitweb.conf[5] for details, especially information about precedence
+rules.
+
+If you use the rewrite rules from the example you *might* also need
+something like the following in your gitweb configuration file
+('/etc/gitweb.conf' following example):
+----------------------------------------------------------------------------
+@stylesheets = ("/some/absolute/path/gitweb.css");
+$my_uri = "/";
+$home_link = "/";
+$per_request_config = 1;
+----------------------------------------------------------------------------
+Nowadays though gitweb should create HTML base tag when needed (to set base
+URI for relative links), so it should work automatically.
+
+
+Webserver configuration with multiple projects' root
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+If you want to use gitweb with several project roots you can edit your
+Apache virtual host and gitweb configuration files in the following way.
+
+The virtual host configuration (in Apache configuration file) should look
+like this:
+--------------------------------------------------------------------------
+<VirtualHost *:80>
+ ServerName git.example.org
+ DocumentRoot /pub/git
+ SetEnv GITWEB_CONFIG /etc/gitweb.conf
+
+ # turning on mod rewrite
+ RewriteEngine on
+
+ # make the front page an internal rewrite to the gitweb script
+ RewriteRule ^/$ /cgi-bin/gitweb.cgi [QSA,L,PT]
+
+ # look for a public_git folder in unix users' home
+ # http://git.example.org/~<user>/
+ RewriteRule ^/\~([^\/]+)(/|/gitweb.cgi)?$ /cgi-bin/gitweb.cgi \
+ [QSA,E=GITWEB_PROJECTROOT:/home/$1/public_git/,L,PT]
+
+ # http://git.example.org/+<user>/
+ #RewriteRule ^/\+([^\/]+)(/|/gitweb.cgi)?$ /cgi-bin/gitweb.cgi \
+ [QSA,E=GITWEB_PROJECTROOT:/home/$1/public_git/,L,PT]
+
+ # http://git.example.org/user/<user>/
+ #RewriteRule ^/user/([^\/]+)/(gitweb.cgi)?$ /cgi-bin/gitweb.cgi \
+ [QSA,E=GITWEB_PROJECTROOT:/home/$1/public_git/,L,PT]
+
+ # defined list of project roots
+ RewriteRule ^/scm(/|/gitweb.cgi)?$ /cgi-bin/gitweb.cgi \
+ [QSA,E=GITWEB_PROJECTROOT:/pub/scm/,L,PT]
+ RewriteRule ^/var(/|/gitweb.cgi)?$ /cgi-bin/gitweb.cgi \
+ [QSA,E=GITWEB_PROJECTROOT:/var/git/,L,PT]
+
+ # make access for "dumb clients" work
+ RewriteRule ^/(.*\.git/(?!/?(HEAD|info|objects|refs)).*)?$ \
+ /cgi-bin/gitweb.cgi%{REQUEST_URI} [L,PT]
+</VirtualHost>
+--------------------------------------------------------------------------
+
+Here actual project root is passed to gitweb via `GITWEB_PROJECT_ROOT`
+environment variable from a web server, so you need to put the following
+line in gitweb configuration file ('/etc/gitweb.conf' in above example):
+--------------------------------------------------------------------------
+$projectroot = $ENV{'GITWEB_PROJECTROOT'} || "/pub/git";
+--------------------------------------------------------------------------
+*Note* that this requires to be set for each request, so either
+`$per_request_config` must be false, or the above must be put in code
+referenced by `$per_request_config`;
+
+These configurations enable two things. First, each unix user (`<user>`) of
+the server will be able to browse through gitweb git repositories found in
+'~/public_git/' with the following url:
+
+ http://git.example.org/~<user>/
+
+If you do not want this feature on your server just remove the second
+rewrite rule.
+
+If you already use `mod_userdir` in your virtual host or you don't want to
+use the \'~' as first character, just comment or remove the second rewrite
+rule, and uncomment one of the following according to what you want.
+
+Second, repositories found in '/pub/scm/' and '/var/git/' will be accessible
+through `http://git.example.org/scm/` and `http://git.example.org/var/`.
+You can add as many project roots as you want by adding rewrite rules like
+the third and the fourth.
+
+
+PATH_INFO usage
+~~~~~~~~~~~~~~~
+If you enable PATH_INFO usage in gitweb by putting
+----------------------------------------------------------------------------
+$feature{'pathinfo'}{'default'} = [1];
+----------------------------------------------------------------------------
+in your gitweb configuration file, it is possible to set up your server so
+that it consumes and produces URLs in the form
+
+ http://git.example.com/project.git/shortlog/sometag
+
+i.e. without 'gitweb.cgi' part, by using a configuration such as the
+following. This configuration assumes that '/var/www/gitweb' is the
+DocumentRoot of your webserver, contains the gitweb.cgi script and
+complementary static files (stylesheet, favicon, JavaScript):
+
+----------------------------------------------------------------------------
+<VirtualHost *:80>
+ ServerAlias git.example.com
+
+ DocumentRoot /var/www/gitweb
+
+ <Directory /var/www/gitweb>
+ Options ExecCGI
+ AddHandler cgi-script cgi
+
+ DirectoryIndex gitweb.cgi
+
+ RewriteEngine On
+ RewriteCond %{REQUEST_FILENAME} !-f
+ RewriteCond %{REQUEST_FILENAME} !-d
+ RewriteRule ^.* /gitweb.cgi/$0 [L,PT]
+ </Directory>
+</VirtualHost>
+----------------------------------------------------------------------------
+The rewrite rule guarantees that existing static files will be properly
+served, whereas any other URL will be passed to gitweb as PATH_INFO
+parameter.
+
+*Notice* that in this case you don't need special settings for
+`@stylesheets`, `$my_uri` and `$home_link`, but you lose "dumb client"
+access to your project .git dirs (described in "Single URL for gitweb and
+for fetching" section). A possible workaround for the latter is the
+following: in your project root dir (e.g. '/pub/git') have the projects
+named *without* a .git extension (e.g. '/pub/git/project' instead of
+'/pub/git/project.git') and configure Apache as follows:
+----------------------------------------------------------------------------
+<VirtualHost *:80>
+ ServerAlias git.example.com
+
+ DocumentRoot /var/www/gitweb
+
+ AliasMatch ^(/.*?)(\.git)(/.*)?$ /pub/git$1$3
+ <Directory /var/www/gitweb>
+ Options ExecCGI
+ AddHandler cgi-script cgi
+
+ DirectoryIndex gitweb.cgi
+
+ RewriteEngine On
+ RewriteCond %{REQUEST_FILENAME} !-f
+ RewriteCond %{REQUEST_FILENAME} !-d
+ RewriteRule ^.* /gitweb.cgi/$0 [L,PT]
+ </Directory>
+</VirtualHost>
+----------------------------------------------------------------------------
+
+The additional AliasMatch makes it so that
+
+ http://git.example.com/project.git
+
+will give raw access to the project's git dir (so that the project can be
+cloned), while
+
+ http://git.example.com/project
+
+will provide human-friendly gitweb access.
+
+This solution is not 100% bulletproof, in the sense that if some project has
+a named ref (branch, tag) starting with 'git/', then paths such as
+
+ http://git.example.com/project/command/abranch..git/abranch
+
+will fail with a 404 error.
+
+
+BUGS
+----
+Please report any bugs or feature requests to git@vger.kernel.org,
+putting "gitweb" in the subject of email.
+
+SEE ALSO
+--------
+linkgit:gitweb.conf[5], linkgit:git-instaweb[1]
+
+'gitweb/README', 'gitweb/INSTALL'
+
+GIT
+---
+Part of the linkgit:git[1] suite
diff --git a/Documentation/gitworkflows.txt b/Documentation/gitworkflows.txt
index 1ef55ff..5e4f362 100644
--- a/Documentation/gitworkflows.txt
+++ b/Documentation/gitworkflows.txt
@@ -7,6 +7,7 @@ gitworkflows - An overview of recommended workflows with git
SYNOPSIS
--------
+[verse]
git *
diff --git a/Documentation/glossary-content.txt b/Documentation/glossary-content.txt
index 8f62d1a..3595b58 100644
--- a/Documentation/glossary-content.txt
+++ b/Documentation/glossary-content.txt
@@ -161,8 +161,8 @@ to point at the new commit.
[[def_head]]head::
A <<def_ref,named reference>> to the <<def_commit,commit>> at the tip of a
- <<def_branch,branch>>. Heads are stored in
- `$GIT_DIR/refs/heads/`, except when using packed refs. (See
+ <<def_branch,branch>>. Heads are stored in a file in
+ `$GIT_DIR/refs/heads/` directory, except when using packed refs. (See
linkgit:git-pack-refs[1].)
[[def_HEAD]]HEAD::
@@ -170,8 +170,8 @@ to point at the new commit.
working tree>> is normally derived from the state of the tree
referred to by HEAD. HEAD is a reference to one of the
<<def_head,heads>> in your repository, except when using a
- <<def_detached_HEAD,detached HEAD>>, in which case it may
- reference an arbitrary commit.
+ <<def_detached_HEAD,detached HEAD>>, in which case it directly
+ references an arbitrary commit.
[[def_head_ref]]head ref::
A synonym for <<def_head,head>>.
@@ -382,8 +382,9 @@ should not be combined with other pathspec.
[[def_ref]]ref::
A 40-byte hex representation of a <<def_SHA1,SHA1>> or a name that
- denotes a particular <<def_object,object>>. These may be stored in
- `$GIT_DIR/refs/`.
+ denotes a particular <<def_object,object>>. They may be stored in
+ a file under `$GIT_DIR/refs/` directory, or
+ in the `$GIT_DIR/packed-refs` file.
[[def_reflog]]reflog::
A reflog shows the local "history" of a ref. In other words,
@@ -459,14 +460,14 @@ should not be combined with other pathspec.
command.
[[def_tag]]tag::
- A <<def_ref,ref>> pointing to a <<def_tag_object,tag>> or
- <<def_commit_object,commit object>>. In contrast to a <<def_head,head>>,
- a tag is not changed by a <<def_commit,commit>>. Tags (not
- <<def_tag_object,tag objects>>) are stored in `$GIT_DIR/refs/tags/`. A
- git tag has nothing to do with a Lisp tag (which would be
- called an <<def_object_type,object type>> in git's context). A
- tag is most typically used to mark a particular point in the
- commit ancestry <<def_chain,chain>>.
+ A <<def_ref,ref>> under `refs/tags/` namespace that points to an
+ object of an arbitrary type (typically a tag points to either a
+ <<def_tag_object,tag>> or a <<def_commit_object,commit object>>).
+ In contrast to a <<def_head,head>>, a tag is not updated by
+ the `commit` command. A git tag has nothing to do with a Lisp
+ tag (which would be called an <<def_object_type,object type>>
+ in git's context). A tag is most typically used to mark a particular
+ point in the commit ancestry <<def_chain,chain>>.
[[def_tag_object]]tag object::
An <<def_object,object>> containing a <<def_ref,ref>> pointing to
diff --git a/Documentation/howto/maintain-git.txt b/Documentation/howto/maintain-git.txt
index d527b30..8823a37 100644
--- a/Documentation/howto/maintain-git.txt
+++ b/Documentation/howto/maintain-git.txt
@@ -176,7 +176,7 @@ by doing the following:
- Update "What's cooking" message to review the updates to
existing topics, newly added topics and graduated topics.
- This step is helped with Meta/UWC script (where Meta/ contains
+ This step is helped with Meta/cook script (where Meta/ contains
a checkout of the 'todo' branch).
- Merge topics to 'next'. For each branch whose tip is not
@@ -197,10 +197,9 @@ by doing the following:
- Nothing is next-worthy; do not do anything.
- - Rebase topics that do not have any commit in next yet. This
- step is optional but sometimes is worth doing when an old
- series that is not in next can take advantage of low-level
- framework change that is merged to 'master' already.
+ - [** OBSOLETE **] Optionally rebase topics that do not have any commit
+ in next yet, when they can take advantage of low-level framework
+ change that is merged to 'master' already.
$ git rebase master ai/topic
@@ -209,7 +208,7 @@ by doing the following:
pre-rebase hook to make sure that topics that are already in
'next' are not rebased beyond the merged commit.
- - Rebuild "pu" to merge the tips of topics not in 'next'.
+ - [** OBSOLETE **] Rebuild "pu" to merge the tips of topics not in 'next'.
$ git checkout pu
$ git reset --hard next
@@ -241,7 +240,7 @@ by doing the following:
- Fetch html and man branches back from k.org, and push four
integration branches and the two documentation branches to
- repo.or.cz
+ repo.or.cz and other mirrors.
Some observations to be made.
diff --git a/Documentation/install-doc-quick.sh b/Documentation/install-doc-quick.sh
index 35f4408..327f69b 100755
--- a/Documentation/install-doc-quick.sh
+++ b/Documentation/install-doc-quick.sh
@@ -1,31 +1,39 @@
#!/bin/sh
-# This requires a branch named in $head
-# (usually 'man' or 'html', provided by the git.git repository)
-set -e
-head="$1"
-mandir="$2"
-SUBDIRECTORY_OK=t
-USAGE='<refname> <target directory>'
-. "$(git --exec-path)"/git-sh-setup
-cd_to_toplevel
+# This requires git-manpages and/or git-htmldocs repositories
-test -z "$mandir" && usage
-if ! git rev-parse --verify "$head^0" >/dev/null; then
- echo >&2 "head: $head does not exist in the current repository"
- usage
+repository=${1?repository}
+destdir=${2?destination}
+
+head=master GIT_DIR=
+for d in "$repository/.git" "$repository"
+do
+ if GIT_DIR="$d" git rev-parse refs/heads/master >/dev/null 2>&1
+ then
+ GIT_DIR="$d"
+ export GIT_DIR
+ break
+ fi
+done
+
+if test -z "$GIT_DIR"
+then
+ echo >&2 "Neither $repository nor $repository/.git is a repository"
+ exit 1
fi
-GIT_INDEX_FILE=`pwd`/.quick-doc.index
-export GIT_INDEX_FILE
+GIT_WORK_TREE=$(pwd)
+GIT_INDEX_FILE=$(pwd)/.quick-doc.$$
+export GIT_INDEX_FILE GIT_WORK_TREE
rm -f "$GIT_INDEX_FILE"
trap 'rm -f "$GIT_INDEX_FILE"' 0
git read-tree $head
-git checkout-index -a -f --prefix="$mandir"/
+git checkout-index -a -f --prefix="$destdir"/
-if test -n "$GZ"; then
+if test -n "$GZ"
+then
git ls-tree -r --name-only $head |
- xargs printf "$mandir/%s\n" |
+ xargs printf "$destdir/%s\n" |
xargs gzip -f
fi
rm -f "$GIT_INDEX_FILE"
diff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt
index b613d4e..1a5c12e 100644
--- a/Documentation/merge-options.txt
+++ b/Documentation/merge-options.txt
@@ -7,6 +7,11 @@ With --no-commit perform the merge but pretend the merge
failed and do not autocommit, to give the user a chance to
inspect and further tweak the merge result before committing.
+--edit::
+-e::
+ Invoke editor before committing successful merge to further
+ edit the default merge message.
+
--ff::
--no-ff::
Do not generate a merge commit if the merge resolved as
diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt
index 7e7ba68..39e6207 100644
--- a/Documentation/rev-list-options.txt
+++ b/Documentation/rev-list-options.txt
@@ -272,7 +272,7 @@ Default mode::
--full-history::
- As the default mode but does not prune some history.
+ Same as the default mode, but does not prune some history.
--dense::
@@ -313,7 +313,7 @@ that you are filtering for a file `foo` in this commit graph:
\ / / / /
`-------------'
-----------------------------------------------------------------------
-The horizontal line of history A--P is taken to be the first parent of
+The horizontal line of history A---P is taken to be the first parent of
each merge. The commits are:
* `I` is the initial commit, in which `foo` exists with contents
diff --git a/Documentation/sequencer.txt b/Documentation/sequencer.txt
new file mode 100644
index 0000000..5747f44
--- /dev/null
+++ b/Documentation/sequencer.txt
@@ -0,0 +1,12 @@
+--continue::
+ Continue the operation in progress using the information in
+ '.git/sequencer'. Can be used to continue after resolving
+ conflicts in a failed cherry-pick or revert.
+
+--quit::
+ Forget about the current operation in progress. Can be used
+ to clear the sequencer state after a failed cherry-pick or
+ revert.
+
+--abort::
+ Cancel the operation and return to the pre-sequence state.
diff --git a/Documentation/technical/api-argv-array.txt b/Documentation/technical/api-argv-array.txt
new file mode 100644
index 0000000..49b3d52
--- /dev/null
+++ b/Documentation/technical/api-argv-array.txt
@@ -0,0 +1,46 @@
+argv-array API
+==============
+
+The argv-array API allows one to dynamically build and store
+NULL-terminated lists. An argv-array maintains the invariant that the
+`argv` member always points to a non-NULL array, and that the array is
+always NULL-terminated at the element pointed to by `argv[argc]`. This
+makes the result suitable for passing to functions expecting to receive
+argv from main(), or the link:api-run-command.html[run-command API].
+
+The link:api-string-list.html[string-list API] is similar, but cannot be
+used for these purposes; instead of storing a straight string pointer,
+it contains an item structure with a `util` field that is not compatible
+with the traditional argv interface.
+
+Each `argv_array` manages its own memory. Any strings pushed into the
+array are duplicated, and all memory is freed by argv_array_clear().
+
+Data Structures
+---------------
+
+`struct argv_array`::
+
+ A single array. This should be initialized by assignment from
+ `ARGV_ARRAY_INIT`, or by calling `argv_array_init`. The `argv`
+ member contains the actual array; the `argc` member contains the
+ number of elements in the array, not including the terminating
+ NULL.
+
+Functions
+---------
+
+`argv_array_init`::
+ Initialize an array. This is no different than assigning from
+ `ARGV_ARRAY_INIT`.
+
+`argv_array_push`::
+ Push a copy of a string onto the end of the array.
+
+`argv_array_pushf`::
+ Format a string and push it onto the end of the array. This is a
+ convenience wrapper combining `strbuf_addf` and `argv_array_push`.
+
+`argv_array_clear`::
+ Free all memory associated with the array and return it to the
+ initial, empty state.
diff --git a/Documentation/technical/api-builtin.txt b/Documentation/technical/api-builtin.txt
index 5cb2b05..b0cafe8 100644
--- a/Documentation/technical/api-builtin.txt
+++ b/Documentation/technical/api-builtin.txt
@@ -49,6 +49,8 @@ Additionally, if `foo` is a new command, there are 3 more things to do:
. Add an entry for `git-foo` to `command-list.txt`.
+. Add an entry for `/git-foo` to `.gitignore`.
+
How a built-in is called
------------------------
diff --git a/Documentation/technical/api-gitattributes.txt b/Documentation/technical/api-gitattributes.txt
index 9d97eaa..ce363b6 100644
--- a/Documentation/technical/api-gitattributes.txt
+++ b/Documentation/technical/api-gitattributes.txt
@@ -11,27 +11,15 @@ Data Structure
`struct git_attr`::
An attribute is an opaque object that is identified by its name.
- Pass the name and its length to `git_attr()` function to obtain
- the object of this type. The internal representation of this
- structure is of no interest to the calling programs.
+ Pass the name to `git_attr()` function to obtain the object of
+ this type. The internal representation of this structure is
+ of no interest to the calling programs. The name of the
+ attribute can be retrieved by calling `git_attr_name()`.
`struct git_attr_check`::
This structure represents a set of attributes to check in a call
- to `git_checkattr()` function, and receives the results.
-
-
-Calling Sequence
-----------------
-
-* Prepare an array of `struct git_attr_check` to define the list of
- attributes you would want to check. To populate this array, you would
- need to define necessary attributes by calling `git_attr()` function.
-
-* Call git_checkattr() to check the attributes for the path.
-
-* Inspect `git_attr_check` structure to see how each of the attribute in
- the array is defined for the path.
+ to `git_check_attr()` function, and receives the results.
Attribute Values
@@ -57,6 +45,19 @@ If none of the above returns true, `.value` member points at a string
value of the attribute for the path.
+Querying Specific Attributes
+----------------------------
+
+* Prepare an array of `struct git_attr_check` to define the list of
+ attributes you would want to check. To populate this array, you would
+ need to define necessary attributes by calling `git_attr()` function.
+
+* Call `git_check_attr()` to check the attributes for the path.
+
+* Inspect `git_attr_check` structure to see how each of the attribute in
+ the array is defined for the path.
+
+
Example
-------
@@ -72,18 +73,18 @@ static void setup_check(void)
{
if (check[0].attr)
return; /* already done */
- check[0].attr = git_attr("crlf", 4);
- check[1].attr = git_attr("ident", 5);
+ check[0].attr = git_attr("crlf");
+ check[1].attr = git_attr("ident");
}
------------
-. Call `git_checkattr()` with the prepared array of `struct git_attr_check`:
+. Call `git_check_attr()` with the prepared array of `struct git_attr_check`:
------------
const char *path;
setup_check();
- git_checkattr(path, ARRAY_SIZE(check), check);
+ git_check_attr(path, ARRAY_SIZE(check), check);
------------
. Act on `.value` member of the result, left in `check[]`:
@@ -108,4 +109,20 @@ static void setup_check(void)
}
------------
-(JC)
+
+Querying All Attributes
+-----------------------
+
+To get the values of all attributes associated with a file:
+
+* Call `git_all_attrs()`, which returns an array of `git_attr_check`
+ structures.
+
+* Iterate over the `git_attr_check` array to examine the attribute
+ names and values. The name of the attribute described by a
+ `git_attr_check` object can be retrieved via
+ `git_attr_name(check[i].attr)`. (Please note that no items will be
+ returned for unset attributes, so `ATTR_UNSET()` will return false
+ for all returned `git_array_check` objects.)
+
+* Free the `git_array_check` array.
diff --git a/Documentation/technical/api-parse-options.txt b/Documentation/technical/api-parse-options.txt
index f6a4a36..4b92514 100644
--- a/Documentation/technical/api-parse-options.txt
+++ b/Documentation/technical/api-parse-options.txt
@@ -135,9 +135,14 @@ There are some macros to easily define options:
describes the group or an empty string.
Start the description with an upper-case letter.
-`OPT_BOOLEAN(short, long, &int_var, description)`::
- Introduce a boolean option.
- `int_var` is incremented on each use.
+`OPT_BOOL(short, long, &int_var, description)`::
+ Introduce a boolean option. `int_var` is set to one with
+ `--option` and set to zero with `--no-option`.
+
+`OPT_COUNTUP(short, long, &int_var, description)`::
+ Introduce a count-up option.
+ `int_var` is incremented on each use of `--option`, and
+ reset to zero with `--no-option`.
`OPT_BIT(short, long, &int_var, description, mask)`::
Introduce a boolean option.
@@ -148,8 +153,9 @@ There are some macros to easily define options:
If used, `int_var` is bitwise-anded with the inverted `mask`.
`OPT_SET_INT(short, long, &int_var, description, integer)`::
- Introduce a boolean option.
- If used, set `int_var` to `integer`.
+ Introduce an integer option.
+ `int_var` is set to `integer` with `--option`, and
+ reset to zero with `--no-option`.
`OPT_SET_PTR(short, long, &ptr_var, description, ptr)`::
Introduce a boolean option.
@@ -198,6 +204,11 @@ There are some macros to easily define options:
"auto", set `int_var` to 1 if stdout is a tty or a pager,
0 otherwise.
+`OPT_NOOP_NOARG(short, long)`::
+ Introduce an option that has no effect and takes no arguments.
+ Use it to hide deprecated options that are still to be recognized
+ and ignored silently.
+
The last element of the array must be `OPT_END()`.
diff --git a/Documentation/technical/api-ref-iteration.txt b/Documentation/technical/api-ref-iteration.txt
new file mode 100644
index 0000000..dbbea95
--- /dev/null
+++ b/Documentation/technical/api-ref-iteration.txt
@@ -0,0 +1,81 @@
+ref iteration API
+=================
+
+
+Iteration of refs is done by using an iterate function which will call a
+callback function for every ref. The callback function has this
+signature:
+
+ int handle_one_ref(const char *refname, const unsigned char *sha1,
+ int flags, void *cb_data);
+
+There are different kinds of iterate functions which all take a
+callback of this type. The callback is then called for each found ref
+until the callback returns nonzero. The returned value is then also
+returned by the iterate function.
+
+Iteration functions
+-------------------
+
+* `head_ref()` just iterates the head ref.
+
+* `for_each_ref()` iterates all refs.
+
+* `for_each_ref_in()` iterates all refs which have a defined prefix and
+ strips that prefix from the passed variable refname.
+
+* `for_each_tag_ref()`, `for_each_branch_ref()`, `for_each_remote_ref()`,
+ `for_each_replace_ref()` iterate refs from the respective area.
+
+* `for_each_glob_ref()` iterates all refs that match the specified glob
+ pattern.
+
+* `for_each_glob_ref_in()` the previous and `for_each_ref_in()` combined.
+
+* `head_ref_submodule()`, `for_each_ref_submodule()`,
+ `for_each_ref_in_submodule()`, `for_each_tag_ref_submodule()`,
+ `for_each_branch_ref_submodule()`, `for_each_remote_ref_submodule()`
+ do the same as the functions descibed above but for a specified
+ submodule.
+
+* `for_each_rawref()` can be used to learn about broken ref and symref.
+
+* `for_each_reflog()` iterates each reflog file.
+
+Submodules
+----------
+
+If you want to iterate the refs of a submodule you first need to add the
+submodules object database. You can do this by a code-snippet like
+this:
+
+ const char *path = "path/to/submodule"
+ if (!add_submodule_odb(path))
+ die("Error submodule '%s' not populated.", path);
+
+`add_submodule_odb()` will return an non-zero value on success. If you
+do not do this you will get an error for each ref that it does not point
+to a valid object.
+
+Note: As a side-effect of this you can not safely assume that all
+objects you lookup are available in superproject. All submodule objects
+will be available the same way as the superprojects objects.
+
+Example:
+--------
+
+----
+static int handle_remote_ref(const char *refname,
+ const unsigned char *sha1, int flags, void *cb_data)
+{
+ struct strbuf *output = cb_data;
+ strbuf_addf(output, "%s\n", refname);
+ return 0;
+}
+
+...
+
+ struct strbuf output = STRBUF_INIT;
+ for_each_remote_ref(handle_remote_ref, &output);
+ printf("%s", output.buf);
+----
diff --git a/Documentation/technical/api-sha1-array.txt b/Documentation/technical/api-sha1-array.txt
new file mode 100644
index 0000000..4a4bae8
--- /dev/null
+++ b/Documentation/technical/api-sha1-array.txt
@@ -0,0 +1,79 @@
+sha1-array API
+==============
+
+The sha1-array API provides storage and manipulation of sets of SHA1
+identifiers. The emphasis is on storage and processing efficiency,
+making them suitable for large lists. Note that the ordering of items is
+not preserved over some operations.
+
+Data Structures
+---------------
+
+`struct sha1_array`::
+
+ A single array of SHA1 hashes. This should be initialized by
+ assignment from `SHA1_ARRAY_INIT`. The `sha1` member contains
+ the actual data. The `nr` member contains the number of items in
+ the set. The `alloc` and `sorted` members are used internally,
+ and should not be needed by API callers.
+
+Functions
+---------
+
+`sha1_array_append`::
+ Add an item to the set. The sha1 will be placed at the end of
+ the array (but note that some operations below may lose this
+ ordering).
+
+`sha1_array_sort`::
+ Sort the elements in the array.
+
+`sha1_array_lookup`::
+ Perform a binary search of the array for a specific sha1.
+ If found, returns the offset (in number of elements) of the
+ sha1. If not found, returns a negative integer. If the array is
+ not sorted, this function has the side effect of sorting it.
+
+`sha1_array_clear`::
+ Free all memory associated with the array and return it to the
+ initial, empty state.
+
+`sha1_array_for_each_unique`::
+ Efficiently iterate over each unique element of the list,
+ executing the callback function for each one. If the array is
+ not sorted, this function has the side effect of sorting it.
+
+Examples
+--------
+
+-----------------------------------------
+void print_callback(const unsigned char sha1[20],
+ void *data)
+{
+ printf("%s\n", sha1_to_hex(sha1));
+}
+
+void some_func(void)
+{
+ struct sha1_array hashes = SHA1_ARRAY_INIT;
+ unsigned char sha1[20];
+
+ /* Read objects into our set */
+ while (read_object_from_stdin(sha1))
+ sha1_array_append(&hashes, sha1);
+
+ /* Check if some objects are in our set */
+ while (read_object_from_stdin(sha1)) {
+ if (sha1_array_lookup(&hashes, sha1) >= 0)
+ printf("it's in there!\n");
+
+ /*
+ * Print the unique set of objects. We could also have
+ * avoided adding duplicate objects in the first place,
+ * but we would end up re-sorting the array repeatedly.
+ * Instead, this will sort once and then skip duplicates
+ * in linear time.
+ */
+ sha1_array_for_each_unique(&hashes, print_callback, NULL);
+}
+-----------------------------------------
diff --git a/Documentation/technical/api-string-list.txt b/Documentation/technical/api-string-list.txt
index 3f575bd..ce24eb9 100644
--- a/Documentation/technical/api-string-list.txt
+++ b/Documentation/technical/api-string-list.txt
@@ -29,6 +29,9 @@ member (you need this if you add things later) and you should set the
. Can sort an unsorted list using `sort_string_list`.
+. Can remove individual items of an unsorted list using
+ `unsorted_string_list_delete_item`.
+
. Finally it should free the list using `string_list_clear`.
Example:
@@ -112,6 +115,13 @@ write `string_list_insert(...)->util = ...;`.
The above two functions need to look through all items, as opposed to their
counterpart for sorted lists, which performs a binary search.
+`unsorted_string_list_delete_item`::
+
+ Remove an item from a string_list. The `string` pointer of the items
+ will be freed in case the `strdup_strings` member of the string_list
+ is set. The third parameter controls if the `util` pointer of the
+ items should be freed or not.
+
Data structures
---------------
diff --git a/Documentation/technical/index-format.txt b/Documentation/technical/index-format.txt
index 7b233ca..8930b3f 100644
--- a/Documentation/technical/index-format.txt
+++ b/Documentation/technical/index-format.txt
@@ -147,8 +147,9 @@ GIT index format
- 160-bit object name for the object that would result from writing
this span of index as a tree.
- An entry can be in an invalidated state and is represented by having -1
- in the entry_count field.
+ An entry can be in an invalidated state and is represented by having
+ -1 in the entry_count field. In this case, there is no object name
+ and the next entry starts immediately after the newline.
The entries are written out in the top-down, depth-first order. The
first entry represents the root level of the repository, followed by the
diff --git a/Documentation/technical/pack-protocol.txt b/Documentation/technical/pack-protocol.txt
index 369f91d..546980c 100644
--- a/Documentation/technical/pack-protocol.txt
+++ b/Documentation/technical/pack-protocol.txt
@@ -60,6 +60,13 @@ process on the server side over the Git protocol is this:
"0039git-upload-pack /schacon/gitbook.git\0host=example.com\0" |
nc -v example.com 9418
+If the server refuses the request for some reasons, it could abort
+gracefully with an error message.
+
+----
+ error-line = PKT-LINE("ERR" SP explanation-text)
+----
+
SSH Transport
-------------
@@ -179,34 +186,36 @@ and descriptions.
Packfile Negotiation
--------------------
-After reference and capabilities discovery, the client can decide
-to terminate the connection by sending a flush-pkt, telling the
-server it can now gracefully terminate (as happens with the ls-remote
-command) or it can enter the negotiation phase, where the client and
-server determine what the minimal packfile necessary for transport is.
-
-Once the client has the initial list of references that the server
-has, as well as the list of capabilities, it will begin telling the
-server what objects it wants and what objects it has, so the server
-can make a packfile that only contains the objects that the client needs.
-The client will also send a list of the capabilities it wants to be in
-effect, out of what the server said it could do with the first 'want' line.
+After reference and capabilities discovery, the client can decide to
+terminate the connection by sending a flush-pkt, telling the server it can
+now gracefully terminate, and disconnect, when it does not need any pack
+data. This can happen with the ls-remote command, and also can happen when
+the client already is up-to-date.
+
+Otherwise, it enters the negotiation phase, where the client and
+server determine what the minimal packfile necessary for transport is,
+by telling the server what objects it wants, its shallow objects
+(if any), and the maximum commit depth it wants (if any). The client
+will also send a list of the capabilities it wants to be in effect,
+out of what the server said it could do with the first 'want' line.
----
upload-request = want-list
- have-list
- compute-end
+ *shallow-line
+ *1depth-request
+ flush-pkt
want-list = first-want
*additional-want
- flush-pkt
+
+ shallow-line = PKT_LINE("shallow" SP obj-id)
+
+ depth-request = PKT_LINE("deepen" SP depth)
first-want = PKT-LINE("want" SP obj-id SP capability-list LF)
additional-want = PKT-LINE("want" SP obj-id LF)
- have-list = *have-line
- have-line = PKT-LINE("have" SP obj-id LF)
- compute-end = flush-pkt / PKT-LINE("done")
+ depth = 1*DIGIT
----
Clients MUST send all the obj-ids it wants from the reference
@@ -215,21 +224,64 @@ discovery phase as 'want' lines. Clients MUST send at least one
obj-id in a 'want' command which did not appear in the response
obtained through ref discovery.
-If client is requesting a shallow clone, it will now send a 'deepen'
-line with the depth it is requesting.
+The client MUST write all obj-ids which it only has shallow copies
+of (meaning that it does not have the parents of a commit) as
+'shallow' lines so that the server is aware of the limitations of
+the client's history. Clients MUST NOT mention an obj-id which
+it does not know exists on the server.
+
+The client now sends the maximum commit history depth it wants for
+this transaction, which is the number of commits it wants from the
+tip of the history, if any, as a 'deepen' line. A depth of 0 is the
+same as not making a depth request. The client does not want to receive
+any commits beyond this depth, nor objects needed only to complete
+those commits. Commits whose parents are not received as a result are
+defined as shallow and marked as such in the server. This information
+is sent back to the client in the next step.
+
+Once all the 'want's and 'shallow's (and optional 'deepen') are
+transferred, clients MUST send a flush-pkt, to tell the server side
+that it is done sending the list.
+
+Otherwise, if the client sent a positive depth request, the server
+will determine which commits will and will not be shallow and
+send this information to the client. If the client did not request
+a positive depth, this step is skipped.
-Once all the "want"s (and optional 'deepen') are transferred,
-clients MUST send a flush-pkt. If the client has all the references
-on the server, client flushes and disconnects.
+----
+ shallow-update = *shallow-line
+ *unshallow-line
+ flush-pkt
+
+ shallow-line = PKT-LINE("shallow" SP obj-id)
+
+ unshallow-line = PKT-LINE("unshallow" SP obj-id)
+----
-TODO: shallow/unshallow response and document the deepen command in the ABNF.
+If the client has requested a positive depth, the server will compute
+the set of commits which are no deeper than the desired depth, starting
+at the client's wants. The server writes 'shallow' lines for each
+commit whose parents will not be sent as a result. The server writes
+an 'unshallow' line for each commit which the client has indicated is
+shallow, but is no longer shallow at the currently requested depth
+(that is, its parents will now be sent). The server MUST NOT mark
+as unshallow anything which the client has not indicated was shallow.
Now the client will send a list of the obj-ids it has using 'have'
-lines. In multi_ack mode, the canonical implementation will send up
-to 32 of these at a time, then will send a flush-pkt. The canonical
-implementation will skip ahead and send the next 32 immediately,
-so that there is always a block of 32 "in-flight on the wire" at a
-time.
+lines, so the server can make a packfile that only contains the objects
+that the client needs. In multi_ack mode, the canonical implementation
+will send up to 32 of these at a time, then will send a flush-pkt. The
+canonical implementation will skip ahead and send the next 32 immediately,
+so that there is always a block of 32 "in-flight on the wire" at a time.
+
+----
+ upload-haves = have-list
+ compute-end
+
+ have-list = *have-line
+ have-line = PKT-LINE("have" SP obj-id LF)
+ compute-end = flush-pkt / PKT-LINE("done")
+----
If the server reads 'have' lines, it then will respond by ACKing any
of the obj-ids the client said it had that the server also has. The
diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN
index f04e4b1..e18a30a 100755
--- a/GIT-VERSION-GEN
+++ b/GIT-VERSION-GEN
@@ -1,7 +1,7 @@
#!/bin/sh
GVF=GIT-VERSION-FILE
-DEF_VER=v1.7.6
+DEF_VER=v1.7.8.GIT
LF='
'
diff --git a/INSTALL b/INSTALL
index 16e45f1..bf0d97e 100644
--- a/INSTALL
+++ b/INSTALL
@@ -25,6 +25,19 @@ set up install paths (via config.mak.autogen), so you can write instead
$ make all doc ;# as yourself
# make install install-doc install-html;# as root
+If you're willing to trade off (much) longer build time for a later
+faster git you can also do a profile feedback build with
+
+ $ make profile-all
+ # make prefix=... install
+
+This will run the complete test suite as training workload and then
+rebuild git with the generated profile feedback. This results in a git
+which is a few percent faster on CPU intensive workloads. This
+may be a good tradeoff for distribution packagers.
+
+Note that the profile feedback build stage currently generates
+a lot of additional compiler warnings.
Issues of note:
@@ -126,34 +139,11 @@ Issues of note:
uses some compatibility wrappers to work on AsciiDoc 8. If you have
AsciiDoc 7, try "make ASCIIDOC7=YesPlease".
- Alternatively, pre-formatted documentation is available in
- "html" and "man" branches of the git repository itself. For
- example, you could:
-
- $ mkdir manual && cd manual
- $ git init
- $ git fetch-pack git://git.kernel.org/pub/scm/git/git.git man html |
- while read a b
- do
- echo $a >.git/$b
- done
- $ cp .git/refs/heads/man .git/refs/heads/master
- $ git checkout
-
- to checkout the pre-built man pages. Also in this repository:
-
- $ git checkout html
-
- would instead give you a copy of what you see at:
-
- http://www.kernel.org/pub/software/scm/git/docs/
-
There are also "make quick-install-doc", "make quick-install-man"
and "make quick-install-html" which install preformatted man pages
- and html documentation.
- This does not require asciidoc/xmlto, but it only works from within
- a cloned checkout of git.git with these two extra branches, and will
- not work for the maintainer for obvious chicken-and-egg reasons.
+ and html documentation. To use these build targets, you need to
+ clone two separate git-htmldocs and git-manpages repositories next
+ to the clone of git itself.
It has been reported that docbook-xsl version 1.72 and 1.73 are
buggy; 1.72 misformats manual pages for callouts, and 1.73 needs
diff --git a/Makefile b/Makefile
index e40ac0c..b21d2f1 100644
--- a/Makefile
+++ b/Makefile
@@ -30,15 +30,15 @@ all::
# Define LIBPCREDIR=/foo/bar if your libpcre header and library files are in
# /foo/bar/include and /foo/bar/lib directories.
#
-# Define NO_CURL if you do not have libcurl installed. git-http-pull and
+# Define NO_CURL if you do not have libcurl installed. git-http-fetch and
# git-http-push are not built, and you cannot use http:// and https://
-# transports.
+# transports (neither smart nor dumb).
#
# Define CURLDIR=/foo/bar if your curl header and library files are in
# /foo/bar/include and /foo/bar/lib directories.
#
# Define NO_EXPAT if you do not have expat installed. git-http-push is
-# not built, and you cannot push using http:// and https:// transports.
+# not built, and you cannot push using http:// and https:// transports (dumb).
#
# Define EXPATDIR=/foo/bar if your expat header and library files are in
# /foo/bar/include and /foo/bar/lib directories.
@@ -57,8 +57,8 @@ all::
#
# Define NO_STRLCPY if you don't have strlcpy.
#
-# Define NO_STRTOUMAX if you don't have strtoumax in the C library.
-# If your compiler also does not support long long or does not have
+# Define NO_STRTOUMAX if you don't have both strtoimax and strtoumax in the
+# C library. If your compiler also does not support long long or does not have
# strtoull, define NO_STRTOULL.
#
# Define NO_SETENV if you don't have setenv in the C library.
@@ -115,6 +115,10 @@ all::
#
# Define NEEDS_SSL_WITH_CRYPTO if you need -lssl when using -lcrypto (Darwin).
#
+# Define NEEDS_SSL_WITH_CURL if you need -lssl with -lcurl (Minix).
+#
+# Define NEEDS_IDN_WITH_CURL if you need -lidn when using -lcurl (Minix).
+#
# Define NEEDS_LIBICONV if linking with libc is not enough (Darwin).
#
# Define NEEDS_SOCKET if linking with libc is not enough (SunOS,
@@ -153,6 +157,9 @@ all::
# that tells runtime paths to dynamic libraries;
# "-Wl,-rpath=/path/lib" is used instead.
#
+# Define NO_NORETURN if using buggy versions of gcc 4.6+ and profile feedback,
+# as the compiler can crash (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49299)
+#
# Define USE_NSEC below if you want git to care about sub-second file mtimes
# and ctimes. Note that you need recent glibc (at least 2.2.4) for this, and
# it will BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely
@@ -243,9 +250,11 @@ all::
# DEFAULT_EDITOR='$GIT_FALLBACK_EDITOR',
# DEFAULT_EDITOR='"C:\Program Files\Vim\gvim.exe" --nofork'
#
-# Define COMPUTE_HEADER_DEPENDENCIES if your compiler supports the -MMD option
-# and you want to avoid rebuilding objects when an unrelated header file
-# changes.
+# Define COMPUTE_HEADER_DEPENDENCIES to "yes" if you want dependencies on
+# header files to be automatically computed, to avoid rebuilding objects when
+# an unrelated header file changes. Define it to "no" to use the hard-coded
+# dependency rules. The default is "auto", which means to use computed header
+# dependencies if your compiler is detected to support it.
#
# Define CHECK_HEADER_DEPENDENCIES to check for problems in the hard-coded
# dependency rules.
@@ -295,6 +304,7 @@ bindir = $(prefix)/$(bindir_relative)
mandir = share/man
infodir = share/info
gitexecdir = libexec/git-core
+mergetoolsdir = $(gitexecdir)/mergetools
sharedir = $(prefix)/share
gitwebdir = $(sharedir)/gitweb
template_dir = share/git-core/templates
@@ -497,6 +507,7 @@ VCSSVN_LIB=vcs-svn/lib.a
LIB_H += advice.h
LIB_H += archive.h
+LIB_H += argv-array.h
LIB_H += attr.h
LIB_H += blob.h
LIB_H += builtin.h
@@ -507,10 +518,13 @@ LIB_H += commit.h
LIB_H += compat/bswap.h
LIB_H += compat/cygwin.h
LIB_H += compat/mingw.h
+LIB_H += compat/obstack.h
LIB_H += compat/win32/pthread.h
LIB_H += compat/win32/syslog.h
-LIB_H += compat/win32/sys/poll.h
+LIB_H += compat/win32/poll.h
LIB_H += compat/win32/dirent.h
+LIB_H += connected.h
+LIB_H += convert.h
LIB_H += csum-file.h
LIB_H += decorate.h
LIB_H += delta.h
@@ -525,6 +539,7 @@ LIB_H += graph.h
LIB_H += grep.h
LIB_H += hash.h
LIB_H += help.h
+LIB_H += kwset.h
LIB_H += levenshtein.h
LIB_H += list-objects.h
LIB_H += ll-merge.h
@@ -551,11 +566,13 @@ LIB_H += rerere.h
LIB_H += resolve-undo.h
LIB_H += revision.h
LIB_H += run-command.h
+LIB_H += sequencer.h
LIB_H += sha1-array.h
LIB_H += sha1-lookup.h
LIB_H += sideband.h
LIB_H += sigchain.h
LIB_H += strbuf.h
+LIB_H += streaming.h
LIB_H += string-list.h
LIB_H += submodule.h
LIB_H += tag.h
@@ -575,6 +592,7 @@ LIB_OBJS += alloc.o
LIB_OBJS += archive.o
LIB_OBJS += archive-tar.o
LIB_OBJS += archive-zip.o
+LIB_OBJS += argv-array.o
LIB_OBJS += attr.o
LIB_OBJS += base85.o
LIB_OBJS += bisect.o
@@ -585,8 +603,10 @@ LIB_OBJS += cache-tree.o
LIB_OBJS += color.o
LIB_OBJS += combine-diff.o
LIB_OBJS += commit.o
+LIB_OBJS += compat/obstack.o
LIB_OBJS += config.o
LIB_OBJS += connect.o
+LIB_OBJS += connected.o
LIB_OBJS += convert.o
LIB_OBJS += copy.o
LIB_OBJS += csum-file.o
@@ -614,6 +634,7 @@ LIB_OBJS += hash.o
LIB_OBJS += help.o
LIB_OBJS += hex.o
LIB_OBJS += ident.o
+LIB_OBJS += kwset.o
LIB_OBJS += levenshtein.o
LIB_OBJS += list-objects.o
LIB_OBJS += ll-merge.o
@@ -634,6 +655,7 @@ LIB_OBJS += pack-revindex.o
LIB_OBJS += pack-write.o
LIB_OBJS += pager.o
LIB_OBJS += parse-options.o
+LIB_OBJS += parse-options-cb.o
LIB_OBJS += patch-delta.o
LIB_OBJS += patch-ids.o
LIB_OBJS += path.o
@@ -654,6 +676,7 @@ LIB_OBJS += revision.o
LIB_OBJS += run-command.o
LIB_OBJS += server-info.o
LIB_OBJS += setup.o
+LIB_OBJS += sequencer.o
LIB_OBJS += sha1-array.o
LIB_OBJS += sha1-lookup.o
LIB_OBJS += sha1_file.o
@@ -662,6 +685,7 @@ LIB_OBJS += shallow.o
LIB_OBJS += sideband.o
LIB_OBJS += sigchain.o
LIB_OBJS += strbuf.o
+LIB_OBJS += streaming.o
LIB_OBJS += string-list.o
LIB_OBJS += submodule.o
LIB_OBJS += symlinks.o
@@ -805,6 +829,7 @@ ifeq ($(uname_S),GNU/kFreeBSD)
NO_STRLCPY = YesPlease
NO_MKSTEMPS = YesPlease
HAVE_PATHS_H = YesPlease
+ DIR_HAS_BSD_GROUP_SEMANTICS = YesPlease
endif
ifeq ($(uname_S),UnixWare)
CC = cc
@@ -1070,6 +1095,7 @@ ifeq ($(uname_S),Windows)
NO_PREAD = YesPlease
NEEDS_CRYPTO_WITH_SSL = YesPlease
NO_LIBGEN_H = YesPlease
+ NO_SYS_POLL_H = YesPlease
NO_SYMLINK_HEAD = YesPlease
NO_IPV6 = YesPlease
NO_SETENV = YesPlease
@@ -1108,7 +1134,7 @@ ifeq ($(uname_S),Windows)
BASIC_CFLAGS = -nologo -I. -I../zlib -Icompat/vcbuild -Icompat/vcbuild/include -DWIN32 -D_CONSOLE -DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE
COMPAT_OBJS = compat/msvc.o compat/winansi.o \
compat/win32/pthread.o compat/win32/syslog.o \
- compat/win32/sys/poll.o compat/win32/dirent.o
+ compat/win32/poll.o compat/win32/dirent.o
COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -DHAVE_ALLOCA_H -Icompat -Icompat/regex -Icompat/win32 -DSTRIP_EXTENSION=\".exe\"
BASIC_LDFLAGS = -IGNORE:4217 -IGNORE:4049 -NOLOGO -SUBSYSTEM:CONSOLE -NODEFAULTLIB:MSVCRT.lib
EXTLIBS = user32.lib advapi32.lib shell32.lib wininet.lib ws2_32.lib
@@ -1124,8 +1150,6 @@ endif
X = .exe
endif
ifeq ($(uname_S),Interix)
- NO_SYS_POLL_H = YesPlease
- NO_INTTYPES_H = YesPlease
NO_INITGROUPS = YesPlease
NO_IPV6 = YesPlease
NO_MEMMEM = YesPlease
@@ -1136,17 +1160,36 @@ ifeq ($(uname_S),Interix)
ifeq ($(uname_R),3.5)
NO_INET_NTOP = YesPlease
NO_INET_PTON = YesPlease
+ NO_SOCKADDR_STORAGE = YesPlease
+ NO_FNMATCH_CASEFOLD = YesPlease
endif
ifeq ($(uname_R),5.2)
NO_INET_NTOP = YesPlease
NO_INET_PTON = YesPlease
+ NO_SOCKADDR_STORAGE = YesPlease
+ NO_FNMATCH_CASEFOLD = YesPlease
endif
endif
+ifeq ($(uname_S),Minix)
+ NO_IPV6 = YesPlease
+ NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
+ NO_NSEC = YesPlease
+ NEEDS_LIBGEN =
+ NEEDS_CRYPTO_WITH_SSL = YesPlease
+ NEEDS_IDN_WITH_CURL = YesPlease
+ NEEDS_SSL_WITH_CURL = YesPlease
+ NEEDS_RESOLV =
+ NO_HSTRERROR = YesPlease
+ NO_MMAP = YesPlease
+ NO_CURL =
+ NO_EXPAT =
+endif
ifneq (,$(findstring MINGW,$(uname_S)))
pathsep = ;
NO_PREAD = YesPlease
NEEDS_CRYPTO_WITH_SSL = YesPlease
NO_LIBGEN_H = YesPlease
+ NO_SYS_POLL_H = YesPlease
NO_SYMLINK_HEAD = YesPlease
NO_SETENV = YesPlease
NO_UNSETENV = YesPlease
@@ -1180,7 +1223,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
COMPAT_OBJS += compat/mingw.o compat/winansi.o \
compat/win32/pthread.o compat/win32/syslog.o \
- compat/win32/sys/poll.o compat/win32/dirent.o
+ compat/win32/poll.o compat/win32/dirent.o
EXTLIBS += -lws2_32
PTHREAD_LIBS =
X = .exe
@@ -1209,12 +1252,32 @@ endif
endif
ifdef CHECK_HEADER_DEPENDENCIES
-COMPUTE_HEADER_DEPENDENCIES =
+COMPUTE_HEADER_DEPENDENCIES = no
USE_COMPUTED_HEADER_DEPENDENCIES =
endif
-ifdef COMPUTE_HEADER_DEPENDENCIES
+ifndef COMPUTE_HEADER_DEPENDENCIES
+COMPUTE_HEADER_DEPENDENCIES = auto
+endif
+
+ifeq ($(COMPUTE_HEADER_DEPENDENCIES),auto)
+dep_check = $(shell $(CC) $(ALL_CFLAGS) \
+ -c -MF /dev/null -MMD -MP -x c /dev/null -o /dev/null 2>&1; \
+ echo $$?)
+ifeq ($(dep_check),0)
+override COMPUTE_HEADER_DEPENDENCIES = yes
+else
+override COMPUTE_HEADER_DEPENDENCIES = no
+endif
+endif
+
+ifeq ($(COMPUTE_HEADER_DEPENDENCIES),yes)
USE_COMPUTED_HEADER_DEPENDENCIES = YesPlease
+else
+ifneq ($(COMPUTE_HEADER_DEPENDENCIES),no)
+$(error please set COMPUTE_HEADER_DEPENDENCIES to yes, no, or auto \
+(not "$(COMPUTE_HEADER_DEPENDENCIES)"))
+endif
endif
ifdef SANE_TOOL_PATH
@@ -1286,6 +1349,16 @@ else
else
CURL_LIBCURL = -lcurl
endif
+ ifdef NEEDS_SSL_WITH_CURL
+ CURL_LIBCURL += -lssl
+ ifdef NEEDS_CRYPTO_WITH_SSL
+ CURL_LIBCURL += -lcrypto
+ endif
+ endif
+ ifdef NEEDS_IDN_WITH_CURL
+ CURL_LIBCURL += -lidn
+ endif
+
REMOTE_CURL_PRIMARY = git-remote-http$X
REMOTE_CURL_ALIASES = git-remote-https$X git-remote-ftp$X git-remote-ftps$X
REMOTE_CURL_NAMES = $(REMOTE_CURL_PRIMARY) $(REMOTE_CURL_ALIASES)
@@ -1322,7 +1395,7 @@ ifndef NO_OPENSSL
OPENSSL_LINK =
endif
ifdef NEEDS_CRYPTO_WITH_SSL
- OPENSSL_LINK += -lcrypto
+ OPENSSL_LIBSSL += -lcrypto
endif
else
BASIC_CFLAGS += -DNO_OPENSSL
@@ -1374,6 +1447,9 @@ endif
ifdef USE_ST_TIMESPEC
BASIC_CFLAGS += -DUSE_ST_TIMESPEC
endif
+ifdef NO_NORETURN
+ BASIC_CFLAGS += -DNO_NORETURN
+endif
ifdef NO_NSEC
BASIC_CFLAGS += -DNO_NSEC
endif
@@ -1402,7 +1478,7 @@ ifdef NO_STRLCPY
endif
ifdef NO_STRTOUMAX
COMPAT_CFLAGS += -DNO_STRTOUMAX
- COMPAT_OBJS += compat/strtoumax.o
+ COMPAT_OBJS += compat/strtoumax.o compat/strtoimax.o
endif
ifdef NO_STRTOULL
COMPAT_CFLAGS += -DNO_STRTOULL
@@ -1706,7 +1782,7 @@ git.sp git.s git.o: EXTRA_CPPFLAGS = -DGIT_VERSION='"$(GIT_VERSION)"' \
'-DGIT_MAN_PATH="$(mandir_SQ)"' \
'-DGIT_INFO_PATH="$(infodir_SQ)"'
-git$X: git.o $(BUILTIN_OBJS) $(GITLIBS)
+git$X: git.o GIT-LDFLAGS $(BUILTIN_OBJS) $(GITLIBS)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ git.o \
$(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS)
@@ -1838,7 +1914,7 @@ ifndef NO_CURL
GIT_OBJS += http.o http-walker.o remote-curl.o
endif
XDIFF_OBJS = xdiff/xdiffi.o xdiff/xprepare.o xdiff/xutils.o xdiff/xemit.o \
- xdiff/xmerge.o xdiff/xpatience.o
+ xdiff/xmerge.o xdiff/xpatience.o xdiff/xhistogram.o
VCSSVN_OBJS = vcs-svn/string_pool.o vcs-svn/line_buffer.o \
vcs-svn/repo_tree.o vcs-svn/fast_export.o vcs-svn/svndump.o
VCSSVN_TEST_OBJS = test-obj-pool.o test-string-pool.o \
@@ -1848,9 +1924,9 @@ OBJECTS := $(GIT_OBJS) $(XDIFF_OBJS) $(VCSSVN_OBJS)
dep_files := $(foreach f,$(OBJECTS),$(dir $f).depend/$(notdir $f).d)
dep_dirs := $(addsuffix .depend,$(sort $(dir $(OBJECTS))))
-ifdef COMPUTE_HEADER_DEPENDENCIES
+ifeq ($(COMPUTE_HEADER_DEPENDENCIES),yes)
$(dep_dirs):
- mkdir -p $@
+ @mkdir -p $@
missing_dep_dirs := $(filter-out $(wildcard $(dep_dirs)),$(dep_dirs))
dep_file = $(dir $@).depend/$(notdir $@).d
@@ -1861,7 +1937,7 @@ Please unset CHECK_HEADER_DEPENDENCIES and try again)
endif
endif
-ifndef COMPUTE_HEADER_DEPENDENCIES
+ifneq ($(COMPUTE_HEADER_DEPENDENCIES),yes)
ifndef CHECK_HEADER_DEPENDENCIES
dep_dirs =
missing_dep_dirs =
@@ -1951,13 +2027,13 @@ builtin/branch.o builtin/checkout.o builtin/clone.o builtin/reset.o branch.o tra
builtin/bundle.o bundle.o transport.o: bundle.h
builtin/bisect--helper.o builtin/rev-list.o bisect.o: bisect.h
builtin/clone.o builtin/fetch-pack.o transport.o: fetch-pack.h
-builtin/grep.o builtin/pack-objects.o transport-helper.o: thread-utils.h
+builtin/grep.o builtin/pack-objects.o transport-helper.o thread-utils.o: thread-utils.h
builtin/send-pack.o transport.o: send-pack.h
builtin/log.o builtin/shortlog.o: shortlog.h
builtin/prune.o builtin/reflog.o reachable.o: reachable.h
builtin/commit.o builtin/revert.o wt-status.o: wt-status.h
builtin/tar-tree.o archive-tar.o: tar.h
-connect.o transport.o http-backend.o: url.h
+connect.o transport.o url.o http-backend.o: url.h
http-fetch.o http-walker.o remote-curl.o transport.o walker.o: walker.h
http.o http-walker.o http-push.o http-fetch.o remote-curl.o: http.h url.h
@@ -2004,17 +2080,17 @@ compat/nedmalloc/nedmalloc.sp compat/nedmalloc/nedmalloc.o: EXTRA_CPPFLAGS = \
-DNDEBUG -DOVERRIDE_STRDUP -DREPLACE_SYSTEM_ALLOCATOR
endif
-git-%$X: %.o $(GITLIBS)
+git-%$X: %.o GIT-LDFLAGS $(GITLIBS)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
-git-imap-send$X: imap-send.o $(GITLIBS)
+git-imap-send$X: imap-send.o GIT-LDFLAGS $(GITLIBS)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
$(LIBS) $(OPENSSL_LINK) $(OPENSSL_LIBSSL) $(LIB_4_CRYPTO)
-git-http-fetch$X: revision.o http.o http-walker.o http-fetch.o $(GITLIBS)
+git-http-fetch$X: revision.o http.o http-walker.o http-fetch.o GIT-LDFLAGS $(GITLIBS)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
$(LIBS) $(CURL_LIBCURL)
-git-http-push$X: revision.o http.o http-push.o $(GITLIBS)
+git-http-push$X: revision.o http.o http-push.o GIT-LDFLAGS $(GITLIBS)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
$(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
@@ -2024,7 +2100,7 @@ $(REMOTE_CURL_ALIASES): $(REMOTE_CURL_PRIMARY)
ln -s $< $@ 2>/dev/null || \
cp $< $@
-$(REMOTE_CURL_PRIMARY): remote-curl.o http.o http-walker.o $(GITLIBS)
+$(REMOTE_CURL_PRIMARY): remote-curl.o http.o http-walker.o GIT-LDFLAGS $(GITLIBS)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
$(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
@@ -2071,17 +2147,21 @@ po/git.pot: $(LOCALIZED_C)
pot: po/git.pot
+FIND_SOURCE_FILES = ( git ls-files '*.[hcS]' 2>/dev/null || \
+ $(FIND) . \( -name .git -type d -prune \) \
+ -o \( -name '*.[hcS]' -type f -print \) )
+
$(ETAGS_TARGET): FORCE
$(RM) $(ETAGS_TARGET)
- $(FIND) . -name '*.[hcS]' -print | xargs etags -a -o $(ETAGS_TARGET)
+ $(FIND_SOURCE_FILES) | xargs etags -a -o $(ETAGS_TARGET)
tags: FORCE
$(RM) tags
- $(FIND) . -name '*.[hcS]' -print | xargs ctags -a
+ $(FIND_SOURCE_FILES) | xargs ctags -a
cscope:
$(RM) cscope*
- $(FIND) . -name '*.[hcS]' -print | xargs cscope -b
+ $(FIND_SOURCE_FILES) | xargs cscope -b
### Detect prefix changes
TRACK_CFLAGS = $(CC):$(subst ','\'',$(ALL_CFLAGS)):\
@@ -2094,6 +2174,15 @@ GIT-CFLAGS: FORCE
echo "$$FLAGS" >GIT-CFLAGS; \
fi
+TRACK_LDFLAGS = $(subst ','\'',$(ALL_LDFLAGS))
+
+GIT-LDFLAGS: FORCE
+ @FLAGS='$(TRACK_LDFLAGS)'; \
+ if test x"$$FLAGS" != x"`cat GIT-LDFLAGS 2>/dev/null`" ; then \
+ echo 1>&2 " * new link flags"; \
+ echo "$$FLAGS" >GIT-LDFLAGS; \
+ fi
+
# We need to apply sq twice, once to protect from the shell
# that runs GIT-BUILD-OPTIONS, and then again to protect it
# and the first level quoting from the shell that runs "echo".
@@ -2157,7 +2246,7 @@ test-delta$X: diff-delta.o patch-delta.o
test-line-buffer$X: vcs-svn/lib.a
-test-parse-options$X: parse-options.o
+test-parse-options$X: parse-options.o parse-options-cb.o
test-string-pool$X: vcs-svn/lib.a
@@ -2165,7 +2254,7 @@ test-svn-fe$X: vcs-svn/lib.a
.PRECIOUS: $(TEST_OBJS)
-test-%$X: test-%.o $(GITLIBS)
+test-%$X: test-%.o GIT-LDFLAGS $(GITLIBS)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(filter %.a,$^) $(LIBS)
check-sha1:: test-sha1$X
@@ -2210,6 +2299,13 @@ endif
gitexec_instdir_SQ = $(subst ','\'',$(gitexec_instdir))
export gitexec_instdir
+ifneq ($(filter /%,$(firstword $(mergetoolsdir))),)
+mergetools_instdir = $(mergetoolsdir)
+else
+mergetools_instdir = $(prefix)/$(mergetoolsdir)
+endif
+mergetools_instdir_SQ = $(subst ','\'',$(mergetools_instdir))
+
install_bindir_programs := $(patsubst %,%$X,$(BINDIR_PROGRAMS_NEED_X)) $(BINDIR_PROGRAMS_NO_X)
install: all
@@ -2219,6 +2315,8 @@ install: all
$(INSTALL) -m 644 $(SCRIPT_LIB) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) $(install_bindir_programs) '$(DESTDIR_SQ)$(bindir_SQ)'
$(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(mergetools_instdir_SQ)'
+ $(INSTALL) -m 644 mergetools/* '$(DESTDIR_SQ)$(mergetools_instdir_SQ)'
ifndef NO_PERL
$(MAKE) -C perl prefix='$(prefix_SQ)' DESTDIR='$(DESTDIR_SQ)' install
$(MAKE) -C gitweb install
@@ -2375,7 +2473,7 @@ ifndef NO_TCLTK
$(MAKE) -C gitk-git clean
$(MAKE) -C git-gui clean
endif
- $(RM) GIT-VERSION-FILE GIT-CFLAGS GIT-GUI-VARS GIT-BUILD-OPTIONS
+ $(RM) GIT-VERSION-FILE GIT-CFLAGS GIT-LDFLAGS GIT-GUI-VARS GIT-BUILD-OPTIONS
.PHONY: all install clean strip
.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
@@ -2486,3 +2584,19 @@ cover_db: coverage-report
cover_db_html: cover_db
cover -report html -outputdir cover_db_html cover_db
+
+### profile feedback build
+#
+.PHONY: profile-all profile-clean
+
+PROFILE_GEN_CFLAGS := $(CFLAGS) -fprofile-generate -DNO_NORETURN=1
+PROFILE_USE_CFLAGS := $(CFLAGS) -fprofile-use -fprofile-correction -DNO_NORETURN=1
+
+profile-clean:
+ $(RM) $(addsuffix *.gcda,$(object_dirs))
+ $(RM) $(addsuffix *.gcno,$(object_dirs))
+
+profile-all: profile-clean
+ $(MAKE) CFLAGS="$(PROFILE_GEN_CFLAGS)" all
+ $(MAKE) CFLAGS="$(PROFILE_GEN_CFLAGS)" -j1 test
+ $(MAKE) CFLAGS="$(PROFILE_USE_CFLAGS)" all
diff --git a/RelNotes b/RelNotes
index 5fcc4ef..766bbaf 120000
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/1.7.6.txt \ No newline at end of file
+Documentation/RelNotes/1.7.9.txt \ No newline at end of file
diff --git a/abspath.c b/abspath.c
index 3005aed..f04ac18 100644
--- a/abspath.c
+++ b/abspath.c
@@ -40,7 +40,7 @@ const char *real_path(const char *path)
while (depth--) {
if (!is_directory(buf)) {
- char *last_slash = strrchr(buf, '/');
+ char *last_slash = find_last_dir_sep(buf);
if (last_slash) {
*last_slash = '\0';
last_elem = xstrdup(last_slash + 1);
@@ -65,7 +65,7 @@ const char *real_path(const char *path)
if (len + strlen(last_elem) + 2 > PATH_MAX)
die ("Too long path name: '%s/%s'",
buf, last_elem);
- if (len && buf[len-1] != '/')
+ if (len && !is_dir_sep(buf[len-1]))
buf[len++] = '/';
strcpy(buf + len, last_elem);
free(last_elem);
@@ -102,7 +102,8 @@ static const char *get_pwd_cwd(void)
pwd = getenv("PWD");
if (pwd && strcmp(pwd, cwd)) {
stat(cwd, &cwd_stat);
- if (!stat(pwd, &pwd_stat) &&
+ if ((cwd_stat.st_dev || cwd_stat.st_ino) &&
+ !stat(pwd, &pwd_stat) &&
pwd_stat.st_dev == cwd_stat.st_dev &&
pwd_stat.st_ino == cwd_stat.st_ino) {
strlcpy(cwd, pwd, PATH_MAX);
@@ -138,3 +139,31 @@ const char *absolute_path(const char *path)
}
return buf;
}
+
+/*
+ * Unlike prefix_path, this should be used if the named file does
+ * not have to interact with index entry; i.e. name of a random file
+ * on the filesystem.
+ */
+const char *prefix_filename(const char *pfx, int pfx_len, const char *arg)
+{
+ static char path[PATH_MAX];
+#ifndef WIN32
+ if (!pfx_len || is_absolute_path(arg))
+ return arg;
+ memcpy(path, pfx, pfx_len);
+ strcpy(path + pfx_len, arg);
+#else
+ char *p;
+ /* don't add prefix to absolute paths, but still replace '\' by '/' */
+ if (is_absolute_path(arg))
+ pfx_len = 0;
+ else if (pfx_len)
+ memcpy(path, pfx, pfx_len);
+ strcpy(path + pfx_len, arg);
+ for (p = path + pfx_len; *p; p++)
+ if (*p == '\\')
+ *p = '/';
+#endif
+ return path;
+}
diff --git a/advice.c b/advice.c
index 0be4b5f..e02e632 100644
--- a/advice.c
+++ b/advice.c
@@ -19,6 +19,15 @@ static struct {
{ "detachedhead", &advice_detached_head },
};
+void advise(const char *advice, ...)
+{
+ va_list params;
+
+ va_start(params, advice);
+ vreportf("hint: ", advice, params);
+ va_end(params);
+}
+
int git_default_advice_config(const char *var, const char *value)
{
const char *k = skip_prefix(var, "advice.");
@@ -34,16 +43,24 @@ int git_default_advice_config(const char *var, const char *value)
return 0;
}
-void NORETURN die_resolve_conflict(const char *me)
+int error_resolve_conflict(const char *me)
{
- if (advice_resolve_conflict)
+ error("'%s' is not possible because you have unmerged files.", me);
+ if (advice_resolve_conflict) {
/*
* Message used both when 'git commit' fails and when
* other commands doing a merge do.
*/
- die("'%s' is not possible because you have unmerged files.\n"
- "Please, fix them up in the work tree, and then use 'git add/rm <file>' as\n"
- "appropriate to mark resolution and make a commit, or use 'git commit -a'.", me);
- else
- die("'%s' is not possible because you have unmerged files.", me);
+ advise("Fix them up in the work tree,");
+ advise("and then use 'git add/rm <file>' as");
+ advise("appropriate to mark resolution and make a commit,");
+ advise("or use 'git commit -a'.");
+ }
+ return -1;
+}
+
+void NORETURN die_resolve_conflict(const char *me)
+{
+ error_resolve_conflict(me);
+ die("Exiting because of an unresolved conflict.");
}
diff --git a/advice.h b/advice.h
index 3244ebb..e5d0af7 100644
--- a/advice.h
+++ b/advice.h
@@ -11,7 +11,8 @@ extern int advice_implicit_identity;
extern int advice_detached_head;
int git_default_advice_config(const char *var, const char *value);
-
+void advise(const char *advice, ...);
+int error_resolve_conflict(const char *me);
extern void NORETURN die_resolve_conflict(const char *me);
#endif /* ADVICE_H */
diff --git a/archive-tar.c b/archive-tar.c
index cee06ce..20af005 100644
--- a/archive-tar.c
+++ b/archive-tar.c
@@ -4,6 +4,7 @@
#include "cache.h"
#include "tar.h"
#include "archive.h"
+#include "run-command.h"
#define RECORDSIZE (512)
#define BLOCKSIZE (RECORDSIZE * 20)
@@ -13,6 +14,9 @@ static unsigned long offset;
static int tar_umask = 002;
+static int write_tar_filter_archive(const struct archiver *ar,
+ struct archiver_args *args);
+
/* writes out the whole block, but only if it is full */
static void write_if_needed(void)
{
@@ -220,6 +224,67 @@ static int write_global_extended_header(struct archiver_args *args)
return err;
}
+static struct archiver **tar_filters;
+static int nr_tar_filters;
+static int alloc_tar_filters;
+
+static struct archiver *find_tar_filter(const char *name, int len)
+{
+ int i;
+ for (i = 0; i < nr_tar_filters; i++) {
+ struct archiver *ar = tar_filters[i];
+ if (!strncmp(ar->name, name, len) && !ar->name[len])
+ return ar;
+ }
+ return NULL;
+}
+
+static int tar_filter_config(const char *var, const char *value, void *data)
+{
+ struct archiver *ar;
+ const char *dot;
+ const char *name;
+ const char *type;
+ int namelen;
+
+ if (prefixcmp(var, "tar."))
+ return 0;
+ dot = strrchr(var, '.');
+ if (dot == var + 9)
+ return 0;
+
+ name = var + 4;
+ namelen = dot - name;
+ type = dot + 1;
+
+ ar = find_tar_filter(name, namelen);
+ if (!ar) {
+ ar = xcalloc(1, sizeof(*ar));
+ ar->name = xmemdupz(name, namelen);
+ ar->write_archive = write_tar_filter_archive;
+ ar->flags = ARCHIVER_WANT_COMPRESSION_LEVELS;
+ ALLOC_GROW(tar_filters, nr_tar_filters + 1, alloc_tar_filters);
+ tar_filters[nr_tar_filters++] = ar;
+ }
+
+ if (!strcmp(type, "command")) {
+ if (!value)
+ return config_error_nonbool(var);
+ free(ar->data);
+ ar->data = xstrdup(value);
+ return 0;
+ }
+ if (!strcmp(type, "remote")) {
+ if (git_config_bool(var, value))
+ ar->flags |= ARCHIVER_REMOTE;
+ else
+ ar->flags &= ~ARCHIVER_REMOTE;
+ return 0;
+ }
+
+ return 0;
+}
+
static int git_tar_config(const char *var, const char *value, void *cb)
{
if (!strcmp(var, "tar.umask")) {
@@ -231,15 +296,15 @@ static int git_tar_config(const char *var, const char *value, void *cb)
}
return 0;
}
- return git_default_config(var, value, cb);
+
+ return tar_filter_config(var, value, cb);
}
-int write_tar_archive(struct archiver_args *args)
+static int write_tar_archive(const struct archiver *ar,
+ struct archiver_args *args)
{
int err = 0;
- git_config(git_tar_config, NULL);
-
if (args->commit_sha1)
err = write_global_extended_header(args);
if (!err)
@@ -248,3 +313,65 @@ int write_tar_archive(struct archiver_args *args)
write_trailer();
return err;
}
+
+static int write_tar_filter_archive(const struct archiver *ar,
+ struct archiver_args *args)
+{
+ struct strbuf cmd = STRBUF_INIT;
+ struct child_process filter;
+ const char *argv[2];
+ int r;
+
+ if (!ar->data)
+ die("BUG: tar-filter archiver called with no filter defined");
+
+ strbuf_addstr(&cmd, ar->data);
+ if (args->compression_level >= 0)
+ strbuf_addf(&cmd, " -%d", args->compression_level);
+
+ memset(&filter, 0, sizeof(filter));
+ argv[0] = cmd.buf;
+ argv[1] = NULL;
+ filter.argv = argv;
+ filter.use_shell = 1;
+ filter.in = -1;
+
+ if (start_command(&filter) < 0)
+ die_errno("unable to start '%s' filter", argv[0]);
+ close(1);
+ if (dup2(filter.in, 1) < 0)
+ die_errno("unable to redirect descriptor");
+ close(filter.in);
+
+ r = write_tar_archive(ar, args);
+
+ close(1);
+ if (finish_command(&filter) != 0)
+ die("'%s' filter reported error", argv[0]);
+
+ strbuf_release(&cmd);
+ return r;
+}
+
+static struct archiver tar_archiver = {
+ "tar",
+ write_tar_archive,
+ ARCHIVER_REMOTE
+};
+
+void init_tar_archiver(void)
+{
+ int i;
+ register_archiver(&tar_archiver);
+
+ tar_filter_config("tar.tgz.command", "gzip -cn", NULL);
+ tar_filter_config("tar.tgz.remote", "true", NULL);
+ tar_filter_config("tar.tar.gz.command", "gzip -cn", NULL);
+ tar_filter_config("tar.tar.gz.remote", "true", NULL);
+ git_config(git_tar_config, NULL);
+ for (i = 0; i < nr_tar_filters; i++) {
+ /* omit any filters that never had a command configured */
+ if (tar_filters[i]->data)
+ register_archiver(tar_filters[i]);
+ }
+}
diff --git a/archive-zip.c b/archive-zip.c
index cf28504..02d1f37 100644
--- a/archive-zip.c
+++ b/archive-zip.c
@@ -90,14 +90,14 @@ static void copy_le32(unsigned char *dest, unsigned int n)
static void *zlib_deflate(void *data, unsigned long size,
int compression_level, unsigned long *compressed_size)
{
- z_stream stream;
+ git_zstream stream;
unsigned long maxsize;
void *buffer;
int result;
memset(&stream, 0, sizeof(stream));
- deflateInit(&stream, compression_level);
- maxsize = deflateBound(&stream, size);
+ git_deflate_init(&stream, compression_level);
+ maxsize = git_deflate_bound(&stream, size);
buffer = xmalloc(maxsize);
stream.next_in = data;
@@ -106,7 +106,7 @@ static void *zlib_deflate(void *data, unsigned long size,
stream.avail_out = maxsize;
do {
- result = deflate(&stream, Z_FINISH);
+ result = git_deflate(&stream, Z_FINISH);
} while (result == Z_OK);
if (result != Z_STREAM_END) {
@@ -114,7 +114,7 @@ static void *zlib_deflate(void *data, unsigned long size,
return NULL;
}
- deflateEnd(&stream);
+ git_deflate_end(&stream);
*compressed_size = stream.total_out;
return buffer;
@@ -261,7 +261,8 @@ static void dos_time(time_t *time, int *dos_date, int *dos_time)
*dos_time = t->tm_sec / 2 + t->tm_min * 32 + t->tm_hour * 2048;
}
-int write_zip_archive(struct archiver_args *args)
+static int write_zip_archive(const struct archiver *ar,
+ struct archiver_args *args)
{
int err;
@@ -278,3 +279,14 @@ int write_zip_archive(struct archiver_args *args)
return err;
}
+
+static struct archiver zip_archiver = {
+ "zip",
+ write_zip_archive,
+ ARCHIVER_WANT_COMPRESSION_LEVELS|ARCHIVER_REMOTE
+};
+
+void init_zip_archiver(void)
+{
+ register_archiver(&zip_archiver);
+}
diff --git a/archive.c b/archive.c
index 42f2d2f..2ae740a 100644
--- a/archive.c
+++ b/archive.c
@@ -14,16 +14,15 @@ static char const * const archive_usage[] = {
NULL
};
-#define USES_ZLIB_COMPRESSION 1
-
-static const struct archiver {
- const char *name;
- write_archive_fn_t write_archive;
- unsigned int flags;
-} archivers[] = {
- { "tar", write_tar_archive },
- { "zip", write_zip_archive, USES_ZLIB_COMPRESSION },
-};
+static const struct archiver **archivers;
+static int nr_archivers;
+static int alloc_archivers;
+
+void register_archiver(struct archiver *ar)
+{
+ ALLOC_GROW(archivers, nr_archivers + 1, alloc_archivers);
+ archivers[nr_archivers++] = ar;
+}
static void format_subst(const struct commit *commit,
const char *src, size_t len,
@@ -124,7 +123,7 @@ static int write_archive_entry(const unsigned char *sha1, const char *base,
path_without_prefix = path.buf + args->baselen;
setup_archive_check(check);
- if (!git_checkattr(path_without_prefix, ARRAY_SIZE(check), check)) {
+ if (!git_check_attr(path_without_prefix, ARRAY_SIZE(check), check)) {
if (ATTR_TRUE(check[0].value))
return 0;
convert = ATTR_TRUE(check[1].value);
@@ -208,9 +207,9 @@ static const struct archiver *lookup_archiver(const char *name)
if (!name)
return NULL;
- for (i = 0; i < ARRAY_SIZE(archivers); i++) {
- if (!strcmp(name, archivers[i].name))
- return &archivers[i];
+ for (i = 0; i < nr_archivers; i++) {
+ if (!strcmp(name, archivers[i]->name))
+ return archivers[i];
}
return NULL;
}
@@ -299,9 +298,10 @@ static void parse_treeish_arg(const char **argv,
PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_HIDDEN, NULL, (p) }
static int parse_archive_args(int argc, const char **argv,
- const struct archiver **ar, struct archiver_args *args)
+ const struct archiver **ar, struct archiver_args *args,
+ const char *name_hint, int is_remote)
{
- const char *format = "tar";
+ const char *format = NULL;
const char *base = NULL;
const char *remote = NULL;
const char *exec = NULL;
@@ -318,7 +318,7 @@ static int parse_archive_args(int argc, const char **argv,
"prepend prefix to each pathname in the archive"),
OPT_STRING('o', "output", &output, "file",
"write the archive to this file"),
- OPT_BOOLEAN(0, "worktree-attributes", &worktree_attributes,
+ OPT_BOOL(0, "worktree-attributes", &worktree_attributes,
"read .gitattributes in working directory"),
OPT__VERBOSE(&verbose, "report archived files on stderr"),
OPT__COMPR('0', &compression_level, "store only", 0),
@@ -332,7 +332,7 @@ static int parse_archive_args(int argc, const char **argv,
OPT__COMPR_HIDDEN('8', &compression_level, 8),
OPT__COMPR('9', &compression_level, "compress better", 9),
OPT_GROUP(""),
- OPT_BOOLEAN('l', "list", &list,
+ OPT_BOOL('l', "list", &list,
"list supported archive formats"),
OPT_GROUP(""),
OPT_STRING(0, "remote", &remote, "repo",
@@ -355,21 +355,27 @@ static int parse_archive_args(int argc, const char **argv,
base = "";
if (list) {
- for (i = 0; i < ARRAY_SIZE(archivers); i++)
- printf("%s\n", archivers[i].name);
+ for (i = 0; i < nr_archivers; i++)
+ if (!is_remote || archivers[i]->flags & ARCHIVER_REMOTE)
+ printf("%s\n", archivers[i]->name);
exit(0);
}
+ if (!format && name_hint)
+ format = archive_format_from_filename(name_hint);
+ if (!format)
+ format = "tar";
+
/* We need at least one parameter -- tree-ish */
if (argc < 1)
usage_with_options(archive_usage, opts);
*ar = lookup_archiver(format);
- if (!*ar)
+ if (!*ar || (is_remote && !((*ar)->flags & ARCHIVER_REMOTE)))
die("Unknown archive format '%s'", format);
args->compression_level = Z_DEFAULT_COMPRESSION;
if (compression_level != -1) {
- if ((*ar)->flags & USES_ZLIB_COMPRESSION)
+ if ((*ar)->flags & ARCHIVER_WANT_COMPRESSION_LEVELS)
args->compression_level = compression_level;
else {
die("Argument not supported for format '%s': -%d",
@@ -385,19 +391,55 @@ static int parse_archive_args(int argc, const char **argv,
}
int write_archive(int argc, const char **argv, const char *prefix,
- int setup_prefix)
+ int setup_prefix, const char *name_hint, int remote)
{
+ int nongit = 0;
const struct archiver *ar = NULL;
struct archiver_args args;
- argc = parse_archive_args(argc, argv, &ar, &args);
if (setup_prefix && prefix == NULL)
- prefix = setup_git_directory();
+ prefix = setup_git_directory_gently(&nongit);
+
+ git_config(git_default_config, NULL);
+ init_tar_archiver();
+ init_zip_archiver();
+
+ argc = parse_archive_args(argc, argv, &ar, &args, name_hint, remote);
+ if (nongit) {
+ /*
+ * We know this will die() with an error, so we could just
+ * die ourselves; but its error message will be more specific
+ * than what we could write here.
+ */
+ setup_git_directory();
+ }
parse_treeish_arg(argv, &args, prefix);
parse_pathspec_arg(argv + 1, &args);
- git_config(git_default_config, NULL);
+ return ar->write_archive(ar, &args);
+}
- return ar->write_archive(&args);
+static int match_extension(const char *filename, const char *ext)
+{
+ int prefixlen = strlen(filename) - strlen(ext);
+
+ /*
+ * We need 1 character for the '.', and 1 character to ensure that the
+ * prefix is non-empty (k.e., we don't match .tar.gz with no actual
+ * filename).
+ */
+ if (prefixlen < 2 || filename[prefixlen-1] != '.')
+ return 0;
+ return !strcmp(filename + prefixlen, ext);
+}
+
+const char *archive_format_from_filename(const char *filename)
+{
+ int i;
+
+ for (i = 0; i < nr_archivers; i++)
+ if (match_extension(filename, archivers[i]->name))
+ return archivers[i]->name;
+ return NULL;
}
diff --git a/archive.h b/archive.h
index 038ac35..2b0884f 100644
--- a/archive.h
+++ b/archive.h
@@ -14,17 +14,24 @@ struct archiver_args {
int compression_level;
};
-typedef int (*write_archive_fn_t)(struct archiver_args *);
+#define ARCHIVER_WANT_COMPRESSION_LEVELS 1
+#define ARCHIVER_REMOTE 2
+struct archiver {
+ const char *name;
+ int (*write_archive)(const struct archiver *, struct archiver_args *);
+ unsigned flags;
+ void *data;
+};
+extern void register_archiver(struct archiver *);
-typedef int (*write_archive_entry_fn_t)(struct archiver_args *args, const unsigned char *sha1, const char *path, size_t pathlen, unsigned int mode, void *buffer, unsigned long size);
+extern void init_tar_archiver(void);
+extern void init_zip_archiver(void);
-/*
- * Archive-format specific backends.
- */
-extern int write_tar_archive(struct archiver_args *);
-extern int write_zip_archive(struct archiver_args *);
+typedef int (*write_archive_entry_fn_t)(struct archiver_args *args, const unsigned char *sha1, const char *path, size_t pathlen, unsigned int mode, void *buffer, unsigned long size);
extern int write_archive_entries(struct archiver_args *args, write_archive_entry_fn_t write_entry);
-extern int write_archive(int argc, const char **argv, const char *prefix, int setup_prefix);
+extern int write_archive(int argc, const char **argv, const char *prefix, int setup_prefix, const char *name_hint, int remote);
+
+const char *archive_format_from_filename(const char *filename);
#endif /* ARCHIVE_H */
diff --git a/argv-array.c b/argv-array.c
new file mode 100644
index 0000000..a4e0420
--- /dev/null
+++ b/argv-array.c
@@ -0,0 +1,51 @@
+#include "cache.h"
+#include "argv-array.h"
+#include "strbuf.h"
+
+static const char *empty_argv_storage = NULL;
+const char **empty_argv = &empty_argv_storage;
+
+void argv_array_init(struct argv_array *array)
+{
+ array->argv = empty_argv;
+ array->argc = 0;
+ array->alloc = 0;
+}
+
+static void argv_array_push_nodup(struct argv_array *array, const char *value)
+{
+ if (array->argv == empty_argv)
+ array->argv = NULL;
+
+ ALLOC_GROW(array->argv, array->argc + 2, array->alloc);
+ array->argv[array->argc++] = value;
+ array->argv[array->argc] = NULL;
+}
+
+void argv_array_push(struct argv_array *array, const char *value)
+{
+ argv_array_push_nodup(array, xstrdup(value));
+}
+
+void argv_array_pushf(struct argv_array *array, const char *fmt, ...)
+{
+ va_list ap;
+ struct strbuf v = STRBUF_INIT;
+
+ va_start(ap, fmt);
+ strbuf_vaddf(&v, fmt, ap);
+ va_end(ap);
+
+ argv_array_push_nodup(array, strbuf_detach(&v, NULL));
+}
+
+void argv_array_clear(struct argv_array *array)
+{
+ if (array->argv != empty_argv) {
+ int i;
+ for (i = 0; i < array->argc; i++)
+ free((char **)array->argv[i]);
+ free(array->argv);
+ }
+ argv_array_init(array);
+}
diff --git a/argv-array.h b/argv-array.h
new file mode 100644
index 0000000..74dd2b1
--- /dev/null
+++ b/argv-array.h
@@ -0,0 +1,20 @@
+#ifndef ARGV_ARRAY_H
+#define ARGV_ARRAY_H
+
+extern const char **empty_argv;
+
+struct argv_array {
+ const char **argv;
+ int argc;
+ int alloc;
+};
+
+#define ARGV_ARRAY_INIT { empty_argv, 0, 0 }
+
+void argv_array_init(struct argv_array *);
+void argv_array_push(struct argv_array *, const char *);
+__attribute__((format (printf,2,3)))
+void argv_array_pushf(struct argv_array *, const char *fmt, ...);
+void argv_array_clear(struct argv_array *);
+
+#endif /* ARGV_ARRAY_H */
diff --git a/attr.c b/attr.c
index f6b3f7e..76b079f 100644
--- a/attr.c
+++ b/attr.c
@@ -1,7 +1,17 @@
+/*
+ * Handle git attributes. See gitattributes(5) for a description of
+ * the file syntax, and Documentation/technical/api-gitattributes.txt
+ * for a description of the API.
+ *
+ * One basic design decision here is that we are not going to support
+ * an insanely large number of attributes.
+ */
+
#define NO_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "exec_cmd.h"
#include "attr.h"
+#include "dir.h"
const char git_attr__true[] = "(builtin)true";
const char git_attr__false[] = "\0(builtin)false";
@@ -11,14 +21,7 @@ static const char git_attr__unknown[] = "(builtin)unknown";
#define ATTR__UNSET NULL
#define ATTR__UNKNOWN git_attr__unknown
-static const char *attributes_file;
-
-/*
- * The basic design decision here is that we are not going to have
- * insanely large number of attributes.
- *
- * This is a randomly chosen prime.
- */
+/* This is a randomly chosen prime. */
#define HASHSIZE 257
#ifndef DEBUG_ATTR
@@ -36,6 +39,11 @@ static int attr_nr;
static struct git_attr_check *check_all_attr;
static struct git_attr *(git_attr_hash[HASHSIZE]);
+char *git_attr_name(struct git_attr *attr)
+{
+ return attr->name;
+}
+
static unsigned hash_name(const char *name, int namelen)
{
unsigned val = 0, c;
@@ -50,12 +58,10 @@ static unsigned hash_name(const char *name, int namelen)
static int invalid_attr_name(const char *name, int namelen)
{
/*
- * Attribute name cannot begin with '-' and from
- * [-A-Za-z0-9_.]. We'd specifically exclude '=' for now,
- * as we might later want to allow non-binary value for
- * attributes, e.g. "*.svg merge=special-merge-program-for-svg"
+ * Attribute name cannot begin with '-' and must consist of
+ * characters from [-A-Za-z0-9_.].
*/
- if (*name == '-')
+ if (namelen <= 0 || *name == '-')
return -1;
while (namelen--) {
char ch = *name++;
@@ -103,22 +109,26 @@ struct git_attr *git_attr(const char *name)
return git_attr_internal(name, strlen(name));
}
-/*
- * .gitattributes file is one line per record, each of which is
- *
- * (1) glob pattern.
- * (2) whitespace
- * (3) whitespace separated list of attribute names, each of which
- * could be prefixed with '-' to mean "set to false", '!' to mean
- * "unset".
- */
-
/* What does a matched pattern decide? */
struct attr_state {
struct git_attr *attr;
const char *setto;
};
+/*
+ * One rule, as from a .gitattributes file.
+ *
+ * If is_macro is true, then u.attr is a pointer to the git_attr being
+ * defined.
+ *
+ * If is_macro is false, then u.pattern points at the filename pattern
+ * to which the rule applies. (The memory pointed to is part of the
+ * memory block allocated for the match_attr instance.)
+ *
+ * In either case, num_attr is the number of attributes affected by
+ * this rule, and state is an array listing them. The attributes are
+ * listed as they appear in the file (macros unexpanded).
+ */
struct match_attr {
union {
char *pattern;
@@ -131,8 +141,15 @@ struct match_attr {
static const char blank[] = " \t\r\n";
+/*
+ * Parse a whitespace-delimited attribute state (i.e., "attr",
+ * "-attr", "!attr", or "attr=value") from the string starting at src.
+ * If e is not NULL, write the results to *e. Return a pointer to the
+ * remainder of the string (with leading whitespace removed), or NULL
+ * if there was an error.
+ */
static const char *parse_attr(const char *src, int lineno, const char *cp,
- int *num_attr, struct match_attr *res)
+ struct attr_state *e)
{
const char *ep, *equals;
int len;
@@ -145,7 +162,7 @@ static const char *parse_attr(const char *src, int lineno, const char *cp,
len = equals - cp;
else
len = ep - cp;
- if (!res) {
+ if (!e) {
if (*cp == '-' || *cp == '!') {
cp++;
len--;
@@ -157,9 +174,6 @@ static const char *parse_attr(const char *src, int lineno, const char *cp,
return NULL;
}
} else {
- struct attr_state *e;
-
- e = &(res->state[*num_attr]);
if (*cp == '-' || *cp == '!') {
e->setto = (*cp == '-') ? ATTR__FALSE : ATTR__UNSET;
cp++;
@@ -172,7 +186,6 @@ static const char *parse_attr(const char *src, int lineno, const char *cp,
}
e->attr = git_attr_internal(cp, len);
}
- (*num_attr)++;
return ep + strspn(ep, blank);
}
@@ -180,10 +193,9 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
int lineno, int macro_ok)
{
int namelen;
- int num_attr;
- const char *cp, *name;
+ int num_attr, i;
+ const char *cp, *name, *states;
struct match_attr *res = NULL;
- int pass;
int is_macro;
cp = line + strspn(line, blank);
@@ -212,32 +224,35 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
else
is_macro = 0;
- for (pass = 0; pass < 2; pass++) {
- /* pass 0 counts and allocates, pass 1 fills */
- num_attr = 0;
- cp = name + namelen;
- cp = cp + strspn(cp, blank);
- while (*cp) {
- cp = parse_attr(src, lineno, cp, &num_attr, res);
- if (!cp)
- return NULL;
- }
- if (pass)
- break;
- res = xcalloc(1,
- sizeof(*res) +
- sizeof(struct attr_state) * num_attr +
- (is_macro ? 0 : namelen + 1));
- if (is_macro)
- res->u.attr = git_attr_internal(name, namelen);
- else {
- res->u.pattern = (char *)&(res->state[num_attr]);
- memcpy(res->u.pattern, name, namelen);
- res->u.pattern[namelen] = 0;
- }
- res->is_macro = is_macro;
- res->num_attr = num_attr;
+ states = name + namelen;
+ states += strspn(states, blank);
+
+ /* First pass to count the attr_states */
+ for (cp = states, num_attr = 0; *cp; num_attr++) {
+ cp = parse_attr(src, lineno, cp, NULL);
+ if (!cp)
+ return NULL;
}
+
+ res = xcalloc(1,
+ sizeof(*res) +
+ sizeof(struct attr_state) * num_attr +
+ (is_macro ? 0 : namelen + 1));
+ if (is_macro)
+ res->u.attr = git_attr_internal(name, namelen);
+ else {
+ res->u.pattern = (char *)&(res->state[num_attr]);
+ memcpy(res->u.pattern, name, namelen);
+ res->u.pattern[namelen] = 0;
+ }
+ res->is_macro = is_macro;
+ res->num_attr = num_attr;
+
+ /* Second pass to fill the attr_states */
+ for (cp = states, i = 0; *cp; i++) {
+ cp = parse_attr(src, lineno, cp, &(res->state[i]));
+ }
+
return res;
}
@@ -478,14 +493,6 @@ static int git_attr_system(void)
return !git_env_bool("GIT_ATTR_NOSYSTEM", 0);
}
-static int git_attr_config(const char *var, const char *value, void *dummy)
-{
- if (!strcmp(var, "core.attributesfile"))
- return git_config_pathname(&attributes_file, var, value);
-
- return 0;
-}
-
static void bootstrap_attr_stack(void)
{
if (!attr_stack) {
@@ -505,9 +512,8 @@ static void bootstrap_attr_stack(void)
}
}
- git_config(git_attr_config, NULL);
- if (attributes_file) {
- elem = read_attr_from_file(attributes_file, 1);
+ if (git_attributes_file) {
+ elem = read_attr_from_file(git_attributes_file, 1);
if (elem) {
elem->origin = NULL;
elem->prev = attr_stack;
@@ -517,7 +523,7 @@ static void bootstrap_attr_stack(void)
if (!is_bare_repository() || direction == GIT_ATTR_INDEX) {
elem = read_attr(GITATTRIBUTES_FILE, 1);
- elem->origin = strdup("");
+ elem->origin = xstrdup("");
elem->prev = attr_stack;
attr_stack = elem;
debug_push(elem);
@@ -532,13 +538,17 @@ static void bootstrap_attr_stack(void)
}
}
-static void prepare_attr_stack(const char *path, int dirlen)
+static void prepare_attr_stack(const char *path)
{
struct attr_stack *elem, *info;
- int len;
- struct strbuf pathbuf;
+ int dirlen, len;
+ const char *cp;
- strbuf_init(&pathbuf, dirlen+2+strlen(GITATTRIBUTES_FILE));
+ cp = strrchr(path, '/');
+ if (!cp)
+ dirlen = 0;
+ else
+ dirlen = cp - path;
/*
* At the bottom of the attribute stack is the built-in
@@ -555,8 +565,7 @@ static void prepare_attr_stack(const char *path, int dirlen)
* .gitattributes in deeper directories to shallower ones,
* and finally use the built-in set as the default.
*/
- if (!attr_stack)
- bootstrap_attr_stack();
+ bootstrap_attr_stack();
/*
* Pop the "info" one that is always at the top of the stack.
@@ -585,27 +594,28 @@ static void prepare_attr_stack(const char *path, int dirlen)
* Read from parent directories and push them down
*/
if (!is_bare_repository() || direction == GIT_ATTR_INDEX) {
- while (1) {
- char *cp;
+ struct strbuf pathbuf = STRBUF_INIT;
+ while (1) {
len = strlen(attr_stack->origin);
if (dirlen <= len)
break;
- strbuf_reset(&pathbuf);
- strbuf_add(&pathbuf, path, dirlen);
+ cp = memchr(path + len + 1, '/', dirlen - len - 1);
+ if (!cp)
+ cp = path + dirlen;
+ strbuf_add(&pathbuf, path, cp - path);
strbuf_addch(&pathbuf, '/');
- cp = strchr(pathbuf.buf + len + 1, '/');
- strcpy(cp + 1, GITATTRIBUTES_FILE);
+ strbuf_addstr(&pathbuf, GITATTRIBUTES_FILE);
elem = read_attr(pathbuf.buf, 0);
- *cp = '\0';
- elem->origin = strdup(pathbuf.buf);
+ strbuf_setlen(&pathbuf, cp - path);
+ elem->origin = strbuf_detach(&pathbuf, NULL);
elem->prev = attr_stack;
attr_stack = elem;
debug_push(elem);
}
- }
- strbuf_release(&pathbuf);
+ strbuf_release(&pathbuf);
+ }
/*
* Finally push the "info" one at the top of the stack.
@@ -622,7 +632,7 @@ static int path_matches(const char *pathname, int pathlen,
/* match basename */
const char *basename = strrchr(pathname, '/');
basename = basename ? basename + 1 : pathname;
- return (fnmatch(pattern, basename, 0) == 0);
+ return (fnmatch_icase(pattern, basename, 0) == 0);
}
/*
* match with FNM_PATHNAME; the pattern has base implicitly
@@ -636,7 +646,7 @@ static int path_matches(const char *pathname, int pathlen,
return 0;
if (baselen != 0)
baselen++;
- return fnmatch(pattern, pathname + baselen, FNM_PATHNAME) == 0;
+ return fnmatch_icase(pattern, pathname + baselen, FNM_PATHNAME) == 0;
}
static int macroexpand_one(int attr_nr, int rem);
@@ -703,26 +713,30 @@ static int macroexpand_one(int attr_nr, int rem)
return rem;
}
-int git_checkattr(const char *path, int num, struct git_attr_check *check)
+/*
+ * Collect all attributes for path into the array pointed to by
+ * check_all_attr.
+ */
+static void collect_all_attrs(const char *path)
{
struct attr_stack *stk;
- const char *cp;
- int dirlen, pathlen, i, rem;
+ int i, pathlen, rem;
- bootstrap_attr_stack();
+ prepare_attr_stack(path);
for (i = 0; i < attr_nr; i++)
check_all_attr[i].value = ATTR__UNKNOWN;
pathlen = strlen(path);
- cp = strrchr(path, '/');
- if (!cp)
- dirlen = 0;
- else
- dirlen = cp - path;
- prepare_attr_stack(path, dirlen);
rem = attr_nr;
for (stk = attr_stack; 0 < rem && stk; stk = stk->prev)
rem = fill(path, pathlen, stk, rem);
+}
+
+int git_check_attr(const char *path, int num, struct git_attr_check *check)
+{
+ int i;
+
+ collect_all_attrs(path);
for (i = 0; i < num; i++) {
const char *value = check_all_attr[check[i].attr->attr_nr].value;
@@ -734,6 +748,34 @@ int git_checkattr(const char *path, int num, struct git_attr_check *check)
return 0;
}
+int git_all_attrs(const char *path, int *num, struct git_attr_check **check)
+{
+ int i, count, j;
+
+ collect_all_attrs(path);
+
+ /* Count the number of attributes that are set. */
+ count = 0;
+ for (i = 0; i < attr_nr; i++) {
+ const char *value = check_all_attr[i].value;
+ if (value != ATTR__UNSET && value != ATTR__UNKNOWN)
+ ++count;
+ }
+ *num = count;
+ *check = xmalloc(sizeof(**check) * count);
+ j = 0;
+ for (i = 0; i < attr_nr; i++) {
+ const char *value = check_all_attr[i].value;
+ if (value != ATTR__UNSET && value != ATTR__UNKNOWN) {
+ (*check)[j].attr = check_all_attr[i].attr;
+ (*check)[j].value = value;
+ ++j;
+ }
+ }
+
+ return 0;
+}
+
void git_attr_set_direction(enum git_attr_direction new, struct index_state *istate)
{
enum git_attr_direction old = direction;
diff --git a/attr.h b/attr.h
index 8b3f19b..eb8ca0d 100644
--- a/attr.h
+++ b/attr.h
@@ -20,7 +20,7 @@ extern const char git_attr__false[];
#define ATTR_UNSET(v) ((v) == NULL)
/*
- * Send one or more git_attr_check to git_checkattr(), and
+ * Send one or more git_attr_check to git_check_attr(), and
* each 'value' member tells what its value is.
* Unset one is returned as NULL.
*/
@@ -29,7 +29,23 @@ struct git_attr_check {
const char *value;
};
-int git_checkattr(const char *path, int, struct git_attr_check *);
+/*
+ * Return the name of the attribute represented by the argument. The
+ * return value is a pointer to a null-delimited string that is part
+ * of the internal data structure; it should not be modified or freed.
+ */
+char *git_attr_name(struct git_attr *);
+
+int git_check_attr(const char *path, int, struct git_attr_check *);
+
+/*
+ * Retrieve all attributes that apply to the specified path. *num
+ * will be set the the number of attributes on the path; **check will
+ * be set to point at a newly-allocated array of git_attr_check
+ * objects describing the attributes and their values. *check must be
+ * free()ed by the caller.
+ */
+int git_all_attrs(const char *path, int *num, struct git_attr_check **check);
enum git_attr_direction {
GIT_ATTR_CHECKIN,
diff --git a/bisect.c b/bisect.c
index dd7e8ed..6e186e2 100644
--- a/bisect.c
+++ b/bisect.c
@@ -10,20 +10,16 @@
#include "log-tree.h"
#include "bisect.h"
#include "sha1-array.h"
+#include "argv-array.h"
static struct sha1_array good_revs;
static struct sha1_array skipped_revs;
static const unsigned char *current_bad_sha1;
-struct argv_array {
- const char **argv;
- int argv_nr;
- int argv_alloc;
-};
-
static const char *argv_checkout[] = {"checkout", "-q", NULL, "--", NULL};
static const char *argv_show_branch[] = {"show-branch", NULL, NULL};
+static const char *argv_update_ref[] = {"update-ref", "--no-deref", "BISECT_HEAD", NULL, NULL};
/* bits #0-15 in revision.h */
@@ -404,21 +400,6 @@ struct commit_list *find_bisection(struct commit_list *list,
return best;
}
-static void argv_array_push(struct argv_array *array, const char *string)
-{
- ALLOC_GROW(array->argv, array->argv_nr + 1, array->argv_alloc);
- array->argv[array->argv_nr++] = string;
-}
-
-static void argv_array_push_sha1(struct argv_array *array,
- const unsigned char *sha1,
- const char *format)
-{
- struct strbuf buf = STRBUF_INIT;
- strbuf_addf(&buf, format, sha1_to_hex(sha1));
- argv_array_push(array, strbuf_detach(&buf, NULL));
-}
-
static int register_ref(const char *refname, const unsigned char *sha1,
int flags, void *cb_data)
{
@@ -448,16 +429,10 @@ static void read_bisect_paths(struct argv_array *array)
die_errno("Could not open file '%s'", filename);
while (strbuf_getline(&str, fp, '\n') != EOF) {
- char *quoted;
- int res;
-
strbuf_trim(&str);
- quoted = strbuf_detach(&str, NULL);
- res = sq_dequote_to_argv(quoted, &array->argv,
- &array->argv_nr, &array->argv_alloc);
- if (res)
+ if (sq_dequote_to_argv_array(str.buf, array))
die("Badly quoted content in file '%s': %s",
- filename, quoted);
+ filename, str.buf);
}
strbuf_release(&str);
@@ -622,7 +597,7 @@ static void bisect_rev_setup(struct rev_info *revs, const char *prefix,
const char *bad_format, const char *good_format,
int read_paths)
{
- struct argv_array rev_argv = { NULL, 0, 0 };
+ struct argv_array rev_argv = ARGV_ARRAY_INIT;
int i;
init_revisions(revs, prefix);
@@ -630,17 +605,17 @@ static void bisect_rev_setup(struct rev_info *revs, const char *prefix,
revs->commit_format = CMIT_FMT_UNSPECIFIED;
/* rev_argv.argv[0] will be ignored by setup_revisions */
- argv_array_push(&rev_argv, xstrdup("bisect_rev_setup"));
- argv_array_push_sha1(&rev_argv, current_bad_sha1, bad_format);
+ argv_array_push(&rev_argv, "bisect_rev_setup");
+ argv_array_pushf(&rev_argv, bad_format, sha1_to_hex(current_bad_sha1));
for (i = 0; i < good_revs.nr; i++)
- argv_array_push_sha1(&rev_argv, good_revs.sha1[i],
- good_format);
- argv_array_push(&rev_argv, xstrdup("--"));
+ argv_array_pushf(&rev_argv, good_format,
+ sha1_to_hex(good_revs.sha1[i]));
+ argv_array_push(&rev_argv, "--");
if (read_paths)
read_bisect_paths(&rev_argv);
- argv_array_push(&rev_argv, NULL);
- setup_revisions(rev_argv.argv_nr, rev_argv.argv, revs, NULL);
+ setup_revisions(rev_argv.argc, rev_argv.argv, revs, NULL);
+ /* XXX leak rev_argv, as "revs" may still be pointing to it */
}
static void bisect_common(struct rev_info *revs)
@@ -707,16 +682,23 @@ static void mark_expected_rev(char *bisect_rev_hex)
die("closing file %s: %s", filename, strerror(errno));
}
-static int bisect_checkout(char *bisect_rev_hex)
+static int bisect_checkout(char *bisect_rev_hex, int no_checkout)
{
int res;
mark_expected_rev(bisect_rev_hex);
argv_checkout[2] = bisect_rev_hex;
- res = run_command_v_opt(argv_checkout, RUN_GIT_CMD);
- if (res)
- exit(res);
+ if (no_checkout) {
+ argv_update_ref[3] = bisect_rev_hex;
+ if (run_command_v_opt(argv_update_ref, RUN_GIT_CMD))
+ die("update-ref --no-deref HEAD failed on %s",
+ bisect_rev_hex);
+ } else {
+ res = run_command_v_opt(argv_checkout, RUN_GIT_CMD);
+ if (res)
+ exit(res);
+ }
argv_show_branch[1] = bisect_rev_hex;
return run_command_v_opt(argv_show_branch, RUN_GIT_CMD);
@@ -788,7 +770,7 @@ static void handle_skipped_merge_base(const unsigned char *mb)
* - If one is "skipped", we can't know but we should warn.
* - If we don't know, we should check it out and ask the user to test.
*/
-static void check_merge_bases(void)
+static void check_merge_bases(int no_checkout)
{
struct commit_list *result;
int rev_nr;
@@ -806,7 +788,7 @@ static void check_merge_bases(void)
handle_skipped_merge_base(mb);
} else {
printf("Bisecting: a merge base must be tested\n");
- exit(bisect_checkout(sha1_to_hex(mb)));
+ exit(bisect_checkout(sha1_to_hex(mb), no_checkout));
}
}
@@ -818,25 +800,25 @@ static int check_ancestors(const char *prefix)
{
struct rev_info revs;
struct object_array pending_copy;
- int i, res;
+ int res;
bisect_rev_setup(&revs, prefix, "^%s", "%s", 0);
/* Save pending objects, so they can be cleaned up later. */
- memset(&pending_copy, 0, sizeof(pending_copy));
- for (i = 0; i < revs.pending.nr; i++)
- add_object_array(revs.pending.objects[i].item,
- revs.pending.objects[i].name,
- &pending_copy);
+ pending_copy = revs.pending;
+ revs.leak_pending = 1;
+ /*
+ * bisect_common calls prepare_revision_walk right away, which
+ * (together with .leak_pending = 1) makes us the sole owner of
+ * the list of pending objects.
+ */
bisect_common(&revs);
res = (revs.commits != NULL);
/* Clean up objects used, as they will be reused. */
- for (i = 0; i < pending_copy.nr; i++) {
- struct object *o = pending_copy.objects[i].item;
- clear_commit_marks((struct commit *)o, ALL_REV_FLAGS);
- }
+ clear_commit_marks_for_object_array(&pending_copy, ALL_REV_FLAGS);
+ free(pending_copy.objects);
return res;
}
@@ -849,7 +831,7 @@ static int check_ancestors(const char *prefix)
* If a merge base must be tested by the user, its source code will be
* checked out to be tested by the user and we will exit.
*/
-static void check_good_are_ancestors_of_bad(const char *prefix)
+static void check_good_are_ancestors_of_bad(const char *prefix, int no_checkout)
{
const char *filename = git_path("BISECT_ANCESTORS_OK");
struct stat st;
@@ -868,7 +850,7 @@ static void check_good_are_ancestors_of_bad(const char *prefix)
/* Check if all good revs are ancestor of the bad rev. */
if (check_ancestors(prefix))
- check_merge_bases();
+ check_merge_bases(no_checkout);
/* Create file BISECT_ANCESTORS_OK. */
fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0600);
@@ -908,8 +890,11 @@ static void show_diff_tree(const char *prefix, struct commit *commit)
* We use the convention that exiting with an exit code 10 means that
* the bisection process finished successfully.
* In this case the calling shell script should exit 0.
+ *
+ * If no_checkout is non-zero, the bisection process does not
+ * checkout the trial commit but instead simply updates BISECT_HEAD.
*/
-int bisect_next_all(const char *prefix)
+int bisect_next_all(const char *prefix, int no_checkout)
{
struct rev_info revs;
struct commit_list *tried;
@@ -920,7 +905,7 @@ int bisect_next_all(const char *prefix)
if (read_bisect_refs())
die("reading bisect refs failed");
- check_good_are_ancestors_of_bad(prefix);
+ check_good_are_ancestors_of_bad(prefix, no_checkout);
bisect_rev_setup(&revs, prefix, "%s", "^%s", 1);
revs.limited = 1;
@@ -966,6 +951,6 @@ int bisect_next_all(const char *prefix)
"(roughly %d step%s)\n", nr, (nr == 1 ? "" : "s"),
steps, (steps == 1 ? "" : "s"));
- return bisect_checkout(bisect_rev_hex);
+ return bisect_checkout(bisect_rev_hex, no_checkout);
}
diff --git a/bisect.h b/bisect.h
index 0862ce5..22f2e4d 100644
--- a/bisect.h
+++ b/bisect.h
@@ -27,7 +27,7 @@ struct rev_list_info {
const char *header_prefix;
};
-extern int bisect_next_all(const char *prefix);
+extern int bisect_next_all(const char *prefix, int no_checkout);
extern int estimate_bisect_steps(int all);
diff --git a/branch.c b/branch.c
index c0c865a..025a97b 100644
--- a/branch.c
+++ b/branch.c
@@ -3,6 +3,7 @@
#include "refs.h"
#include "remote.h"
#include "commit.h"
+#include "sequencer.h"
struct tracking {
struct refspec spec;
@@ -135,6 +136,28 @@ static int setup_tracking(const char *new_ref, const char *orig_ref,
return 0;
}
+int validate_new_branchname(const char *name, struct strbuf *ref,
+ int force, int attr_only)
+{
+ if (strbuf_check_branch_ref(ref, name))
+ die("'%s' is not a valid branch name.", name);
+
+ if (!ref_exists(ref->buf))
+ return 0;
+ else if (!force && !attr_only)
+ die("A branch named '%s' already exists.", ref->buf + strlen("refs/heads/"));
+
+ if (!attr_only) {
+ const char *head;
+ unsigned char sha1[20];
+
+ head = resolve_ref("HEAD", sha1, 0, NULL);
+ if (!is_bare_repository() && head && !strcmp(head, ref->buf))
+ die("Cannot force update the current branch.");
+ }
+ return 1;
+}
+
void create_branch(const char *head,
const char *name, const char *start_name,
int force, int reflog, enum branch_track track)
@@ -151,17 +174,12 @@ void create_branch(const char *head,
if (track == BRANCH_TRACK_EXPLICIT || track == BRANCH_TRACK_OVERRIDE)
explicit_tracking = 1;
- if (strbuf_check_branch_ref(&ref, name))
- die("'%s' is not a valid branch name.", name);
-
- if (resolve_ref(ref.buf, sha1, 1, NULL)) {
- if (!force && track == BRANCH_TRACK_OVERRIDE)
+ if (validate_new_branchname(name, &ref, force,
+ track == BRANCH_TRACK_OVERRIDE)) {
+ if (!force)
dont_change_ref = 1;
- else if (!force)
- die("A branch named '%s' already exists.", name);
- else if (!is_bare_repository() && head && !strcmp(head, name))
- die("Cannot force update the current branch.");
- forcing = 1;
+ else
+ forcing = 1;
}
real_ref = NULL;
@@ -210,7 +228,7 @@ void create_branch(const char *head,
start_name);
if (real_ref && track)
- setup_tracking(name, real_ref, track);
+ setup_tracking(ref.buf+11, real_ref, track);
if (!dont_change_ref)
if (write_ref_sha1(lock, sha1, msg) < 0)
@@ -223,9 +241,11 @@ void create_branch(const char *head,
void remove_branch_state(void)
{
unlink(git_path("CHERRY_PICK_HEAD"));
+ unlink(git_path("REVERT_HEAD"));
unlink(git_path("MERGE_HEAD"));
unlink(git_path("MERGE_RR"));
unlink(git_path("MERGE_MSG"));
unlink(git_path("MERGE_MODE"));
unlink(git_path("SQUASH_MSG"));
+ remove_sequencer_state(0);
}
diff --git a/branch.h b/branch.h
index 4026e38..1285158 100644
--- a/branch.h
+++ b/branch.h
@@ -16,6 +16,24 @@ void create_branch(const char *head, const char *name, const char *start_name,
int force, int reflog, enum branch_track track);
/*
+ * Validates that the requested branch may be created, returning the
+ * interpreted ref in ref, force indicates whether (non-head) branches
+ * may be overwritten. A non-zero return value indicates that the force
+ * parameter was non-zero and the branch already exists.
+ *
+ * Contrary to all of the above, when attr_only is 1, the caller is
+ * not interested in verifying if it is Ok to update the named
+ * branch to point at a potentially different commit. It is merely
+ * asking if it is OK to change some attribute for the named branch
+ * (e.g. tracking upstream).
+ *
+ * NEEDSWORK: This needs to be split into two separate functions in the
+ * longer run for sanity.
+ *
+ */
+int validate_new_branchname(const char *name, struct strbuf *ref, int force, int attr_only);
+
+/*
* Remove information about the state of working on the current
* branch. (E.g., MERGE_HEAD)
*/
diff --git a/builtin/apply.c b/builtin/apply.c
index 530d4bb..b3b59db 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -250,9 +250,6 @@ static int fuzzy_matchlines(const char *s1, size_t n1,
const char *last2 = s2 + n2 - 1;
int result = 0;
- if (n1 < 0 || n2 < 0)
- return 0;
-
/* ignore line endings */
while ((*last1 == '\r') || (*last1 == '\n'))
last1--;
@@ -1407,6 +1404,9 @@ static int find_header(char *line, unsigned long size, int *hdrsize, struct patc
"%d leading pathname components (line %d)" , p_value, linenr);
patch->old_name = patch->new_name = patch->def_name;
}
+ if (!patch->is_delete && !patch->new_name)
+ die("git diff header lacks filename information "
+ "(line %d)", linenr);
patch->is_toplevel_relative = 1;
*hdrsize = git_hdr_len;
return offset;
@@ -1634,7 +1634,7 @@ static inline int metadata_changes(struct patch *patch)
static char *inflate_it(const void *data, unsigned long size,
unsigned long inflated_size)
{
- z_stream stream;
+ git_zstream stream;
void *out;
int st;
@@ -2447,6 +2447,8 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
char *old, *oldlines;
struct strbuf newlines;
int new_blank_lines_at_end = 0;
+ int found_new_blank_lines_at_end = 0;
+ int hunk_linenr = frag->linenr;
unsigned long leading, trailing;
int pos, applied_pos;
struct image preimage;
@@ -2540,14 +2542,18 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
error("invalid start of line: '%c'", first);
return -1;
}
- if (added_blank_line)
+ if (added_blank_line) {
+ if (!new_blank_lines_at_end)
+ found_new_blank_lines_at_end = hunk_linenr;
new_blank_lines_at_end++;
+ }
else if (is_blank_context)
;
else
new_blank_lines_at_end = 0;
patch += len;
size -= len;
+ hunk_linenr++;
}
if (inaccurate_eof &&
old > oldlines && old[-1] == '\n' &&
@@ -2629,7 +2635,8 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
preimage.nr + applied_pos >= img->nr &&
(ws_rule & WS_BLANK_AT_EOF) &&
ws_error_action != nowarn_ws_error) {
- record_ws_error(WS_BLANK_AT_EOF, "+", 1, frag->linenr);
+ record_ws_error(WS_BLANK_AT_EOF, "+", 1,
+ found_new_blank_lines_at_end);
if (ws_error_action == correct_ws_error) {
while (new_blank_lines_at_end--)
remove_last_line(&postimage);
@@ -3831,7 +3838,6 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)
int i;
int errs = 0;
int is_not_gitdir = !startup_info->have_repository;
- int binary;
int force_apply = 0;
const char *whitespace_option = NULL;
@@ -3850,12 +3856,8 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)
"ignore additions made by the patch"),
OPT_BOOLEAN(0, "stat", &diffstat,
"instead of applying the patch, output diffstat for the input"),
- { OPTION_BOOLEAN, 0, "allow-binary-replacement", &binary,
- NULL, "old option, now no-op",
- PARSE_OPT_HIDDEN | PARSE_OPT_NOARG },
- { OPTION_BOOLEAN, 0, "binary", &binary,
- NULL, "old option, now no-op",
- PARSE_OPT_HIDDEN | PARSE_OPT_NOARG },
+ OPT_NOOP_NOARG(0, "allow-binary-replacement"),
+ OPT_NOOP_NOARG(0, "binary"),
OPT_BOOLEAN(0, "numstat", &numstat,
"shows number of added and deleted lines in decimal notation"),
OPT_BOOLEAN(0, "summary", &summary,
diff --git a/builtin/archive.c b/builtin/archive.c
index b14eaba..931956d 100644
--- a/builtin/archive.c
+++ b/builtin/archive.c
@@ -24,7 +24,8 @@ static void create_output_file(const char *output_file)
}
static int run_remote_archiver(int argc, const char **argv,
- const char *remote, const char *exec)
+ const char *remote, const char *exec,
+ const char *name_hint)
{
char buf[LARGE_PACKET_MAX];
int fd[2], i, len, rv;
@@ -37,6 +38,17 @@ static int run_remote_archiver(int argc, const char **argv,
transport = transport_get(_remote, _remote->url[0]);
transport_connect(transport, "git-upload-archive", exec, fd);
+ /*
+ * Inject a fake --format field at the beginning of the
+ * arguments, with the format inferred from our output
+ * filename. This way explicit --format options can override
+ * it.
+ */
+ if (name_hint) {
+ const char *format = archive_format_from_filename(name_hint);
+ if (format)
+ packet_write(fd[1], "argument --format=%s\n", format);
+ }
for (i = 1; i < argc; i++)
packet_write(fd[1], "argument %s\n", argv[i]);
packet_flush(fd[1]);
@@ -49,6 +61,8 @@ static int run_remote_archiver(int argc, const char **argv,
if (strcmp(buf, "ACK")) {
if (len > 5 && !prefixcmp(buf, "NACK "))
die(_("git archive: NACK %s"), buf + 5);
+ if (len > 4 && !prefixcmp(buf, "ERR "))
+ die(_("remote error: %s"), buf + 4);
die(_("git archive: protocol error"));
}
@@ -63,17 +77,6 @@ static int run_remote_archiver(int argc, const char **argv,
return !!rv;
}
-static const char *format_from_name(const char *filename)
-{
- const char *ext = strrchr(filename, '.');
- if (!ext)
- return NULL;
- ext++;
- if (!strcasecmp(ext, "zip"))
- return "--format=zip";
- return NULL;
-}
-
#define PARSE_OPT_KEEP_ALL ( PARSE_OPT_KEEP_DASHDASH | \
PARSE_OPT_KEEP_ARGV0 | \
PARSE_OPT_KEEP_UNKNOWN | \
@@ -84,7 +87,6 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
const char *exec = "git-upload-archive";
const char *output = NULL;
const char *remote = NULL;
- const char *format_option = NULL;
struct option local_opts[] = {
OPT_STRING('o', "output", &output, "file",
"write the archive to this file"),
@@ -98,32 +100,13 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix, local_opts, NULL,
PARSE_OPT_KEEP_ALL);
- if (output) {
+ if (output)
create_output_file(output);
- format_option = format_from_name(output);
- }
-
- /*
- * We have enough room in argv[] to muck it in place, because
- * --output must have been given on the original command line
- * if we get to this point, and parse_options() must have eaten
- * it, i.e. we can add back one element to the array.
- *
- * We add a fake --format option at the beginning, with the
- * format inferred from our output filename. This way explicit
- * --format options can override it, and the fake option is
- * inserted before any "--" that might have been given.
- */
- if (format_option) {
- memmove(argv + 2, argv + 1, sizeof(*argv) * argc);
- argv[1] = format_option;
- argv[++argc] = NULL;
- }
if (remote)
- return run_remote_archiver(argc, argv, remote, exec);
+ return run_remote_archiver(argc, argv, remote, exec, output);
setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
- return write_archive(argc, argv, prefix, 1);
+ return write_archive(argc, argv, prefix, 1, output, 0);
}
diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c
index 5b22639..8d325a5 100644
--- a/builtin/bisect--helper.c
+++ b/builtin/bisect--helper.c
@@ -4,16 +4,19 @@
#include "bisect.h"
static const char * const git_bisect_helper_usage[] = {
- "git bisect--helper --next-all",
+ "git bisect--helper --next-all [--no-checkout]",
NULL
};
int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
{
int next_all = 0;
+ int no_checkout = 0;
struct option options[] = {
OPT_BOOLEAN(0, "next-all", &next_all,
"perform 'git bisect next'"),
+ OPT_BOOLEAN(0, "no-checkout", &no_checkout,
+ "update BISECT_HEAD instead of checking out the current commit"),
OPT_END()
};
@@ -24,5 +27,5 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
usage_with_options(git_bisect_helper_usage, options);
/* next-all */
- return bisect_next_all(prefix);
+ return bisect_next_all(prefix, no_checkout);
}
diff --git a/builtin/blame.c b/builtin/blame.c
index 26a5d42..80febbe 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -2096,6 +2096,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
if (!contents_from || strcmp("-", contents_from)) {
struct stat st;
const char *read_from;
+ char *buf_ptr;
unsigned long buf_len;
if (contents_from) {
@@ -2113,8 +2114,8 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
switch (st.st_mode & S_IFMT) {
case S_IFREG:
if (DIFF_OPT_TST(opt, ALLOW_TEXTCONV) &&
- textconv_object(read_from, mode, null_sha1, &buf.buf, &buf_len))
- buf.len = buf_len;
+ textconv_object(read_from, mode, null_sha1, &buf_ptr, &buf_len))
+ strbuf_attach(&buf, buf_ptr, buf_len, buf_len + 1);
else if (strbuf_read_file(&buf, read_from, st.st_size) != st.st_size)
die_errno("cannot open or read '%s'", read_from);
break;
diff --git a/builtin/branch.c b/builtin/branch.c
index d6ab93b..55cad76 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -19,7 +19,7 @@
static const char * const builtin_branch_usage[] = {
"git branch [options] [-r | -a] [--merged | --no-merged]",
"git branch [options] [-l] [-f] <branchname> [<start-point>]",
- "git branch [options] [-r] (-d | -D) <branchname>",
+ "git branch [options] [-r] (-d | -D) <branchname>...",
"git branch [options] (-m | -M) [<oldbranch>] <newbranch>",
NULL
};
@@ -71,7 +71,7 @@ static int parse_branch_color_slot(const char *var, int ofs)
static int git_branch_config(const char *var, const char *value, void *cb)
{
if (!strcmp(var, "color.branch")) {
- branch_use_color = git_config_colorbool(var, value, -1);
+ branch_use_color = git_config_colorbool(var, value);
return 0;
}
if (!prefixcmp(var, "color.branch.")) {
@@ -88,7 +88,7 @@ static int git_branch_config(const char *var, const char *value, void *cb)
static const char *branch_get_color(enum color_branch ix)
{
- if (branch_use_color > 0)
+ if (want_color(branch_use_color))
return branch_colors[ix];
return "";
}
@@ -260,9 +260,22 @@ static char *resolve_symref(const char *src, const char *prefix)
struct append_ref_cb {
struct ref_list *ref_list;
+ const char **pattern;
int ret;
};
+static int match_patterns(const char **pattern, const char *refname)
+{
+ if (!*pattern)
+ return 1; /* no pattern always matches */
+ while (*pattern) {
+ if (!fnmatch(*pattern, refname, 0))
+ return 1;
+ pattern++;
+ }
+ return 0;
+}
+
static int append_ref(const char *refname, const unsigned char *sha1, int flags, void *cb_data)
{
struct append_ref_cb *cb = (struct append_ref_cb *)(cb_data);
@@ -297,6 +310,9 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,
if ((kind & ref_list->kinds) == 0)
return 0;
+ if (!match_patterns(cb->pattern, refname))
+ return 0;
+
commit = NULL;
if (ref_list->verbose || ref_list->with_commit || merge_filter != NO_FILTER) {
commit = lookup_commit_reference_gently(sha1, 1);
@@ -492,7 +508,7 @@ static void show_detached(struct ref_list *ref_list)
}
}
-static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit)
+static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit, const char **pattern)
{
int i;
struct append_ref_cb cb;
@@ -506,6 +522,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru
if (merge_filter != NO_FILTER)
init_revisions(&ref_list.revs, NULL);
cb.ref_list = &ref_list;
+ cb.pattern = pattern;
cb.ret = 0;
for_each_rawref(append_ref, &cb);
if (merge_filter != NO_FILTER) {
@@ -523,7 +540,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru
qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp);
detached = (detached && (kinds & REF_LOCAL_BRANCH));
- if (detached)
+ if (detached && match_patterns(pattern, "HEAD"))
show_detached(&ref_list);
for (i = 0; i < ref_list.index; i++) {
@@ -566,11 +583,7 @@ static void rename_branch(const char *oldname, const char *newname, int force)
die(_("Invalid branch name: '%s'"), oldname);
}
- if (strbuf_check_branch_ref(&newref, newname))
- die(_("Invalid branch name: '%s'"), newname);
-
- if (resolve_ref(newref.buf, sha1, 1, NULL) && !force)
- die(_("A branch named '%s' already exists."), newref.buf + 11);
+ validate_new_branchname(newname, &newref, force, 0);
strbuf_addf(&logmsg, "Branch: renamed %s to %s",
oldref.buf, newref.buf);
@@ -612,8 +625,8 @@ static int opt_parse_merge_filter(const struct option *opt, const char *arg, int
int cmd_branch(int argc, const char **argv, const char *prefix)
{
- int delete = 0, rename = 0, force_create = 0;
- int verbose = 0, abbrev = DEFAULT_ABBREV, detached = 0;
+ int delete = 0, rename = 0, force_create = 0, list = 0;
+ int verbose = 0, abbrev = -1, detached = 0;
int reflog = 0;
enum branch_track track;
int kinds = REF_LOCAL_BRANCH;
@@ -628,7 +641,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
OPT_SET_INT( 0, "set-upstream", &track, "change upstream info",
BRANCH_TRACK_OVERRIDE),
OPT__COLOR(&branch_use_color, "use colored output"),
- OPT_SET_INT('r', NULL, &kinds, "act on remote-tracking branches",
+ OPT_SET_INT('r', "remotes", &kinds, "act on remote-tracking branches",
REF_REMOTE_BRANCH),
{
OPTION_CALLBACK, 0, "contains", &with_commit, "commit",
@@ -645,13 +658,14 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
OPT__ABBREV(&abbrev),
OPT_GROUP("Specific git-branch actions:"),
- OPT_SET_INT('a', NULL, &kinds, "list both remote-tracking and local branches",
+ OPT_SET_INT('a', "all", &kinds, "list both remote-tracking and local branches",
REF_REMOTE_BRANCH | REF_LOCAL_BRANCH),
- OPT_BIT('d', NULL, &delete, "delete fully merged branch", 1),
+ OPT_BIT('d', "delete", &delete, "delete fully merged branch", 1),
OPT_BIT('D', NULL, &delete, "delete branch (even if not merged)", 2),
- OPT_BIT('m', NULL, &rename, "move/rename a branch and its reflog", 1),
+ OPT_BIT('m', "move", &rename, "move/rename a branch and its reflog", 1),
OPT_BIT('M', NULL, &rename, "move/rename a branch, even if target exists", 2),
- OPT_BOOLEAN('l', NULL, &reflog, "create the branch's reflog"),
+ OPT_BOOLEAN(0, "list", &list, "list branch names"),
+ OPT_BOOLEAN('l', "create-reflog", &reflog, "create the branch's reflog"),
OPT__FORCE(&force_create, "force creation (when already exists)"),
{
OPTION_CALLBACK, 0, "no-merged", &merge_filter_ref,
@@ -673,9 +687,6 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
git_config(git_branch_config, NULL);
- if (branch_use_color == -1)
- branch_use_color = git_use_color_default;
-
track = git_branch_track;
head = resolve_ref("HEAD", head_sha1, 0, NULL);
@@ -693,18 +704,29 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix, options, builtin_branch_usage,
0);
- if (!!delete + !!rename + !!force_create > 1)
+
+ if (!delete && !rename && argc == 0)
+ list = 1;
+
+ if (!!delete + !!rename + !!force_create + !!list > 1)
usage_with_options(builtin_branch_usage, options);
+ if (abbrev == -1)
+ abbrev = DEFAULT_ABBREV;
+
if (delete)
return delete_branches(argc, argv, delete > 1, kinds);
- else if (argc == 0)
- return print_ref_list(kinds, detached, verbose, abbrev, with_commit);
- else if (rename && (argc == 1))
- rename_branch(head, argv[0], rename > 1);
- else if (rename && (argc == 2))
- rename_branch(argv[0], argv[1], rename > 1);
- else if (argc <= 2) {
+ else if (list)
+ return print_ref_list(kinds, detached, verbose, abbrev,
+ with_commit, argv);
+ else if (rename) {
+ if (argc == 1)
+ rename_branch(head, argv[0], rename > 1);
+ else if (argc == 2)
+ rename_branch(argv[0], argv[1], rename > 1);
+ else
+ usage_with_options(builtin_branch_usage, options);
+ } else if (argc > 0 && argc <= 2) {
if (kinds != REF_LOCAL_BRANCH)
die(_("-a and -r options to 'git branch' do not make sense with a branch name"));
create_branch(head, argv[0], (argc == 2) ? argv[1] : head,
diff --git a/builtin/bundle.c b/builtin/bundle.c
index 81046a9..92a8a60 100644
--- a/builtin/bundle.c
+++ b/builtin/bundle.c
@@ -58,7 +58,7 @@ int cmd_bundle(int argc, const char **argv, const char *prefix)
} else if (!strcmp(cmd, "unbundle")) {
if (!startup_info->have_repository)
die(_("Need a repository to unbundle."));
- return !!unbundle(&header, bundle_fd) ||
+ return !!unbundle(&header, bundle_fd, 0) ||
list_bundle_refs(&header, argc, argv);
} else
usage(builtin_bundle_usage);
diff --git a/builtin/check-attr.c b/builtin/check-attr.c
index 3016d29..44c421e 100644
--- a/builtin/check-attr.c
+++ b/builtin/check-attr.c
@@ -4,28 +4,30 @@
#include "quote.h"
#include "parse-options.h"
+static int all_attrs;
+static int cached_attrs;
static int stdin_paths;
static const char * const check_attr_usage[] = {
-"git check-attr attr... [--] pathname...",
-"git check-attr --stdin attr... < <list-of-paths>",
+"git check-attr [-a | --all | attr...] [--] pathname...",
+"git check-attr --stdin [-a | --all | attr...] < <list-of-paths>",
NULL
};
static int null_term_line;
static const struct option check_attr_options[] = {
+ OPT_BOOLEAN('a', "all", &all_attrs, "report all attributes set on file"),
+ OPT_BOOLEAN(0, "cached", &cached_attrs, "use .gitattributes only from the index"),
OPT_BOOLEAN(0 , "stdin", &stdin_paths, "read file names from stdin"),
OPT_BOOLEAN('z', NULL, &null_term_line,
"input paths are terminated by a null character"),
OPT_END()
};
-static void check_attr(int cnt, struct git_attr_check *check,
- const char** name, const char *file)
+static void output_attr(int cnt, struct git_attr_check *check,
+ const char *file)
{
int j;
- if (git_checkattr(file, cnt, check))
- die("git_checkattr died");
for (j = 0; j < cnt; j++) {
const char *value = check[j].value;
@@ -37,12 +39,30 @@ static void check_attr(int cnt, struct git_attr_check *check,
value = "unspecified";
quote_c_style(file, NULL, stdout, 0);
- printf(": %s: %s\n", name[j], value);
+ printf(": %s: %s\n", git_attr_name(check[j].attr), value);
}
}
-static void check_attr_stdin_paths(int cnt, struct git_attr_check *check,
- const char** name)
+static void check_attr(const char *prefix, int cnt,
+ struct git_attr_check *check, const char *file)
+{
+ char *full_path =
+ prefix_path(prefix, prefix ? strlen(prefix) : 0, file);
+ if (check != NULL) {
+ if (git_check_attr(full_path, cnt, check))
+ die("git_check_attr died");
+ output_attr(cnt, check, file);
+ } else {
+ if (git_all_attrs(full_path, &cnt, &check))
+ die("git_all_attrs died");
+ output_attr(cnt, check, file);
+ free(check);
+ }
+ free(full_path);
+}
+
+static void check_attr_stdin_paths(const char *prefix, int cnt,
+ struct git_attr_check *check)
{
struct strbuf buf, nbuf;
int line_termination = null_term_line ? 0 : '\n';
@@ -56,67 +76,99 @@ static void check_attr_stdin_paths(int cnt, struct git_attr_check *check,
die("line is badly quoted");
strbuf_swap(&buf, &nbuf);
}
- check_attr(cnt, check, name, buf.buf);
+ check_attr(prefix, cnt, check, buf.buf);
maybe_flush_or_die(stdout, "attribute to stdout");
}
strbuf_release(&buf);
strbuf_release(&nbuf);
}
+static NORETURN void error_with_usage(const char *msg)
+{
+ error("%s", msg);
+ usage_with_options(check_attr_usage, check_attr_options);
+}
+
int cmd_check_attr(int argc, const char **argv, const char *prefix)
{
struct git_attr_check *check;
- int cnt, i, doubledash;
- const char *errstr = NULL;
+ int cnt, i, doubledash, filei;
+
+ git_config(git_default_config, NULL);
argc = parse_options(argc, argv, prefix, check_attr_options,
check_attr_usage, PARSE_OPT_KEEP_DASHDASH);
- if (!argc)
- usage_with_options(check_attr_usage, check_attr_options);
if (read_cache() < 0) {
die("invalid cache");
}
+ if (cached_attrs)
+ git_attr_set_direction(GIT_ATTR_INDEX, NULL);
+
doubledash = -1;
for (i = 0; doubledash < 0 && i < argc; i++) {
if (!strcmp(argv[i], "--"))
doubledash = i;
}
- /* If there is no double dash, we handle only one attribute */
- if (doubledash < 0) {
- cnt = 1;
- doubledash = 0;
- } else
+ /* Process --all and/or attribute arguments: */
+ if (all_attrs) {
+ if (doubledash >= 1)
+ error_with_usage("Attributes and --all both specified");
+
+ cnt = 0;
+ filei = doubledash + 1;
+ } else if (doubledash == 0) {
+ error_with_usage("No attribute specified");
+ } else if (doubledash < 0) {
+ if (!argc)
+ error_with_usage("No attribute specified");
+
+ if (stdin_paths) {
+ /* Treat all arguments as attribute names. */
+ cnt = argc;
+ filei = argc;
+ } else {
+ /* Treat exactly one argument as an attribute name. */
+ cnt = 1;
+ filei = 1;
+ }
+ } else {
cnt = doubledash;
- doubledash++;
-
- if (cnt <= 0)
- errstr = "No attribute specified";
- else if (stdin_paths && doubledash < argc)
- errstr = "Can't specify files with --stdin";
- if (errstr) {
- error("%s", errstr);
- usage_with_options(check_attr_usage, check_attr_options);
+ filei = doubledash + 1;
}
- check = xcalloc(cnt, sizeof(*check));
- for (i = 0; i < cnt; i++) {
- const char *name;
- struct git_attr *a;
- name = argv[i];
- a = git_attr(name);
- if (!a)
- return error("%s: not a valid attribute name", name);
- check[i].attr = a;
+ /* Check file argument(s): */
+ if (stdin_paths) {
+ if (filei < argc)
+ error_with_usage("Can't specify files with --stdin");
+ } else {
+ if (filei >= argc)
+ error_with_usage("No file specified");
+ }
+
+ if (all_attrs) {
+ check = NULL;
+ } else {
+ check = xcalloc(cnt, sizeof(*check));
+ for (i = 0; i < cnt; i++) {
+ const char *name;
+ struct git_attr *a;
+ name = argv[i];
+ a = git_attr(name);
+ if (!a)
+ return error("%s: not a valid attribute name",
+ name);
+ check[i].attr = a;
+ }
}
if (stdin_paths)
- check_attr_stdin_paths(cnt, check, argv);
+ check_attr_stdin_paths(prefix, cnt, check);
else {
- for (i = doubledash; i < argc; i++)
- check_attr(cnt, check, argv, argv[i]);
+ for (i = filei; i < argc; i++)
+ check_attr(prefix, cnt, check, argv[i]);
maybe_flush_or_die(stdout, "attribute to stdout");
}
return 0;
diff --git a/builtin/check-ref-format.c b/builtin/check-ref-format.c
index ae3f281..28a7320 100644
--- a/builtin/check-ref-format.c
+++ b/builtin/check-ref-format.c
@@ -8,29 +8,32 @@
#include "strbuf.h"
static const char builtin_check_ref_format_usage[] =
-"git check-ref-format [--print] <refname>\n"
+"git check-ref-format [--normalize] [options] <refname>\n"
" or: git check-ref-format --branch <branchname-shorthand>";
/*
- * Replace each run of adjacent slashes in src with a single slash,
- * and write the result to dst.
+ * Return a copy of refname but with leading slashes removed and runs
+ * of adjacent slashes replaced with single slashes.
*
* This function is similar to normalize_path_copy(), but stripped down
* to meet check_ref_format's simpler needs.
*/
-static void collapse_slashes(char *dst, const char *src)
+static char *collapse_slashes(const char *refname)
{
+ char *ret = xmalloc(strlen(refname) + 1);
char ch;
- char prev = '\0';
+ char prev = '/';
+ char *cp = ret;
- while ((ch = *src++) != '\0') {
+ while ((ch = *refname++) != '\0') {
if (prev == '/' && ch == prev)
continue;
- *dst++ = ch;
+ *cp++ = ch;
prev = ch;
}
- *dst = '\0';
+ *cp = '\0';
+ return ret;
}
static int check_ref_format_branch(const char *arg)
@@ -45,27 +48,41 @@ static int check_ref_format_branch(const char *arg)
return 0;
}
-static int check_ref_format_print(const char *arg)
-{
- char *refname = xmalloc(strlen(arg) + 1);
-
- if (check_ref_format(arg))
- return 1;
- collapse_slashes(refname, arg);
- printf("%s\n", refname);
- return 0;
-}
-
int cmd_check_ref_format(int argc, const char **argv, const char *prefix)
{
+ int i;
+ int normalize = 0;
+ int flags = 0;
+ const char *refname;
+
if (argc == 2 && !strcmp(argv[1], "-h"))
usage(builtin_check_ref_format_usage);
if (argc == 3 && !strcmp(argv[1], "--branch"))
return check_ref_format_branch(argv[2]);
- if (argc == 3 && !strcmp(argv[1], "--print"))
- return check_ref_format_print(argv[2]);
- if (argc != 2)
+
+ for (i = 1; i < argc && argv[i][0] == '-'; i++) {
+ if (!strcmp(argv[i], "--normalize") || !strcmp(argv[i], "--print"))
+ normalize = 1;
+ else if (!strcmp(argv[i], "--allow-onelevel"))
+ flags |= REFNAME_ALLOW_ONELEVEL;
+ else if (!strcmp(argv[i], "--no-allow-onelevel"))
+ flags &= ~REFNAME_ALLOW_ONELEVEL;
+ else if (!strcmp(argv[i], "--refspec-pattern"))
+ flags |= REFNAME_REFSPEC_PATTERN;
+ else
+ usage(builtin_check_ref_format_usage);
+ }
+ if (! (i == argc - 1))
usage(builtin_check_ref_format_usage);
- return !!check_ref_format(argv[1]);
+
+ refname = argv[i];
+ if (normalize)
+ refname = collapse_slashes(refname);
+ if (check_refname_format(refname, flags))
+ return 1;
+ if (normalize)
+ printf("%s\n", refname);
+
+ return 0;
}
diff --git a/builtin/checkout-index.c b/builtin/checkout-index.c
index f1fec24..c16d82b 100644
--- a/builtin/checkout-index.c
+++ b/builtin/checkout-index.c
@@ -3,38 +3,6 @@
*
* Copyright (C) 2005 Linus Torvalds
*
- * Careful: order of argument flags does matter. For example,
- *
- * git checkout-index -a -f file.c
- *
- * Will first check out all files listed in the cache (but not
- * overwrite any old ones), and then force-checkout "file.c" a
- * second time (ie that one _will_ overwrite any old contents
- * with the same filename).
- *
- * Also, just doing "git checkout-index" does nothing. You probably
- * meant "git checkout-index -a". And if you want to force it, you
- * want "git checkout-index -f -a".
- *
- * Intuitiveness is not the goal here. Repeatability is. The
- * reason for the "no arguments means no work" thing is that
- * from scripts you are supposed to be able to do things like
- *
- * find . -name '*.h' -print0 | xargs -0 git checkout-index -f --
- *
- * or:
- *
- * find . -name '*.h' -print0 | git checkout-index -f -z --stdin
- *
- * which will force all existing *.h files to be replaced with
- * their cached copies. If an empty command line implied "all",
- * then this would force-refresh everything in the cache, which
- * was not the point.
- *
- * Oh, and the "--" is just a good idea when you know the rest
- * will be filenames. Just so that you wouldn't have a filename
- * of "-a" causing problems (not possible in the above example,
- * but get used to it in scripting!).
*/
#include "builtin.h"
#include "cache.h"
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 28cdc51..51840b9 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -19,6 +19,7 @@
#include "ll-merge.h"
#include "resolve-undo.h"
#include "submodule.h"
+#include "argv-array.h"
static const char * const checkout_usage[] = {
"git checkout [options] <branch>",
@@ -71,7 +72,7 @@ static int update_some(const unsigned char *sha1, const char *base, int baselen,
hashcpy(ce->sha1, sha1);
memcpy(ce->name, base, baselen);
memcpy(ce->name + baselen, pathname, len - baselen);
- ce->ce_flags = create_ce_flags(len, 0);
+ ce->ce_flags = create_ce_flags(len, 0) | CE_UPDATE;
ce->ce_mode = create_ce_mode(mode);
add_cache_entry(ce, ADD_CACHE_OK_TO_ADD | ADD_CACHE_OK_TO_REPLACE);
return 0;
@@ -201,7 +202,7 @@ static int checkout_merged(int pos, struct checkout *state)
}
static int checkout_paths(struct tree *source_tree, const char **pathspec,
- struct checkout_opts *opts)
+ const char *prefix, struct checkout_opts *opts)
{
int pos;
struct checkout state;
@@ -228,10 +229,12 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec,
for (pos = 0; pos < active_nr; pos++) {
struct cache_entry *ce = active_cache[pos];
+ if (source_tree && !(ce->ce_flags & CE_UPDATE))
+ continue;
match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, ps_matched);
}
- if (report_path_error(ps_matched, pathspec, 0))
+ if (report_path_error(ps_matched, pathspec, prefix))
return 1;
/* "checkout -m path" to recreate conflicted state */
@@ -266,6 +269,8 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec,
state.refresh_cache = 1;
for (pos = 0; pos < active_nr; pos++) {
struct cache_entry *ce = active_cache[pos];
+ if (source_tree && !(ce->ce_flags & CE_UPDATE))
+ continue;
if (match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, NULL)) {
if (!ce_stage(ce)) {
errs |= checkout_entry(ce, &state, NULL);
@@ -406,7 +411,7 @@ static int merge_working_tree(struct checkout_opts *opts,
topts.fn = twoway_merge;
topts.dir = xcalloc(1, sizeof(*topts.dir));
topts.dir->flags |= DIR_SHOW_IGNORED;
- topts.dir->exclude_per_dir = ".gitignore";
+ setup_standard_excludes(topts.dir);
tree = parse_tree_indirect(old->commit ?
old->commit->object.sha1 :
EMPTY_TREE_SHA1_BIN);
@@ -588,35 +593,11 @@ static void update_refs_for_switch(struct checkout_opts *opts,
report_tracking(new);
}
-struct rev_list_args {
- int argc;
- int alloc;
- const char **argv;
-};
-
-static void add_one_rev_list_arg(struct rev_list_args *args, const char *s)
-{
- ALLOC_GROW(args->argv, args->argc + 1, args->alloc);
- args->argv[args->argc++] = s;
-}
-
-static int add_one_ref_to_rev_list_arg(const char *refname,
- const unsigned char *sha1,
- int flags,
- void *cb_data)
+static int add_pending_uninteresting_ref(const char *refname,
+ const unsigned char *sha1,
+ int flags, void *cb_data)
{
- add_one_rev_list_arg(cb_data, refname);
- return 0;
-}
-
-static int clear_commit_marks_from_one_ref(const char *refname,
- const unsigned char *sha1,
- int flags,
- void *cb_data)
-{
- struct commit *commit = lookup_commit_reference_gently(sha1, 1);
- if (commit)
- clear_commit_marks(commit, -1);
+ add_pending_sha1(cb_data, refname, sha1, flags | UNINTERESTING);
return 0;
}
@@ -657,24 +638,25 @@ static void suggest_reattach(struct commit *commit, struct rev_info *revs)
"Warning: you are leaving %d commit behind, "
"not connected to\n"
"any of your branches:\n\n"
- "%s\n"
- "If you want to keep it by creating a new branch, "
- "this may be a good time\nto do so with:\n\n"
- " git branch new_branch_name %s\n\n",
+ "%s\n",
/* The plural version */
"Warning: you are leaving %d commits behind, "
"not connected to\n"
"any of your branches:\n\n"
- "%s\n"
- "If you want to keep them by creating a new branch, "
- "this may be a good time\nto do so with:\n\n"
- " git branch new_branch_name %s\n\n",
+ "%s\n",
/* Give ngettext() the count */
lost),
lost,
- sb.buf,
- sha1_to_hex(commit->object.sha1));
+ sb.buf);
strbuf_release(&sb);
+
+ if (advice_detached_head)
+ fprintf(stderr,
+ _(
+ "If you want to keep them by creating a new branch, "
+ "this may be a good time\nto do so with:\n\n"
+ " git branch new_branch_name %s\n\n"),
+ sha1_to_hex(commit->object.sha1));
}
/*
@@ -684,19 +666,21 @@ static void suggest_reattach(struct commit *commit, struct rev_info *revs)
*/
static void orphaned_commit_warning(struct commit *commit)
{
- struct rev_list_args args = { 0, 0, NULL };
struct rev_info revs;
-
- add_one_rev_list_arg(&args, "(internal)");
- add_one_rev_list_arg(&args, sha1_to_hex(commit->object.sha1));
- add_one_rev_list_arg(&args, "--not");
- for_each_ref(add_one_ref_to_rev_list_arg, &args);
- add_one_rev_list_arg(&args, "--");
- add_one_rev_list_arg(&args, NULL);
+ struct object *object = &commit->object;
+ struct object_array refs;
init_revisions(&revs, NULL);
- if (setup_revisions(args.argc - 1, args.argv, &revs, NULL) != 1)
- die(_("internal error: only -- alone should have been left"));
+ setup_revisions(0, NULL, &revs, NULL);
+
+ object->flags &= ~UNINTERESTING;
+ add_pending_object(&revs, object, sha1_to_hex(object->sha1));
+
+ for_each_ref(add_pending_uninteresting_ref, &revs);
+
+ refs = revs.pending;
+ revs.leak_pending = 1;
+
if (prepare_revision_walk(&revs))
die(_("internal error in revision walk"));
if (!(commit->object.flags & UNINTERESTING))
@@ -704,8 +688,8 @@ static void orphaned_commit_warning(struct commit *commit)
else
describe_detached_head(_("Previous HEAD position was"), commit);
- clear_commit_marks(commit, -1);
- for_each_ref(clear_commit_marks_from_one_ref, NULL);
+ clear_commit_marks_for_object_array(&refs, ALL_REV_FLAGS);
+ free(refs.objects);
}
static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
@@ -715,10 +699,12 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
unsigned char rev[20];
int flag;
memset(&old, 0, sizeof(old));
- old.path = resolve_ref("HEAD", rev, 0, &flag);
+ old.path = xstrdup(resolve_ref("HEAD", rev, 0, &flag));
old.commit = lookup_commit_reference_gently(rev, 1);
- if (!(flag & REF_ISSYMREF))
+ if (!(flag & REF_ISSYMREF)) {
+ free((char *)old.path);
old.path = NULL;
+ }
if (old.path && !prefixcmp(old.path, "refs/heads/"))
old.name = old.path + strlen("refs/heads/");
@@ -741,6 +727,7 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
update_refs_for_switch(opts, &old, new);
ret = post_checkout_hook(old.commit, new->commit, 1);
+ free((char *)old.path);
return ret || opts->writeout_error;
}
@@ -878,7 +865,7 @@ static int parse_branchname_arg(int argc, const char **argv,
new->name = arg;
setup_branch_path(new);
- if (check_ref_format(new->path) == CHECK_REF_FORMAT_OK &&
+ if (!check_refname_format(new->path, 0) &&
resolve_ref(new->path, branch_rev, 1, NULL))
hashcpy(rev, branch_rev);
else
@@ -1060,7 +1047,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
if (1 < !!opts.writeout_stage + !!opts.force + !!opts.merge)
die(_("git checkout: --ours/--theirs, --force and --merge are incompatible when\nchecking out of the index."));
- return checkout_paths(source_tree, pathspec, &opts);
+ return checkout_paths(source_tree, pathspec, prefix, &opts);
}
if (patch_mode)
@@ -1068,15 +1055,10 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
if (opts.new_branch) {
struct strbuf buf = STRBUF_INIT;
- if (strbuf_check_branch_ref(&buf, opts.new_branch))
- die(_("git checkout: we do not like '%s' as a branch name."),
- opts.new_branch);
- if (!get_sha1(buf.buf, rev)) {
- opts.branch_exists = 1;
- if (!opts.new_branch_force)
- die(_("git checkout: branch %s already exists"),
- opts.new_branch);
- }
+
+ opts.branch_exists = validate_new_branchname(opts.new_branch, &buf,
+ !!opts.new_branch_force, 0);
+
strbuf_release(&buf);
}
diff --git a/builtin/clean.c b/builtin/clean.c
index 75697f7..0c7b3d0 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -54,7 +54,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
OPT_BOOLEAN('d', NULL, &remove_directories,
"remove whole directories"),
{ OPTION_CALLBACK, 'e', "exclude", &exclude_list, "pattern",
- "exclude <pattern>", PARSE_OPT_NONEG, exclude_cb },
+ "add <pattern> to ignore rules", PARSE_OPT_NONEG, exclude_cb },
OPT_BOOLEAN('x', NULL, &ignored, "remove ignored files, too"),
OPT_BOOLEAN('X', NULL, &ignored_only,
"remove only ignored files"),
@@ -98,7 +98,8 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
setup_standard_excludes(&dir);
for (i = 0; i < exclude_list.nr; i++)
- add_exclude(exclude_list.items[i].string, "", 0, dir.exclude_list);
+ add_exclude(exclude_list.items[i].string, "", 0,
+ &dir.exclude_list[EXC_CMDL]);
pathspec = get_pathspec(prefix, argv);
diff --git a/builtin/clone.c b/builtin/clone.c
index f579794..efe8b6c 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -39,13 +39,24 @@ static const char * const builtin_clone_usage[] = {
static int option_no_checkout, option_bare, option_mirror;
static int option_local, option_no_hardlinks, option_shared, option_recursive;
-static char *option_template, *option_reference, *option_depth;
+static char *option_template, *option_depth;
static char *option_origin = NULL;
static char *option_branch = NULL;
static const char *real_git_dir;
static char *option_upload_pack = "git-upload-pack";
static int option_verbosity;
static int option_progress;
+static struct string_list option_config;
+static struct string_list option_reference;
+
+static int opt_parse_reference(const struct option *opt, const char *arg, int unset)
+{
+ struct string_list *option_reference = opt->value;
+ if (!arg)
+ return -1;
+ string_list_append(option_reference, arg);
+ return 0;
+}
static struct option builtin_clone_options[] = {
OPT__VERBOSITY(&option_verbosity),
@@ -71,8 +82,8 @@ static struct option builtin_clone_options[] = {
"initialize submodules in the clone"),
OPT_STRING(0, "template", &option_template, "template-directory",
"directory from which templates will be used"),
- OPT_STRING(0, "reference", &option_reference, "repo",
- "reference repository"),
+ OPT_CALLBACK(0 , "reference", &option_reference, "repo",
+ "reference repository", &opt_parse_reference),
OPT_STRING('o', "origin", &option_origin, "branch",
"use <branch> instead of 'origin' to track upstream"),
OPT_STRING('b', "branch", &option_branch, "branch",
@@ -83,7 +94,8 @@ static struct option builtin_clone_options[] = {
"create a shallow clone of that depth"),
OPT_STRING(0, "separate-git-dir", &real_git_dir, "gitdir",
"separate git dir from working tree"),
-
+ OPT_STRING_LIST('c', "config", &option_config, "key=value",
+ "set config inside the new repository"),
OPT_END()
};
@@ -101,9 +113,26 @@ static char *get_repo_path(const char *repo, int *is_bundle)
for (i = 0; i < ARRAY_SIZE(suffix); i++) {
const char *path;
path = mkpath("%s%s", repo, suffix[i]);
- if (is_directory(path)) {
+ if (stat(path, &st))
+ continue;
+ if (S_ISDIR(st.st_mode)) {
*is_bundle = 0;
return xstrdup(absolute_path(path));
+ } else if (S_ISREG(st.st_mode) && st.st_size > 8) {
+ /* Is it a "gitfile"? */
+ char signature[8];
+ int len, fd = open(path, O_RDONLY);
+ if (fd < 0)
+ continue;
+ len = read_in_full(fd, signature, 8);
+ close(fd);
+ if (len != 8 || strncmp(signature, "gitdir: ", 8))
+ continue;
+ path = read_gitfile(path);
+ if (path) {
+ *is_bundle = 0;
+ return xstrdup(absolute_path(path));
+ }
}
}
@@ -197,39 +226,80 @@ static void strip_trailing_slashes(char *dir)
*end = '\0';
}
-static void setup_reference(const char *repo)
+static int add_one_reference(struct string_list_item *item, void *cb_data)
{
- const char *ref_git;
- char *ref_git_copy;
-
+ char *ref_git;
+ struct strbuf alternate = STRBUF_INIT;
struct remote *remote;
struct transport *transport;
const struct ref *extra;
- ref_git = real_path(option_reference);
-
- if (is_directory(mkpath("%s/.git/objects", ref_git)))
- ref_git = mkpath("%s/.git", ref_git);
- else if (!is_directory(mkpath("%s/objects", ref_git)))
+ /* Beware: real_path() and mkpath() return static buffer */
+ ref_git = xstrdup(real_path(item->string));
+ if (is_directory(mkpath("%s/.git/objects", ref_git))) {
+ char *ref_git_git = xstrdup(mkpath("%s/.git", ref_git));
+ free(ref_git);
+ ref_git = ref_git_git;
+ } else if (!is_directory(mkpath("%s/objects", ref_git)))
die(_("reference repository '%s' is not a local directory."),
- option_reference);
+ item->string);
- ref_git_copy = xstrdup(ref_git);
+ strbuf_addf(&alternate, "%s/objects", ref_git);
+ add_to_alternates_file(alternate.buf);
+ strbuf_release(&alternate);
- add_to_alternates_file(ref_git_copy);
-
- remote = remote_get(ref_git_copy);
- transport = transport_get(remote, ref_git_copy);
+ remote = remote_get(ref_git);
+ transport = transport_get(remote, ref_git);
for (extra = transport_get_remote_refs(transport); extra;
extra = extra->next)
add_extra_ref(extra->name, extra->old_sha1, 0);
transport_disconnect(transport);
+ free(ref_git);
+ return 0;
+}
- free(ref_git_copy);
+static void setup_reference(void)
+{
+ for_each_string_list(&option_reference, add_one_reference, NULL);
}
-static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest)
+static void copy_alternates(struct strbuf *src, struct strbuf *dst,
+ const char *src_repo)
+{
+ /*
+ * Read from the source objects/info/alternates file
+ * and copy the entries to corresponding file in the
+ * destination repository with add_to_alternates_file().
+ * Both src and dst have "$path/objects/info/alternates".
+ *
+ * Instead of copying bit-for-bit from the original,
+ * we need to append to existing one so that the already
+ * created entry via "clone -s" is not lost, and also
+ * to turn entries with paths relative to the original
+ * absolute, so that they can be used in the new repository.
+ */
+ FILE *in = fopen(src->buf, "r");
+ struct strbuf line = STRBUF_INIT;
+
+ while (strbuf_getline(&line, in, '\n') != EOF) {
+ char *abs_path, abs_buf[PATH_MAX];
+ if (!line.len || line.buf[0] == '#')
+ continue;
+ if (is_absolute_path(line.buf)) {
+ add_to_alternates_file(line.buf);
+ continue;
+ }
+ abs_path = mkpath("%s/objects/%s", src_repo, line.buf);
+ normalize_path_copy(abs_buf, abs_path);
+ add_to_alternates_file(abs_buf);
+ }
+ strbuf_release(&line);
+ fclose(in);
+}
+
+static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
+ const char *src_repo, int src_baselen)
{
struct dirent *de;
struct stat buf;
@@ -265,7 +335,14 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest)
}
if (S_ISDIR(buf.st_mode)) {
if (de->d_name[0] != '.')
- copy_or_link_directory(src, dest);
+ copy_or_link_directory(src, dest,
+ src_repo, src_baselen);
+ continue;
+ }
+
+ /* Files that cannot be copied bit-for-bit... */
+ if (!strcmp(src->buf + src_baselen, "/info/alternates")) {
+ copy_alternates(src, dest, src_repo);
continue;
}
@@ -288,17 +365,20 @@ static const struct ref *clone_local(const char *src_repo,
const char *dest_repo)
{
const struct ref *ret;
- struct strbuf src = STRBUF_INIT;
- struct strbuf dest = STRBUF_INIT;
struct remote *remote;
struct transport *transport;
- if (option_shared)
- add_to_alternates_file(src_repo);
- else {
+ if (option_shared) {
+ struct strbuf alt = STRBUF_INIT;
+ strbuf_addf(&alt, "%s/objects", src_repo);
+ add_to_alternates_file(alt.buf);
+ strbuf_release(&alt);
+ } else {
+ struct strbuf src = STRBUF_INIT;
+ struct strbuf dest = STRBUF_INIT;
strbuf_addf(&src, "%s/objects", src_repo);
strbuf_addf(&dest, "%s/objects", dest_repo);
- copy_or_link_directory(&src, &dest);
+ copy_or_link_directory(&src, &dest, src_repo, src.len);
strbuf_release(&src);
strbuf_release(&dest);
}
@@ -343,8 +423,9 @@ static void remove_junk_on_signal(int signo)
static struct ref *wanted_peer_refs(const struct ref *refs,
struct refspec *refspec)
{
- struct ref *local_refs = NULL;
- struct ref **tail = &local_refs;
+ struct ref *head = copy_ref(find_ref_by_name(refs, "HEAD"));
+ struct ref *local_refs = head;
+ struct ref **tail = head ? &head->next : &local_refs;
get_fetch_map(refs, refspec, &tail, 0);
if (!option_mirror)
@@ -357,13 +438,32 @@ static void write_remote_refs(const struct ref *local_refs)
{
const struct ref *r;
- for (r = local_refs; r; r = r->next)
+ for (r = local_refs; r; r = r->next) {
+ if (!r->peer_ref)
+ continue;
add_extra_ref(r->peer_ref->name, r->old_sha1, 0);
+ }
pack_refs(PACK_REFS_ALL);
clear_extra_refs();
}
+static int write_one_config(const char *key, const char *value, void *data)
+{
+ return git_config_set_multivar(key, value ? value : "true", "^$", 0);
+}
+
+static void write_config(struct string_list *config)
+{
+ int i;
+
+ for (i = 0; i < config->nr; i++) {
+ if (git_config_parse_parameter(config->items[i].string,
+ write_one_config, NULL) < 0)
+ die("unable to write parameters to config file");
+ }
+}
+
int cmd_clone(int argc, const char **argv, const char *prefix)
{
int is_bundle = 0, is_local;
@@ -477,11 +577,12 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
if (0 <= option_verbosity) {
if (option_bare)
- printf(_("Cloning into bare repository %s...\n"), dir);
+ printf(_("Cloning into bare repository '%s'...\n"), dir);
else
- printf(_("Cloning into %s...\n"), dir);
+ printf(_("Cloning into '%s'...\n"), dir);
}
init_db(option_template, INIT_DB_QUIET);
+ write_config(&option_config);
/*
* At this point, the config exists, so we do not need the
@@ -521,8 +622,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
git_config_set(key.buf, repo);
strbuf_reset(&key);
- if (option_reference)
- setup_reference(git_dir);
+ if (option_reference.nr)
+ setup_reference();
fetch_pattern = value.buf;
refspec = parse_fetch_refspec(1, &fetch_pattern);
diff --git a/builtin/commit.c b/builtin/commit.c
index e1af9b1..8f2bebe 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -62,8 +62,6 @@ N_("The previous cherry-pick is now empty, possibly due to conflict resolution.\
"\n"
"Otherwise, please use 'git reset'\n");
-static unsigned char head_sha1[20];
-
static const char *use_message_buffer;
static const char commit_editmsg[] = "COMMIT_EDITMSG";
static struct lock_file index_lock; /* real index */
@@ -102,7 +100,7 @@ static enum {
static char *cleanup_arg;
static enum commit_whence whence;
-static int use_editor = 1, initial_commit, include_status = 1;
+static int use_editor = 1, include_status = 1;
static int show_ignored_in_status;
static const char *only_include_assumed;
static struct strbuf message;
@@ -256,8 +254,11 @@ static int list_paths(struct string_list *list, const char *with_tree,
;
m = xcalloc(1, i);
- if (with_tree)
- overlay_tree_on_cache(with_tree, prefix);
+ if (with_tree) {
+ char *max_prefix = common_prefix(pattern);
+ overlay_tree_on_cache(with_tree, max_prefix ? max_prefix : prefix);
+ free(max_prefix);
+ }
for (i = 0; i < active_nr; i++) {
struct cache_entry *ce = active_cache[i];
@@ -272,7 +273,7 @@ static int list_paths(struct string_list *list, const char *with_tree,
item->util = item; /* better a valid pointer than a fake one */
}
- return report_path_error(m, pattern, prefix ? strlen(prefix) : 0);
+ return report_path_error(m, pattern, prefix);
}
static void add_remove_files(struct string_list *list)
@@ -294,13 +295,13 @@ static void add_remove_files(struct string_list *list)
}
}
-static void create_base_index(void)
+static void create_base_index(const struct commit *current_head)
{
struct tree *tree;
struct unpack_trees_options opts;
struct tree_desc t;
- if (initial_commit) {
+ if (!current_head) {
discard_cache();
return;
}
@@ -313,7 +314,7 @@ static void create_base_index(void)
opts.dst_index = &the_index;
opts.fn = oneway_merge;
- tree = parse_tree_indirect(head_sha1);
+ tree = parse_tree_indirect(current_head->object.sha1);
if (!tree)
die(_("failed to unpack HEAD tree object"));
parse_tree(tree);
@@ -332,7 +333,8 @@ static void refresh_cache_or_die(int refresh_flags)
die_resolve_conflict("commit");
}
-static char *prepare_index(int argc, const char **argv, const char *prefix, int is_status)
+static char *prepare_index(int argc, const char **argv, const char *prefix,
+ const struct commit *current_head, int is_status)
{
int fd;
struct string_list partial;
@@ -448,7 +450,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, int
memset(&partial, 0, sizeof(partial));
partial.strdup_strings = 1;
- if (list_paths(&partial, initial_commit ? NULL : "HEAD", prefix, pathspec))
+ if (list_paths(&partial, !current_head ? NULL : "HEAD", prefix, pathspec))
exit(1);
discard_cache();
@@ -467,7 +469,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, int
(uintmax_t) getpid()),
LOCK_DIE_ON_ERROR);
- create_base_index();
+ create_base_index(current_head);
add_remove_files(&partial);
refresh_cache(REFRESH_QUIET);
@@ -516,12 +518,9 @@ static int run_status(FILE *fp, const char *index_file, const char *prefix, int
return s->commitable;
}
-static int is_a_merge(const unsigned char *sha1)
+static int is_a_merge(const struct commit *current_head)
{
- struct commit *commit = lookup_commit(sha1);
- if (!commit || parse_commit(commit))
- die(_("could not parse HEAD commit"));
- return !!(commit->parents && commit->parents->next);
+ return !!(current_head->parents && current_head->parents->next);
}
static const char sign_off_header[] = "Signed-off-by: ";
@@ -625,6 +624,7 @@ static char *cut_ident_timestamp_part(char *string)
}
static int prepare_to_commit(const char *index_file, const char *prefix,
+ struct commit *current_head,
struct wt_status *s,
struct strbuf *author_ident)
{
@@ -846,7 +846,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
* empty due to conflict resolution, which the user should okay.
*/
if (!commitable && whence != FROM_MERGE && !allow_empty &&
- !(amend && is_a_merge(head_sha1))) {
+ !(amend && is_a_merge(current_head))) {
run_status(stdout, index_file, prefix, 0, s);
if (amend)
fputs(_(empty_amend_advice), stderr);
@@ -1004,6 +1004,7 @@ static const char *read_commit_message(const char *name)
static int parse_and_validate_options(int argc, const char *argv[],
const char * const usage[],
const char *prefix,
+ struct commit *current_head,
struct wt_status *s)
{
int f = 0;
@@ -1024,11 +1025,8 @@ static int parse_and_validate_options(int argc, const char *argv[],
if (!use_editor)
setenv("GIT_EDITOR", ":", 1);
- if (get_sha1("HEAD", head_sha1))
- initial_commit = 1;
-
/* Sanity check options */
- if (amend && initial_commit)
+ if (amend && !current_head)
die(_("You have nothing to amend."));
if (amend && whence != FROM_COMMIT)
die(_("You are in the middle of a %s -- cannot amend."), whence_s());
@@ -1100,12 +1098,12 @@ static int parse_and_validate_options(int argc, const char *argv[],
}
static int dry_run_commit(int argc, const char **argv, const char *prefix,
- struct wt_status *s)
+ const struct commit *current_head, struct wt_status *s)
{
int commitable;
const char *index_file;
- index_file = prepare_index(argc, argv, prefix, 1);
+ index_file = prepare_index(argc, argv, prefix, current_head, 1);
commitable = run_status(stdout, index_file, prefix, 0, s);
rollback_index_files();
@@ -1144,7 +1142,7 @@ static int git_status_config(const char *k, const char *v, void *cb)
return 0;
}
if (!strcmp(k, "status.color") || !strcmp(k, "color.status")) {
- s->use_color = git_config_colorbool(k, v, -1);
+ s->use_color = git_config_colorbool(k, v);
return 0;
}
if (!prefixcmp(k, "status.color.") || !prefixcmp(k, "color.status.")) {
@@ -1237,10 +1235,6 @@ int cmd_status(int argc, const char **argv, const char *prefix)
if (s.relative_paths)
s.prefix = prefix;
- if (s.use_color == -1)
- s.use_color = git_use_color_default;
- if (diff_use_color_default == -1)
- diff_use_color_default = git_use_color_default;
switch (status_format) {
case STATUS_FORMAT_SHORT:
@@ -1258,7 +1252,8 @@ int cmd_status(int argc, const char **argv, const char *prefix)
return 0;
}
-static void print_summary(const char *prefix, const unsigned char *sha1)
+static void print_summary(const char *prefix, const unsigned char *sha1,
+ int initial_commit)
{
struct rev_info rev;
struct commit *commit;
@@ -1380,12 +1375,13 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
struct strbuf author_ident = STRBUF_INIT;
const char *index_file, *reflog_msg;
char *nl, *p;
- unsigned char commit_sha1[20];
+ unsigned char sha1[20];
struct ref_lock *ref_lock;
struct commit_list *parents = NULL, **pptr = &parents;
struct stat statbuf;
int allow_fast_forward = 1;
struct wt_status s;
+ struct commit *current_head = NULL;
if (argc == 2 && !strcmp(argv[1], "-h"))
usage_with_options(builtin_commit_usage, builtin_commit_options);
@@ -1394,48 +1390,47 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
git_config(git_commit_config, &s);
determine_whence(&s);
- if (s.use_color == -1)
- s.use_color = git_use_color_default;
- argc = parse_and_validate_options(argc, argv, builtin_commit_usage,
- prefix, &s);
- if (dry_run) {
- if (diff_use_color_default == -1)
- diff_use_color_default = git_use_color_default;
- return dry_run_commit(argc, argv, prefix, &s);
+ if (get_sha1("HEAD", sha1))
+ current_head = NULL;
+ else {
+ current_head = lookup_commit_or_die(sha1, "HEAD");
+ if (!current_head || parse_commit(current_head))
+ die(_("could not parse HEAD commit"));
}
- index_file = prepare_index(argc, argv, prefix, 0);
+ argc = parse_and_validate_options(argc, argv, builtin_commit_usage,
+ prefix, current_head, &s);
+ if (dry_run)
+ return dry_run_commit(argc, argv, prefix, current_head, &s);
+ index_file = prepare_index(argc, argv, prefix, current_head, 0);
/* Set up everything for writing the commit object. This includes
running hooks, writing the trees, and interacting with the user. */
- if (!prepare_to_commit(index_file, prefix, &s, &author_ident)) {
+ if (!prepare_to_commit(index_file, prefix,
+ current_head, &s, &author_ident)) {
rollback_index_files();
return 1;
}
/* Determine parents */
reflog_msg = getenv("GIT_REFLOG_ACTION");
- if (initial_commit) {
+ if (!current_head) {
if (!reflog_msg)
reflog_msg = "commit (initial)";
} else if (amend) {
struct commit_list *c;
- struct commit *commit;
if (!reflog_msg)
reflog_msg = "commit (amend)";
- commit = lookup_commit(head_sha1);
- if (!commit || parse_commit(commit))
- die(_("could not parse HEAD commit"));
-
- for (c = commit->parents; c; c = c->next)
+ for (c = current_head->parents; c; c = c->next)
pptr = &commit_list_insert(c->item, pptr)->next;
} else if (whence == FROM_MERGE) {
struct strbuf m = STRBUF_INIT;
+ struct commit *commit;
FILE *fp;
if (!reflog_msg)
reflog_msg = "commit (merge)";
- pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next;
+ pptr = &commit_list_insert(current_head, pptr)->next;
fp = fopen(git_path("MERGE_HEAD"), "r");
if (fp == NULL)
die_errno(_("could not open '%s' for reading"),
@@ -1444,7 +1439,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
unsigned char sha1[20];
if (get_sha1_hex(m.buf, sha1) < 0)
die(_("Corrupt MERGE_HEAD file (%s)"), m.buf);
- pptr = &commit_list_insert(lookup_commit(sha1), pptr)->next;
+ commit = lookup_commit_or_die(sha1, "MERGE_HEAD");
+ pptr = &commit_list_insert(commit, pptr)->next;
}
fclose(fp);
strbuf_release(&m);
@@ -1461,7 +1457,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
reflog_msg = (whence == FROM_CHERRY_PICK)
? "commit (cherry-pick)"
: "commit";
- pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next;
+ pptr = &commit_list_insert(current_head, pptr)->next;
}
/* Finally, get the commit message */
@@ -1487,7 +1483,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
exit(1);
}
- if (commit_tree(sb.buf, active_cache_tree->sha1, parents, commit_sha1,
+ if (commit_tree(sb.buf, active_cache_tree->sha1, parents, sha1,
author_ident.buf)) {
rollback_index_files();
die(_("failed to write commit object"));
@@ -1495,7 +1491,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
strbuf_release(&author_ident);
ref_lock = lock_any_ref_for_update("HEAD",
- initial_commit ? NULL : head_sha1,
+ !current_head
+ ? NULL
+ : current_head->object.sha1,
0);
nl = strchr(sb.buf, '\n');
@@ -1510,12 +1508,13 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
rollback_index_files();
die(_("cannot lock HEAD ref"));
}
- if (write_ref_sha1(ref_lock, commit_sha1, sb.buf) < 0) {
+ if (write_ref_sha1(ref_lock, sha1, sb.buf) < 0) {
rollback_index_files();
die(_("cannot update HEAD ref"));
}
unlink(git_path("CHERRY_PICK_HEAD"));
+ unlink(git_path("REVERT_HEAD"));
unlink(git_path("MERGE_HEAD"));
unlink(git_path("MERGE_MSG"));
unlink(git_path("MERGE_MODE"));
@@ -1532,13 +1531,14 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
struct notes_rewrite_cfg *cfg;
cfg = init_copy_notes_for_rewrite("amend");
if (cfg) {
- copy_note_for_rewrite(cfg, head_sha1, commit_sha1);
+ /* we are amending, so current_head is not NULL */
+ copy_note_for_rewrite(cfg, current_head->object.sha1, sha1);
finish_copy_notes_for_rewrite(cfg);
}
- run_rewrite_hook(head_sha1, commit_sha1);
+ run_rewrite_hook(current_head->object.sha1, sha1);
}
if (!quiet)
- print_summary(prefix, commit_sha1);
+ print_summary(prefix, sha1, !current_head);
return 0;
}
diff --git a/builtin/config.c b/builtin/config.c
index 211e118..0315ad7 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -99,6 +99,7 @@ static int show_config(const char *key_, const char *value_, void *cb)
const char *vptr = value;
int must_free_vptr = 0;
int dup_error = 0;
+ int must_print_delim = 0;
if (!use_key_regexp && strcmp(key_, key))
return 0;
@@ -109,10 +110,8 @@ static int show_config(const char *key_, const char *value_, void *cb)
return 0;
if (show_keys) {
- if (value_)
- printf("%s%c", key_, key_delim);
- else
- printf("%s", key_);
+ printf("%s", key_);
+ must_print_delim = 1;
}
if (seen && !do_all)
dup_error = 1;
@@ -130,16 +129,23 @@ static int show_config(const char *key_, const char *value_, void *cb)
} else if (types == TYPE_PATH) {
git_config_pathname(&vptr, key_, value_);
must_free_vptr = 1;
+ } else if (value_) {
+ vptr = value_;
+ } else {
+ /* Just show the key name */
+ vptr = "";
+ must_print_delim = 0;
}
- else
- vptr = value_?value_:"";
seen++;
if (dup_error) {
error("More than one value for the key %s: %s",
key_, vptr);
}
- else
+ else {
+ if (must_print_delim)
+ printf("%c", key_delim);
printf("%s%c", vptr, term);
+ }
if (must_free_vptr)
/* If vptr must be freed, it's a pointer to a
* dynamically allocated buffer, it's safe to cast to
@@ -303,24 +309,18 @@ static void get_color(const char *def_color)
fputs(parsed_color, stdout);
}
-static int stdout_is_tty;
static int get_colorbool_found;
static int get_diff_color_found;
+static int get_color_ui_found;
static int git_get_colorbool_config(const char *var, const char *value,
void *cb)
{
- if (!strcmp(var, get_colorbool_slot)) {
- get_colorbool_found =
- git_config_colorbool(var, value, stdout_is_tty);
- }
- if (!strcmp(var, "diff.color")) {
- get_diff_color_found =
- git_config_colorbool(var, value, stdout_is_tty);
- }
- if (!strcmp(var, "color.ui")) {
- git_use_color_default = git_config_colorbool(var, value, stdout_is_tty);
- return 0;
- }
+ if (!strcmp(var, get_colorbool_slot))
+ get_colorbool_found = git_config_colorbool(var, value);
+ else if (!strcmp(var, "diff.color"))
+ get_diff_color_found = git_config_colorbool(var, value);
+ else if (!strcmp(var, "color.ui"))
+ get_color_ui_found = git_config_colorbool(var, value);
return 0;
}
@@ -334,9 +334,11 @@ static int get_colorbool(int print)
if (!strcmp(get_colorbool_slot, "color.diff"))
get_colorbool_found = get_diff_color_found;
if (get_colorbool_found < 0)
- get_colorbool_found = git_use_color_default;
+ get_colorbool_found = get_color_ui_found;
}
+ get_colorbool_found = want_color(get_colorbool_found);
+
if (print) {
printf("%s\n", get_colorbool_found ? "true" : "false");
return 0;
@@ -510,9 +512,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
}
else if (actions == ACTION_GET_COLORBOOL) {
if (argc == 1)
- stdout_is_tty = git_config_bool("command line", argv[0]);
- else if (argc == 0)
- stdout_is_tty = isatty(1);
+ color_stdout_is_tty = git_config_bool("command line", argv[0]);
return get_colorbool(argc != 0);
}
diff --git a/builtin/describe.c b/builtin/describe.c
index 66fc291..9f63067 100644
--- a/builtin/describe.c
+++ b/builtin/describe.c
@@ -462,8 +462,21 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
die(_("No names found, cannot describe anything."));
if (argc == 0) {
- if (dirty && !cmd_diff_index(ARRAY_SIZE(diff_index_args) - 1, diff_index_args, prefix))
- dirty = NULL;
+ if (dirty) {
+ static struct lock_file index_lock;
+ int fd;
+
+ read_cache_preload(NULL);
+ refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED,
+ NULL, NULL, NULL);
+ fd = hold_locked_index(&index_lock, 0);
+ if (0 <= fd)
+ update_index_if_able(&the_index, &index_lock);
+
+ if (!cmd_diff_index(ARRAY_SIZE(diff_index_args) - 1,
+ diff_index_args, prefix))
+ dirty = NULL;
+ }
describe("HEAD", 1);
} else if (dirty) {
die(_("--dirty is incompatible with committishes"));
diff --git a/builtin/diff.c b/builtin/diff.c
index 69cd5ee..0fe638f 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -182,7 +182,7 @@ static int builtin_diff_combined(struct rev_info *revs,
hashcpy((unsigned char *)(parent + i), ent[i].item->sha1);
diff_tree_combined(parent[0], parent + 1, ents - 1,
revs->dense_combined_merges, revs);
- free(parent);
+ free((void *)parent);
return 0;
}
@@ -277,9 +277,6 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
gitmodules_config();
git_config(git_diff_ui_config, NULL);
- if (diff_use_color_default == -1)
- diff_use_color_default = git_use_color_default;
-
init_revisions(&rev, prefix);
/* If this is a no-index diff, just run it and exit there. */
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index daf1945..9836e6b 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -16,6 +16,7 @@
#include "string-list.h"
#include "utf8.h"
#include "parse-options.h"
+#include "quote.h"
static const char *fast_export_usage[] = {
"git fast-export [rev-list-opts]",
@@ -26,6 +27,7 @@ static int progress;
static enum { ABORT, VERBATIM, WARN, STRIP } signed_tag_mode = ABORT;
static enum { ERROR, DROP, REWRITE } tag_of_filtered_mode = ABORT;
static int fake_missing_tagger;
+static int use_done_feature;
static int no_data;
static int full_tree;
@@ -178,6 +180,15 @@ static int depth_first(const void *a_, const void *b_)
return (a->status == 'R') - (b->status == 'R');
}
+static void print_path(const char *path)
+{
+ int need_quote = quote_c_style(path, NULL, NULL, 0);
+ if (need_quote)
+ quote_c_style(path, NULL, stdout, 0);
+ else
+ printf("%s", path);
+}
+
static void show_filemodify(struct diff_queue_struct *q,
struct diff_options *options, void *data)
{
@@ -195,13 +206,18 @@ static void show_filemodify(struct diff_queue_struct *q,
switch (q->queue[i]->status) {
case DIFF_STATUS_DELETED:
- printf("D %s\n", spec->path);
+ printf("D ");
+ print_path(spec->path);
+ putchar('\n');
break;
case DIFF_STATUS_COPIED:
case DIFF_STATUS_RENAMED:
- printf("%c \"%s\" \"%s\"\n", q->queue[i]->status,
- ospec->path, spec->path);
+ printf("%c ", q->queue[i]->status);
+ print_path(ospec->path);
+ putchar(' ');
+ print_path(spec->path);
+ putchar('\n');
if (!hashcmp(ospec->sha1, spec->sha1) &&
ospec->mode == spec->mode)
@@ -216,13 +232,15 @@ static void show_filemodify(struct diff_queue_struct *q,
* output the SHA-1 verbatim.
*/
if (no_data || S_ISGITLINK(spec->mode))
- printf("M %06o %s %s\n", spec->mode,
- sha1_to_hex(spec->sha1), spec->path);
+ printf("M %06o %s ", spec->mode,
+ sha1_to_hex(spec->sha1));
else {
struct object *object = lookup_object(spec->sha1);
- printf("M %06o :%d %s\n", spec->mode,
- get_object_mark(object), spec->path);
+ printf("M %06o :%d ", spec->mode,
+ get_object_mark(object));
}
+ print_path(spec->path);
+ putchar('\n');
break;
default:
@@ -627,6 +645,8 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
"Fake a tagger when tags lack one"),
OPT_BOOLEAN(0, "full-tree", &full_tree,
"Output full tree for each commit"),
+ OPT_BOOLEAN(0, "use-done-feature", &use_done_feature,
+ "Use the done feature to terminate the stream"),
{ OPTION_NEGBIT, 0, "data", &no_data, NULL,
"Skip output of blob data",
PARSE_OPT_NOARG | PARSE_OPT_NEGHELP, NULL, 1 },
@@ -648,6 +668,9 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
if (argc > 1)
usage_with_options (fast_export_usage, options);
+ if (use_done_feature)
+ printf("feature done\n");
+
if (import_filename)
import_marks(import_filename);
@@ -675,5 +698,8 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
if (export_filename)
export_marks(export_filename);
+ if (use_done_feature)
+ printf("done\n");
+
return 0;
}
diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c
index 4367984..c6bc8eb 100644
--- a/builtin/fetch-pack.c
+++ b/builtin/fetch-pack.c
@@ -15,7 +15,9 @@ static int transfer_unpack_limit = -1;
static int fetch_unpack_limit = -1;
static int unpack_limit = 100;
static int prefer_ofs_delta = 1;
-static int no_done = 0;
+static int no_done;
+static int fetch_fsck_objects = -1;
+static int transfer_fsck_objects = -1;
static struct fetch_pack_args args = {
/* .uploadpack = */ "git-upload-pack",
};
@@ -185,6 +187,36 @@ static void consume_shallow_list(int fd)
}
}
+struct write_shallow_data {
+ struct strbuf *out;
+ int use_pack_protocol;
+ int count;
+};
+
+static int write_one_shallow(const struct commit_graft *graft, void *cb_data)
+{
+ struct write_shallow_data *data = cb_data;
+ const char *hex = sha1_to_hex(graft->sha1);
+ data->count++;
+ if (data->use_pack_protocol)
+ packet_buf_write(data->out, "shallow %s", hex);
+ else {
+ strbuf_addstr(data->out, hex);
+ strbuf_addch(data->out, '\n');
+ }
+ return 0;
+}
+
+static int write_shallow_commits(struct strbuf *out, int use_pack_protocol)
+{
+ struct write_shallow_data data;
+ data.out = out;
+ data.use_pack_protocol = use_pack_protocol;
+ data.count = 0;
+ for_each_commit_graft(write_one_shallow, &data);
+ return data.count;
+}
+
static enum ack_type get_ack(int fd, unsigned char *result_sha1)
{
static char line[1000];
@@ -395,6 +427,8 @@ static int find_common(int fd[2], unsigned char *result_sha1,
case ACK_continue: {
struct commit *commit =
lookup_commit(result_sha1);
+ if (!commit)
+ die("invalid commit %s", sha1_to_hex(result_sha1));
if (args.stateless_rpc
&& ack == ACK_common
&& !(commit->object.flags & COMMON)) {
@@ -512,7 +546,7 @@ static void filter_refs(struct ref **refs, int nr_match, char **match)
for (ref = *refs; ref; ref = next) {
next = ref->next;
if (!memcmp(ref->name, "refs/", 5) &&
- check_ref_format(ref->name + 5))
+ check_refname_format(ref->name + 5, 0))
; /* trash */
else if (args.fetch_all &&
(!args.depth || prefixcmp(ref->name, "refs/tags/") )) {
@@ -702,6 +736,12 @@ static int get_pack(int xd[2], char **pack_lockfile)
}
if (*hdr_arg)
*av++ = hdr_arg;
+ if (fetch_fsck_objects >= 0
+ ? fetch_fsck_objects
+ : transfer_fsck_objects >= 0
+ ? transfer_fsck_objects
+ : 0)
+ *av++ = "--strict";
*av++ = NULL;
cmd.in = demux.out;
@@ -821,6 +861,16 @@ static int fetch_pack_config(const char *var, const char *value, void *cb)
return 0;
}
+ if (!strcmp(var, "fetch.fsckobjects")) {
+ fetch_fsck_objects = git_config_bool(var, value);
+ return 0;
+ }
+
+ if (!strcmp(var, "transfer.fsckobjects")) {
+ transfer_fsck_objects = git_config_bool(var, value);
+ return 0;
+ }
+
return git_default_config(var, value, cb);
}
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 93c9938..91731b9 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -13,6 +13,7 @@
#include "sigchain.h"
#include "transport.h"
#include "submodule.h"
+#include "connected.h"
static const char * const builtin_fetch_usage[] = {
"git fetch [<options>] [<repository> [<refspec>...]]",
@@ -345,6 +346,18 @@ static int update_local_ref(struct ref *ref,
}
}
+static int iterate_ref_map(void *cb_data, unsigned char sha1[20])
+{
+ struct ref **rm = cb_data;
+ struct ref *ref = *rm;
+
+ if (!ref)
+ return -1; /* end of the list */
+ *rm = ref->next;
+ hashcpy(sha1, ref->old_sha1);
+ return 0;
+}
+
static int store_updated_refs(const char *raw_url, const char *remote_name,
struct ref *ref_map)
{
@@ -364,6 +377,13 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
url = transport_anonymize_url(raw_url);
else
url = xstrdup("foreign");
+
+ rm = ref_map;
+ if (check_everything_connected(iterate_ref_map, 0, &rm)) {
+ rc = error(_("%s did not send all necessary objects\n"), url);
+ goto abort;
+ }
+
for (rm = ref_map; rm; rm = rm->next) {
struct ref *ref = NULL;
@@ -444,12 +464,15 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
fprintf(stderr, " %s\n", note);
}
}
- free(url);
- fclose(fp);
+
if (rc & STORE_REF_ERROR_DF_CONFLICT)
error(_("some local refs could not be updated; try running\n"
" 'git remote prune %s' to remove any old, conflicting "
"branches"), remote_name);
+
+ abort:
+ free(url);
+ fclose(fp);
return rc;
}
@@ -457,23 +480,10 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
* We would want to bypass the object transfer altogether if
* everything we are going to fetch already exists and is connected
* locally.
- *
- * The refs we are going to fetch are in ref_map. If running
- *
- * $ git rev-list --objects --stdin --not --all
- *
- * (feeding all the refs in ref_map on its standard input)
- * does not error out, that means everything reachable from the
- * refs we are going to fetch exists and is connected to some of
- * our existing refs.
*/
static int quickfetch(struct ref *ref_map)
{
- struct child_process revlist;
- struct ref *ref;
- int err;
- const char *argv[] = {"rev-list",
- "--quiet", "--objects", "--stdin", "--not", "--all", NULL};
+ struct ref *rm = ref_map;
/*
* If we are deepening a shallow clone we already have these
@@ -484,47 +494,7 @@ static int quickfetch(struct ref *ref_map)
*/
if (depth)
return -1;
-
- if (!ref_map)
- return 0;
-
- memset(&revlist, 0, sizeof(revlist));
- revlist.argv = argv;
- revlist.git_cmd = 1;
- revlist.no_stdout = 1;
- revlist.no_stderr = 1;
- revlist.in = -1;
-
- err = start_command(&revlist);
- if (err) {
- error(_("could not run rev-list"));
- return err;
- }
-
- /*
- * If rev-list --stdin encounters an unknown commit, it terminates,
- * which will cause SIGPIPE in the write loop below.
- */
- sigchain_push(SIGPIPE, SIG_IGN);
-
- for (ref = ref_map; ref; ref = ref->next) {
- if (write_in_full(revlist.in, sha1_to_hex(ref->old_sha1), 40) < 0 ||
- write_str_in_full(revlist.in, "\n") < 0) {
- if (errno != EPIPE && errno != EINVAL)
- error(_("failed write to rev-list: %s"), strerror(errno));
- err = -1;
- break;
- }
- }
-
- if (close(revlist.in)) {
- error(_("failed to close rev-list's stdin: %s"), strerror(errno));
- err = -1;
- }
-
- sigchain_pop(SIGPIPE);
-
- return finish_command(&revlist) || err;
+ return check_everything_connected(iterate_ref_map, 1, &rm);
}
static int fetch_refs(struct transport *transport, struct ref *ref_map)
@@ -540,10 +510,10 @@ static int fetch_refs(struct transport *transport, struct ref *ref_map)
return ret;
}
-static int prune_refs(struct transport *transport, struct ref *ref_map)
+static int prune_refs(struct refspec *refs, int ref_count, struct ref *ref_map)
{
int result = 0;
- struct ref *ref, *stale_refs = get_stale_heads(transport->remote, ref_map);
+ struct ref *ref, *stale_refs = get_stale_heads(refs, ref_count, ref_map);
const char *dangling_msg = dry_run
? _(" (%s will become dangling)\n")
: _(" (%s has become dangling)\n");
@@ -734,8 +704,31 @@ static int do_fetch(struct transport *transport,
free_refs(ref_map);
return 1;
}
- if (prune)
- prune_refs(transport, ref_map);
+ if (prune) {
+ /* If --tags was specified, pretend the user gave us the canonical tags refspec */
+ if (tags == TAGS_SET) {
+ const char *tags_str = "refs/tags/*:refs/tags/*";
+ struct refspec *tags_refspec, *refspec;
+
+ /* Copy the refspec and add the tags to it */
+ refspec = xcalloc(ref_count + 1, sizeof(struct refspec));
+ tags_refspec = parse_fetch_refspec(1, &tags_str);
+ memcpy(refspec, refs, ref_count * sizeof(struct refspec));
+ memcpy(&refspec[ref_count], tags_refspec, sizeof(struct refspec));
+ ref_count++;
+
+ prune_refs(refspec, ref_count, ref_map);
+
+ ref_count--;
+ /* The rest of the strings belong to fetch_one */
+ free_refspec(1, tags_refspec);
+ free(refspec);
+ } else if (ref_count) {
+ prune_refs(refs, ref_count, ref_map);
+ } else {
+ prune_refs(transport->remote->fetch, transport->remote->fetch_refspec_nr, ref_map);
+ }
+ }
free_refs(ref_map);
/* if neither --no-tags nor --tags was specified, do automated tag
@@ -918,7 +911,7 @@ static int fetch_one(struct remote *remote, int argc, const char **argv)
atexit(unlock_pack);
refspec = parse_fetch_refspec(ref_nr, refs);
exit_code = do_fetch(transport, refspec, ref_nr);
- free(refspec);
+ free_refspec(ref_nr, refspec);
transport_disconnect(transport);
transport = NULL;
return exit_code;
@@ -941,6 +934,15 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix,
builtin_fetch_options, builtin_fetch_usage, 0);
+ if (recurse_submodules != RECURSE_SUBMODULES_OFF) {
+ if (recurse_submodules_default) {
+ int arg = parse_fetch_recurse_submodules_arg("--recurse-submodules-default", recurse_submodules_default);
+ set_config_fetch_recurse_submodules(arg);
+ }
+ gitmodules_config();
+ git_config(submodule_config, NULL);
+ }
+
if (all) {
if (argc == 1)
die(_("fetch --all does not take a repository argument"));
@@ -976,12 +978,6 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
if (!result && (recurse_submodules != RECURSE_SUBMODULES_OFF)) {
const char *options[10];
int num_options = 0;
- if (recurse_submodules_default) {
- int arg = parse_fetch_recurse_submodules_arg("--recurse-submodules-default", recurse_submodules_default);
- set_config_fetch_recurse_submodules(arg);
- }
- gitmodules_config();
- git_config(submodule_config, NULL);
add_options_to_argv(&num_options, options);
result = fetch_populated_submodules(num_options, options,
submodule_prefix,
diff --git a/builtin/fmt-merge-msg.c b/builtin/fmt-merge-msg.c
index 7581632..7e2f225 100644
--- a/builtin/fmt-merge-msg.c
+++ b/builtin/fmt-merge-msg.c
@@ -293,7 +293,7 @@ static int do_fmt_merge_msg(int merge_title, struct strbuf *in,
struct commit *head;
struct rev_info rev;
- head = lookup_commit(head_sha1);
+ head = lookup_commit_or_die(head_sha1, "HEAD");
init_revisions(&rev, NULL);
rev.commit_format = CMIT_FMT_ONELINE;
rev.ignore_merges = 1;
diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c
index 89e75c6..d90e5d2 100644
--- a/builtin/for-each-ref.c
+++ b/builtin/for-each-ref.c
@@ -69,6 +69,9 @@ static struct {
{ "subject" },
{ "body" },
{ "contents" },
+ { "contents:subject" },
+ { "contents:body" },
+ { "contents:signature" },
{ "upstream" },
{ "symref" },
{ "flag" },
@@ -361,6 +364,18 @@ static const char *copy_email(const char *buf)
return xmemdupz(email, eoemail + 1 - email);
}
+static char *copy_subject(const char *buf, unsigned long len)
+{
+ char *r = xmemdupz(buf, len);
+ int i;
+
+ for (i = 0; i < len; i++)
+ if (r[i] == '\n')
+ r[i] = ' ';
+
+ return r;
+}
+
static void grab_date(const char *buf, struct atom_value *v, const char *atomname)
{
const char *eoemail = strstr(buf, "> ");
@@ -458,38 +473,56 @@ static void grab_person(const char *who, struct atom_value *val, int deref, stru
}
}
-static void find_subpos(const char *buf, unsigned long sz, const char **sub, const char **body)
+static void find_subpos(const char *buf, unsigned long sz,
+ const char **sub, unsigned long *sublen,
+ const char **body, unsigned long *bodylen,
+ unsigned long *nonsiglen,
+ const char **sig, unsigned long *siglen)
{
- while (*buf) {
- const char *eol = strchr(buf, '\n');
- if (!eol)
- return;
- if (eol[1] == '\n') {
- buf = eol + 1;
- break; /* found end of header */
- }
- buf = eol + 1;
+ const char *eol;
+ /* skip past header until we hit empty line */
+ while (*buf && *buf != '\n') {
+ eol = strchrnul(buf, '\n');
+ if (*eol)
+ eol++;
+ buf = eol;
}
+ /* skip any empty lines */
while (*buf == '\n')
buf++;
- if (!*buf)
- return;
- *sub = buf; /* first non-empty line */
- buf = strchr(buf, '\n');
- if (!buf) {
- *body = "";
- return; /* no body */
+
+ /* parse signature first; we might not even have a subject line */
+ *sig = buf + parse_signature(buf, strlen(buf));
+ *siglen = strlen(*sig);
+
+ /* subject is first non-empty line */
+ *sub = buf;
+ /* subject goes to first empty line */
+ while (buf < *sig && *buf && *buf != '\n') {
+ eol = strchrnul(buf, '\n');
+ if (*eol)
+ eol++;
+ buf = eol;
}
+ *sublen = buf - *sub;
+ /* drop trailing newline, if present */
+ if (*sublen && (*sub)[*sublen - 1] == '\n')
+ *sublen -= 1;
+
+ /* skip any empty lines */
while (*buf == '\n')
- buf++; /* skip blank between subject and body */
+ buf++;
*body = buf;
+ *bodylen = strlen(buf);
+ *nonsiglen = *sig - buf;
}
/* See grab_values */
static void grab_sub_body_contents(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
{
int i;
- const char *subpos = NULL, *bodypos = NULL;
+ const char *subpos = NULL, *bodypos = NULL, *sigpos = NULL;
+ unsigned long sublen = 0, bodylen = 0, nonsiglen = 0, siglen = 0;
for (i = 0; i < used_atom_cnt; i++) {
const char *name = used_atom[i];
@@ -500,17 +533,27 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, struct obj
name++;
if (strcmp(name, "subject") &&
strcmp(name, "body") &&
- strcmp(name, "contents"))
+ strcmp(name, "contents") &&
+ strcmp(name, "contents:subject") &&
+ strcmp(name, "contents:body") &&
+ strcmp(name, "contents:signature"))
continue;
if (!subpos)
- find_subpos(buf, sz, &subpos, &bodypos);
- if (!subpos)
- return;
+ find_subpos(buf, sz,
+ &subpos, &sublen,
+ &bodypos, &bodylen, &nonsiglen,
+ &sigpos, &siglen);
if (!strcmp(name, "subject"))
- v->s = copy_line(subpos);
+ v->s = copy_subject(subpos, sublen);
+ else if (!strcmp(name, "contents:subject"))
+ v->s = copy_subject(subpos, sublen);
else if (!strcmp(name, "body"))
- v->s = xstrdup(bodypos);
+ v->s = xmemdupz(bodypos, bodylen);
+ else if (!strcmp(name, "contents:body"))
+ v->s = xmemdupz(bodypos, nonsiglen);
+ else if (!strcmp(name, "contents:signature"))
+ v->s = xmemdupz(sigpos, siglen);
else if (!strcmp(name, "contents"))
v->s = xstrdup(subpos);
}
diff --git a/builtin/fsck.c b/builtin/fsck.c
index 5ae0366..30d0dc8 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -11,6 +11,7 @@
#include "fsck.h"
#include "parse-options.h"
#include "dir.h"
+#include "progress.h"
#define REACHABLE 0x0001
#define SEEN 0x0002
@@ -27,8 +28,10 @@ static const char *head_points_at;
static int errors_found;
static int write_lost_and_found;
static int verbose;
+static int show_progress = -1;
#define ERROR_OBJECT 01
#define ERROR_REACHABLE 02
+#define ERROR_PACK 04
#ifdef NO_D_INO_IN_DIRENT
#define SORT_DIRENT 0
@@ -137,7 +140,11 @@ static int traverse_one_object(struct object *obj)
static int traverse_reachable(void)
{
+ struct progress *progress = NULL;
+ unsigned int nr = 0;
int result = 0;
+ if (show_progress)
+ progress = start_progress_delay("Checking connectivity", 0, 0, 2);
while (pending.nr) {
struct object_array_entry *entry;
struct object *obj;
@@ -145,7 +152,9 @@ static int traverse_reachable(void)
entry = pending.objects + --pending.nr;
obj = entry->item;
result |= traverse_one_object(obj);
+ display_progress(progress, ++nr);
}
+ stop_progress(&progress);
return !!result;
}
@@ -231,12 +240,9 @@ static void check_unreachable_object(struct object *obj)
unsigned long size;
char *buf = read_sha1_file(obj->sha1,
&type, &size);
- if (buf) {
- if (fwrite(buf, size, 1, f) != 1)
- die_errno("Could not write '%s'",
- filename);
- free(buf);
- }
+ if (buf && fwrite(buf, 1, size, f) != size)
+ die_errno("Could not write '%s'", filename);
+ free(buf);
} else
fprintf(f, "%s\n", sha1_to_hex(obj->sha1));
if (fclose(f))
@@ -284,14 +290,8 @@ static void check_connectivity(void)
}
}
-static int fsck_sha1(const unsigned char *sha1)
+static int fsck_obj(struct object *obj)
{
- struct object *obj = parse_object(sha1);
- if (!obj) {
- errors_found |= ERROR_OBJECT;
- return error("%s: object corrupt or missing",
- sha1_to_hex(sha1));
- }
if (obj->flags & SEEN)
return 0;
obj->flags |= SEEN;
@@ -334,6 +334,29 @@ static int fsck_sha1(const unsigned char *sha1)
return 0;
}
+static int fsck_sha1(const unsigned char *sha1)
+{
+ struct object *obj = parse_object(sha1);
+ if (!obj) {
+ errors_found |= ERROR_OBJECT;
+ return error("%s: object corrupt or missing",
+ sha1_to_hex(sha1));
+ }
+ return fsck_obj(obj);
+}
+
+static int fsck_obj_buffer(const unsigned char *sha1, enum object_type type,
+ unsigned long size, void *buffer, int *eaten)
+{
+ struct object *obj;
+ obj = parse_object_buffer(sha1, type, size, buffer, eaten);
+ if (!obj) {
+ errors_found |= ERROR_OBJECT;
+ return error("%s: object corrupt or missing", sha1_to_hex(sha1));
+ }
+ return fsck_obj(obj);
+}
+
/*
* This is the sorting chunk size: make it reasonably
* big so that we can sort well..
@@ -515,15 +538,20 @@ static void get_default_heads(void)
static void fsck_object_dir(const char *path)
{
int i;
+ struct progress *progress = NULL;
if (verbose)
fprintf(stderr, "Checking object directory\n");
+ if (show_progress)
+ progress = start_progress("Checking object directories", 256);
for (i = 0; i < 256; i++) {
static char dir[4096];
sprintf(dir, "%s/%02x", path, i);
fsck_dir(i, dir);
+ display_progress(progress, i+1);
}
+ stop_progress(&progress);
fsck_sha1_list();
}
@@ -594,6 +622,7 @@ static struct option fsck_opts[] = {
OPT_BOOLEAN(0, "strict", &check_strict, "enable more strict checking"),
OPT_BOOLEAN(0, "lost-found", &write_lost_and_found,
"write dangling objects in .git/lost-found"),
+ OPT_BOOL(0, "progress", &show_progress, "show progress"),
OPT_END(),
};
@@ -606,6 +635,12 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
read_replace_refs = 0;
argc = parse_options(argc, argv, prefix, fsck_opts, fsck_usage, 0);
+
+ if (show_progress == -1)
+ show_progress = isatty(2);
+ if (verbose)
+ show_progress = 0;
+
if (write_lost_and_found) {
check_full = 1;
include_reflogs = 0;
@@ -625,20 +660,28 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
if (check_full) {
struct packed_git *p;
+ uint32_t total = 0, count = 0;
+ struct progress *progress = NULL;
prepare_packed_git();
- for (p = packed_git; p; p = p->next)
- /* verify gives error messages itself */
- verify_pack(p);
+ if (show_progress) {
+ for (p = packed_git; p; p = p->next) {
+ if (open_pack_index(p))
+ continue;
+ total += p->num_objects;
+ }
+
+ progress = start_progress("Checking objects", total);
+ }
for (p = packed_git; p; p = p->next) {
- uint32_t j, num;
- if (open_pack_index(p))
- continue;
- num = p->num_objects;
- for (j = 0; j < num; j++)
- fsck_sha1(nth_packed_object_sha1(p, j));
+ /* verify gives error messages itself */
+ if (verify_pack(p, fsck_obj_buffer,
+ progress, count))
+ errors_found |= ERROR_PACK;
+ count += p->num_objects;
}
+ stop_progress(&progress);
}
heads = 0;
diff --git a/builtin/gc.c b/builtin/gc.c
index 0498094..271376d 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -32,7 +32,7 @@ static const char *prune_expire = "2.weeks.ago";
static const char *argv_pack_refs[] = {"pack-refs", "--all", "--prune", NULL};
static const char *argv_reflog[] = {"reflog", "expire", "--all", NULL};
static const char *argv_repack[MAX_ADD] = {"repack", "-d", "-l", NULL};
-static const char *argv_prune[] = {"prune", "--expire", NULL, NULL};
+static const char *argv_prune[] = {"prune", "--expire", NULL, NULL, NULL};
static const char *argv_rerere[] = {"rerere", "gc", NULL};
static int gc_config(const char *var, const char *value, void *cb)
@@ -243,6 +243,8 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
if (prune_expire) {
argv_prune[2] = prune_expire;
+ if (quiet)
+ argv_prune[3] = "--no-progress";
if (run_command_v_opt(argv_prune, RUN_GIT_CMD))
return error(FAILED_RUN, argv_prune[0]);
}
diff --git a/builtin/grep.c b/builtin/grep.c
index 871afaa..988ea1d 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -74,13 +74,32 @@ static int all_work_added;
/* This lock protects all the variables above. */
static pthread_mutex_t grep_mutex;
+static inline void grep_lock(void)
+{
+ if (use_threads)
+ pthread_mutex_lock(&grep_mutex);
+}
+
+static inline void grep_unlock(void)
+{
+ if (use_threads)
+ pthread_mutex_unlock(&grep_mutex);
+}
+
/* Used to serialize calls to read_sha1_file. */
static pthread_mutex_t read_sha1_mutex;
-#define grep_lock() pthread_mutex_lock(&grep_mutex)
-#define grep_unlock() pthread_mutex_unlock(&grep_mutex)
-#define read_sha1_lock() pthread_mutex_lock(&read_sha1_mutex)
-#define read_sha1_unlock() pthread_mutex_unlock(&read_sha1_mutex)
+static inline void read_sha1_lock(void)
+{
+ if (use_threads)
+ pthread_mutex_lock(&read_sha1_mutex);
+}
+
+static inline void read_sha1_unlock(void)
+{
+ if (use_threads)
+ pthread_mutex_unlock(&read_sha1_mutex);
+}
/* Signalled when a new work_item is added to todo. */
static pthread_cond_t cond_add;
@@ -93,8 +112,7 @@ static pthread_cond_t cond_write;
/* Signalled when we are finished with everything. */
static pthread_cond_t cond_result;
-static int print_hunk_marks_between_files;
-static int printed_something;
+static int skip_first_line;
static void add_work(enum work_type type, char *name, void *id)
{
@@ -160,10 +178,20 @@ static void work_done(struct work_item *w)
todo_done = (todo_done+1) % ARRAY_SIZE(todo)) {
w = &todo[todo_done];
if (w->out.len) {
- if (print_hunk_marks_between_files && printed_something)
- write_or_die(1, "--\n", 3);
- write_or_die(1, w->out.buf, w->out.len);
- printed_something = 1;
+ const char *p = w->out.buf;
+ size_t len = w->out.len;
+
+ /* Skip the leading hunk mark of the first file. */
+ if (skip_first_line) {
+ while (len) {
+ len--;
+ if (*p++ == '\n')
+ break;
+ }
+ skip_first_line = 0;
+ }
+
+ write_or_die(1, p, len);
}
free(w->name);
free(w->identifier);
@@ -316,7 +344,7 @@ static int grep_config(const char *var, const char *value, void *cb)
}
if (!strcmp(var, "color.grep"))
- opt->color = git_config_colorbool(var, value, -1);
+ opt->color = git_config_colorbool(var, value);
else if (!strcmp(var, "color.grep.context"))
color = opt->color_context;
else if (!strcmp(var, "color.grep.filename"))
@@ -345,13 +373,9 @@ static void *lock_and_read_sha1_file(const unsigned char *sha1, enum object_type
{
void *data;
- if (use_threads) {
- read_sha1_lock();
- data = read_sha1_file(sha1, type, size);
- read_sha1_unlock();
- } else {
- data = read_sha1_file(sha1, type, size);
- }
+ read_sha1_lock();
+ data = read_sha1_file(sha1, type, size);
+ read_sha1_unlock();
return data;
}
@@ -533,18 +557,19 @@ static int grep_cache(struct grep_opt *opt, const struct pathspec *pathspec, int
static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
struct tree_desc *tree, struct strbuf *base, int tn_len)
{
- int hit = 0, match = 0;
+ int hit = 0;
+ enum interesting match = entry_not_interesting;
struct name_entry entry;
int old_baselen = base->len;
while (tree_entry(tree, &entry)) {
- int te_len = tree_entry_len(entry.path, entry.sha1);
+ int te_len = tree_entry_len(&entry);
- if (match != 2) {
+ if (match != all_entries_interesting) {
match = tree_entry_interesting(&entry, base, tn_len, pathspec);
- if (match < 0)
+ if (match == all_entries_not_interesting)
break;
- if (match == 0)
+ if (match == entry_not_interesting)
continue;
}
@@ -589,8 +614,11 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
struct strbuf base;
int hit, len;
+ read_sha1_lock();
data = read_object_with_reference(obj->sha1, tree_type,
&size, NULL);
+ read_sha1_unlock();
+
if (!data)
die(_("unable to read tree (%s)"), sha1_to_hex(obj->sha1));
@@ -628,13 +656,15 @@ static int grep_objects(struct grep_opt *opt, const struct pathspec *pathspec,
return hit;
}
-static int grep_directory(struct grep_opt *opt, const struct pathspec *pathspec)
+static int grep_directory(struct grep_opt *opt, const struct pathspec *pathspec,
+ int exc_std)
{
struct dir_struct dir;
int i, hit = 0;
memset(&dir, 0, sizeof(dir));
- setup_standard_excludes(&dir);
+ if (exc_std)
+ setup_standard_excludes(&dir);
fill_directory(&dir, pathspec->raw);
for (i = 0; i < dir.nr; i++) {
@@ -741,7 +771,7 @@ static int help_callback(const struct option *opt, const char *arg, int unset)
int cmd_grep(int argc, const char **argv, const char *prefix)
{
int hit = 0;
- int cached = 0;
+ int cached = 0, untracked = 0, opt_exclude = -1;
int seen_dashdash = 0;
int external_grep_allowed__ignored;
const char *show_in_pager = NULL, *default_pager = "dummy";
@@ -765,8 +795,13 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
struct option options[] = {
OPT_BOOLEAN(0, "cached", &cached,
"search in index instead of in the work tree"),
- OPT_BOOLEAN(0, "index", &use_index,
- "--no-index finds in contents not managed by git"),
+ { OPTION_BOOLEAN, 0, "index", &use_index, NULL,
+ "finds in contents not managed by git",
+ PARSE_OPT_NOARG | PARSE_OPT_NEGHELP },
+ OPT_BOOLEAN(0, "untracked", &untracked,
+ "search in both tracked and untracked files"),
+ OPT_SET_INT(0, "exclude-standard", &opt_exclude,
+ "search also in ignored files", 1),
OPT_GROUP(""),
OPT_BOOLEAN('v', "invert-match", &opt.invert,
"show non-matching lines"),
@@ -813,18 +848,24 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
OPT_BOOLEAN('c', "count", &opt.count,
"show the number of matches instead of matching lines"),
OPT__COLOR(&opt.color, "highlight matches"),
+ OPT_BOOLEAN(0, "break", &opt.file_break,
+ "print empty line between matches from different files"),
+ OPT_BOOLEAN(0, "heading", &opt.heading,
+ "show filename only once above matches from same file"),
OPT_GROUP(""),
- OPT_CALLBACK('C', NULL, &opt, "n",
+ OPT_CALLBACK('C', "context", &opt, "n",
"show <n> context lines before and after matches",
context_callback),
- OPT_INTEGER('B', NULL, &opt.pre_context,
+ OPT_INTEGER('B', "before-context", &opt.pre_context,
"show <n> context lines before matches"),
- OPT_INTEGER('A', NULL, &opt.post_context,
+ OPT_INTEGER('A', "after-context", &opt.post_context,
"show <n> context lines after matches"),
OPT_NUMBER_CALLBACK(&opt, "shortcut for -C NUM",
context_callback),
OPT_BOOLEAN('p', "show-function", &opt.funcname,
"show a line with the function name before matches"),
+ OPT_BOOLEAN('W', "function-context", &opt.funcbody,
+ "show the surrounding function"),
OPT_GROUP(""),
OPT_CALLBACK('f', NULL, &opt, "file",
"read patterns from file", file_callback),
@@ -883,8 +924,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
strcpy(opt.color_sep, GIT_COLOR_CYAN);
opt.color = -1;
git_config(grep_config, &opt);
- if (opt.color == -1)
- opt.color = git_use_color_default;
/*
* If there is no -- then the paths must exist in the working
@@ -967,8 +1006,9 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
use_threads = 0;
if (use_threads) {
- if (opt.pre_context || opt.post_context)
- print_hunk_marks_between_files = 1;
+ if (opt.pre_context || opt.post_context || opt.file_break ||
+ opt.funcbody)
+ skip_first_line = 1;
start_threads(&opt);
}
#else
@@ -1031,13 +1071,16 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
if (!show_in_pager)
setup_pager();
+ if (!use_index && (untracked || cached))
+ die(_("--cached or --untracked cannot be used with --no-index."));
- if (!use_index) {
- if (cached)
- die(_("--cached cannot be used with --no-index."));
+ if (!use_index || untracked) {
+ int use_exclude = (opt_exclude < 0) ? use_index : !!opt_exclude;
if (list.nr)
- die(_("--no-index cannot be used with revs."));
- hit = grep_directory(&opt, &pathspec);
+ die(_("--no-index or --untracked cannot be used with revs."));
+ hit = grep_directory(&opt, &pathspec, use_exclude);
+ } else if (0 <= opt_exclude) {
+ die(_("--[no-]exclude-standard cannot be used for tracked contents."));
} else if (!list.nr) {
if (!cached)
setup_work_tree();
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index e40451f..98025da 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -11,7 +11,7 @@
#include "exec_cmd.h"
static const char index_pack_usage[] =
-"git index-pack [-v] [-o <index-file>] [ --keep | --keep=<msg> ] [--strict] (<pack-file> | --stdin [--fix-thin] [<pack-file>])";
+"git index-pack [-v] [-o <index-file>] [--keep | --keep=<msg>] [--verify] [--strict] (<pack-file> | --stdin [--fix-thin] [<pack-file>])";
struct object_entry {
struct pack_idx_entry idx;
@@ -19,6 +19,8 @@ struct object_entry {
unsigned int hdr_size;
enum object_type type;
enum object_type real_type;
+ unsigned delta_depth;
+ int base_object_no;
};
union delta_base {
@@ -66,6 +68,7 @@ static struct progress *progress;
static unsigned char input_buffer[4096];
static unsigned int input_offset, input_len;
static off_t consumed_bytes;
+static unsigned deepest_delta;
static git_SHA_CTX input_ctx;
static uint32_t input_crc32;
static int input_fd, output_fd, pack_fd;
@@ -265,7 +268,7 @@ static void unlink_base_data(struct base_data *c)
static void *unpack_entry_data(unsigned long offset, unsigned long size)
{
int status;
- z_stream stream;
+ git_zstream stream;
void *buf = xmalloc(size);
memset(&stream, 0, sizeof(stream));
@@ -355,7 +358,7 @@ static void *get_data_from_pack(struct object_entry *obj)
off_t from = obj[0].idx.offset + obj[0].hdr_size;
unsigned long len = obj[1].idx.offset - from;
unsigned char *data, *inbuf;
- z_stream stream;
+ git_zstream stream;
int status;
data = xmalloc(obj->size);
@@ -389,7 +392,18 @@ static void *get_data_from_pack(struct object_entry *obj)
return data;
}
-static int find_delta(const union delta_base *base)
+static int compare_delta_bases(const union delta_base *base1,
+ const union delta_base *base2,
+ enum object_type type1,
+ enum object_type type2)
+{
+ int cmp = type1 - type2;
+ if (cmp)
+ return cmp;
+ return memcmp(base1, base2, UNION_BASE_SZ);
+}
+
+static int find_delta(const union delta_base *base, enum object_type type)
{
int first = 0, last = nr_deltas;
@@ -398,7 +412,8 @@ static int find_delta(const union delta_base *base)
struct delta_entry *delta = &deltas[next];
int cmp;
- cmp = memcmp(base, &delta->base, UNION_BASE_SZ);
+ cmp = compare_delta_bases(base, &delta->base,
+ type, objects[delta->obj_no].type);
if (!cmp)
return next;
if (cmp < 0) {
@@ -411,9 +426,10 @@ static int find_delta(const union delta_base *base)
}
static void find_delta_children(const union delta_base *base,
- int *first_index, int *last_index)
+ int *first_index, int *last_index,
+ enum object_type type)
{
- int first = find_delta(base);
+ int first = find_delta(base, type);
int last = first;
int end = nr_deltas - 1;
@@ -483,12 +499,17 @@ static void sha1_object(const void *data, unsigned long size,
}
}
+static int is_delta_type(enum object_type type)
+{
+ return (type == OBJ_REF_DELTA || type == OBJ_OFS_DELTA);
+}
+
static void *get_base_data(struct base_data *c)
{
if (!c->data) {
struct object_entry *obj = c->obj;
- if (obj->type == OBJ_REF_DELTA || obj->type == OBJ_OFS_DELTA) {
+ if (is_delta_type(obj->type)) {
void *base = get_base_data(c->base);
void *raw = get_data_from_pack(obj);
c->data = patch_delta(
@@ -515,6 +536,10 @@ static void resolve_delta(struct object_entry *delta_obj,
void *base_data, *delta_data;
delta_obj->real_type = base->obj->real_type;
+ delta_obj->delta_depth = base->obj->delta_depth + 1;
+ if (deepest_delta < delta_obj->delta_depth)
+ deepest_delta = delta_obj->delta_depth;
+ delta_obj->base_object_no = base->obj - objects;
delta_data = get_data_from_pack(delta_obj);
base_data = get_base_data(base);
result->obj = delta_obj;
@@ -541,11 +566,13 @@ static void find_unresolved_deltas(struct base_data *base,
union delta_base base_spec;
hashcpy(base_spec.sha1, base->obj->idx.sha1);
- find_delta_children(&base_spec, &ref_first, &ref_last);
+ find_delta_children(&base_spec,
+ &ref_first, &ref_last, OBJ_REF_DELTA);
memset(&base_spec, 0, sizeof(base_spec));
base_spec.offset = base->obj->idx.offset;
- find_delta_children(&base_spec, &ofs_first, &ofs_last);
+ find_delta_children(&base_spec,
+ &ofs_first, &ofs_last, OBJ_OFS_DELTA);
}
if (ref_last == -1 && ofs_last == -1) {
@@ -557,24 +584,24 @@ static void find_unresolved_deltas(struct base_data *base,
for (i = ref_first; i <= ref_last; i++) {
struct object_entry *child = objects + deltas[i].obj_no;
- if (child->real_type == OBJ_REF_DELTA) {
- struct base_data result;
- resolve_delta(child, base, &result);
- if (i == ref_last && ofs_last == -1)
- free_base_data(base);
- find_unresolved_deltas(&result, base);
- }
+ struct base_data result;
+
+ assert(child->real_type == OBJ_REF_DELTA);
+ resolve_delta(child, base, &result);
+ if (i == ref_last && ofs_last == -1)
+ free_base_data(base);
+ find_unresolved_deltas(&result, base);
}
for (i = ofs_first; i <= ofs_last; i++) {
struct object_entry *child = objects + deltas[i].obj_no;
- if (child->real_type == OBJ_OFS_DELTA) {
- struct base_data result;
- resolve_delta(child, base, &result);
- if (i == ofs_last)
- free_base_data(base);
- find_unresolved_deltas(&result, base);
- }
+ struct base_data result;
+
+ assert(child->real_type == OBJ_OFS_DELTA);
+ resolve_delta(child, base, &result);
+ if (i == ofs_last)
+ free_base_data(base);
+ find_unresolved_deltas(&result, base);
}
unlink_base_data(base);
@@ -584,7 +611,11 @@ static int compare_delta_entry(const void *a, const void *b)
{
const struct delta_entry *delta_a = a;
const struct delta_entry *delta_b = b;
- return memcmp(&delta_a->base, &delta_b->base, UNION_BASE_SZ);
+
+ /* group by type (ref vs ofs) and then by value (sha-1 or offset) */
+ return compare_delta_bases(&delta_a->base, &delta_b->base,
+ objects[delta_a->obj_no].type,
+ objects[delta_b->obj_no].type);
}
/* Parse all objects and return the pack content SHA1 hash */
@@ -608,7 +639,7 @@ static void parse_pack_objects(unsigned char *sha1)
struct object_entry *obj = &objects[i];
void *data = unpack_raw_entry(obj, &delta->base);
obj->real_type = obj->type;
- if (obj->type == OBJ_REF_DELTA || obj->type == OBJ_OFS_DELTA) {
+ if (is_delta_type(obj->type)) {
nr_deltas++;
delta->obj_no = i;
delta++;
@@ -655,7 +686,7 @@ static void parse_pack_objects(unsigned char *sha1)
struct object_entry *obj = &objects[i];
struct base_data base_obj;
- if (obj->type == OBJ_REF_DELTA || obj->type == OBJ_OFS_DELTA)
+ if (is_delta_type(obj->type))
continue;
base_obj.obj = obj;
base_obj.data = NULL;
@@ -666,26 +697,26 @@ static void parse_pack_objects(unsigned char *sha1)
static int write_compressed(struct sha1file *f, void *in, unsigned int size)
{
- z_stream stream;
+ git_zstream stream;
int status;
unsigned char outbuf[4096];
memset(&stream, 0, sizeof(stream));
- deflateInit(&stream, zlib_compression_level);
+ git_deflate_init(&stream, zlib_compression_level);
stream.next_in = in;
stream.avail_in = size;
do {
stream.next_out = outbuf;
stream.avail_out = sizeof(outbuf);
- status = deflate(&stream, Z_FINISH);
+ status = git_deflate(&stream, Z_FINISH);
sha1write(f, outbuf, sizeof(outbuf) - stream.avail_out);
} while (status == Z_OK);
if (status != Z_STREAM_END)
die("unable to deflate appended object (%d)", status);
size = stream.total_out;
- deflateEnd(&stream);
+ git_deflate_end(&stream);
return size;
}
@@ -859,24 +890,137 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
static int git_index_pack_config(const char *k, const char *v, void *cb)
{
+ struct pack_idx_option *opts = cb;
+
if (!strcmp(k, "pack.indexversion")) {
- pack_idx_default_version = git_config_int(k, v);
- if (pack_idx_default_version > 2)
- die("bad pack.indexversion=%"PRIu32,
- pack_idx_default_version);
+ opts->version = git_config_int(k, v);
+ if (opts->version > 2)
+ die("bad pack.indexversion=%"PRIu32, opts->version);
return 0;
}
return git_default_config(k, v, cb);
}
+static int cmp_uint32(const void *a_, const void *b_)
+{
+ uint32_t a = *((uint32_t *)a_);
+ uint32_t b = *((uint32_t *)b_);
+
+ return (a < b) ? -1 : (a != b);
+}
+
+static void read_v2_anomalous_offsets(struct packed_git *p,
+ struct pack_idx_option *opts)
+{
+ const uint32_t *idx1, *idx2;
+ uint32_t i;
+
+ /* The address of the 4-byte offset table */
+ idx1 = (((const uint32_t *)p->index_data)
+ + 2 /* 8-byte header */
+ + 256 /* fan out */
+ + 5 * p->num_objects /* 20-byte SHA-1 table */
+ + p->num_objects /* CRC32 table */
+ );
+
+ /* The address of the 8-byte offset table */
+ idx2 = idx1 + p->num_objects;
+
+ for (i = 0; i < p->num_objects; i++) {
+ uint32_t off = ntohl(idx1[i]);
+ if (!(off & 0x80000000))
+ continue;
+ off = off & 0x7fffffff;
+ if (idx2[off * 2])
+ continue;
+ /*
+ * The real offset is ntohl(idx2[off * 2]) in high 4
+ * octets, and ntohl(idx2[off * 2 + 1]) in low 4
+ * octets. But idx2[off * 2] is Zero!!!
+ */
+ ALLOC_GROW(opts->anomaly, opts->anomaly_nr + 1, opts->anomaly_alloc);
+ opts->anomaly[opts->anomaly_nr++] = ntohl(idx2[off * 2 + 1]);
+ }
+
+ if (1 < opts->anomaly_nr)
+ qsort(opts->anomaly, opts->anomaly_nr, sizeof(uint32_t), cmp_uint32);
+}
+
+static void read_idx_option(struct pack_idx_option *opts, const char *pack_name)
+{
+ struct packed_git *p = add_packed_git(pack_name, strlen(pack_name), 1);
+
+ if (!p)
+ die("Cannot open existing pack file '%s'", pack_name);
+ if (open_pack_index(p))
+ die("Cannot open existing pack idx file for '%s'", pack_name);
+
+ /* Read the attributes from the existing idx file */
+ opts->version = p->index_version;
+
+ if (opts->version == 2)
+ read_v2_anomalous_offsets(p, opts);
+
+ /*
+ * Get rid of the idx file as we do not need it anymore.
+ * NEEDSWORK: extract this bit from free_pack_by_name() in
+ * sha1_file.c, perhaps? It shouldn't matter very much as we
+ * know we haven't installed this pack (hence we never have
+ * read anything from it).
+ */
+ close_pack_index(p);
+ free(p);
+}
+
+static void show_pack_info(int stat_only)
+{
+ int i, baseobjects = nr_objects - nr_deltas;
+ unsigned long *chain_histogram = NULL;
+
+ if (deepest_delta)
+ chain_histogram = xcalloc(deepest_delta, sizeof(unsigned long));
+
+ for (i = 0; i < nr_objects; i++) {
+ struct object_entry *obj = &objects[i];
+
+ if (is_delta_type(obj->type))
+ chain_histogram[obj->delta_depth - 1]++;
+ if (stat_only)
+ continue;
+ printf("%s %-6s %lu %lu %"PRIuMAX,
+ sha1_to_hex(obj->idx.sha1),
+ typename(obj->real_type), obj->size,
+ (unsigned long)(obj[1].idx.offset - obj->idx.offset),
+ (uintmax_t)obj->idx.offset);
+ if (is_delta_type(obj->type)) {
+ struct object_entry *bobj = &objects[obj->base_object_no];
+ printf(" %u %s", obj->delta_depth, sha1_to_hex(bobj->idx.sha1));
+ }
+ putchar('\n');
+ }
+
+ if (baseobjects)
+ printf("non delta: %d object%s\n",
+ baseobjects, baseobjects > 1 ? "s" : "");
+ for (i = 0; i < deepest_delta; i++) {
+ if (!chain_histogram[i])
+ continue;
+ printf("chain length = %d: %lu object%s\n",
+ i + 1,
+ chain_histogram[i],
+ chain_histogram[i] > 1 ? "s" : "");
+ }
+}
+
int cmd_index_pack(int argc, const char **argv, const char *prefix)
{
- int i, fix_thin_pack = 0;
+ int i, fix_thin_pack = 0, verify = 0, stat_only = 0, stat = 0;
const char *curr_pack, *curr_index;
const char *index_name = NULL, *pack_name = NULL;
const char *keep_name = NULL, *keep_msg = NULL;
char *index_name_buf = NULL, *keep_name_buf = NULL;
struct pack_idx_entry **idx_objects;
+ struct pack_idx_option opts;
unsigned char pack_sha1[20];
if (argc == 2 && !strcmp(argv[1], "-h"))
@@ -884,7 +1028,8 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
read_replace_refs = 0;
- git_config(git_index_pack_config, NULL);
+ reset_pack_idx_option(&opts);
+ git_config(git_index_pack_config, &opts);
if (prefix && chdir(prefix))
die("Cannot come back to cwd");
@@ -898,6 +1043,15 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
fix_thin_pack = 1;
} else if (!strcmp(arg, "--strict")) {
strict = 1;
+ } else if (!strcmp(arg, "--verify")) {
+ verify = 1;
+ } else if (!strcmp(arg, "--verify-stat")) {
+ verify = 1;
+ stat = 1;
+ } else if (!strcmp(arg, "--verify-stat-only")) {
+ verify = 1;
+ stat = 1;
+ stat_only = 1;
} else if (!strcmp(arg, "--keep")) {
keep_msg = "";
} else if (!prefixcmp(arg, "--keep=")) {
@@ -923,12 +1077,12 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
index_name = argv[++i];
} else if (!prefixcmp(arg, "--index-version=")) {
char *c;
- pack_idx_default_version = strtoul(arg + 16, &c, 10);
- if (pack_idx_default_version > 2)
+ opts.version = strtoul(arg + 16, &c, 10);
+ if (opts.version > 2)
die("bad %s", arg);
if (*c == ',')
- pack_idx_off32_limit = strtoul(c+1, &c, 0);
- if (*c || pack_idx_off32_limit & 0x80000000)
+ opts.off32_limit = strtoul(c+1, &c, 0);
+ if (*c || opts.off32_limit & 0x80000000)
die("bad %s", arg);
} else
usage(index_pack_usage);
@@ -964,11 +1118,19 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
strcpy(keep_name_buf + len - 5, ".keep");
keep_name = keep_name_buf;
}
+ if (verify) {
+ if (!index_name)
+ die("--verify with no packfile name given");
+ read_idx_option(&opts, index_name);
+ opts.flags |= WRITE_IDX_VERIFY | WRITE_IDX_STRICT;
+ }
+ if (strict)
+ opts.flags |= WRITE_IDX_STRICT;
curr_pack = open_pack_file(pack_name);
parse_pack_header();
- objects = xmalloc((nr_objects + 1) * sizeof(struct object_entry));
- deltas = xmalloc(nr_objects * sizeof(struct delta_entry));
+ objects = xcalloc(nr_objects + 1, sizeof(struct object_entry));
+ deltas = xcalloc(nr_objects, sizeof(struct delta_entry));
parse_pack_objects(pack_sha1);
if (nr_deltas == nr_resolved_deltas) {
stop_progress(&progress);
@@ -1008,16 +1170,22 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
if (strict)
check_objects();
+ if (stat)
+ show_pack_info(stat_only);
+
idx_objects = xmalloc((nr_objects) * sizeof(struct pack_idx_entry *));
for (i = 0; i < nr_objects; i++)
idx_objects[i] = &objects[i].idx;
- curr_index = write_idx_file(index_name, idx_objects, nr_objects, pack_sha1);
+ curr_index = write_idx_file(index_name, idx_objects, nr_objects, &opts, pack_sha1);
free(idx_objects);
- final(pack_name, curr_pack,
- index_name, curr_index,
- keep_name, keep_msg,
- pack_sha1);
+ if (!verify)
+ final(pack_name, curr_pack,
+ index_name, curr_index,
+ keep_name, keep_msg,
+ pack_sha1);
+ else
+ close(input_fd);
free(objects);
free(index_name_buf);
free(keep_name_buf);
diff --git a/builtin/init-db.c b/builtin/init-db.c
index 025aa47..d07554c 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -347,7 +347,7 @@ static void separate_git_dir(const char *git_dir)
const char *src;
if (S_ISREG(st.st_mode))
- src = read_gitfile_gently(git_link);
+ src = read_gitfile(git_link);
else if (S_ISDIR(st.st_mode))
src = git_link;
else
diff --git a/builtin/log.c b/builtin/log.c
index 5c2af59..f5d4930 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -359,9 +359,6 @@ int cmd_whatchanged(int argc, const char **argv, const char *prefix)
git_config(git_log_config, NULL);
- if (diff_use_color_default == -1)
- diff_use_color_default = git_use_color_default;
-
init_revisions(&rev, prefix);
rev.diff = 1;
rev.simplify_history = 0;
@@ -446,9 +443,6 @@ int cmd_show(int argc, const char **argv, const char *prefix)
git_config(git_log_config, NULL);
- if (diff_use_color_default == -1)
- diff_use_color_default = git_use_color_default;
-
init_pathspec(&match_all, NULL);
init_revisions(&rev, prefix);
rev.diff = 1;
@@ -524,9 +518,6 @@ int cmd_log_reflog(int argc, const char **argv, const char *prefix)
git_config(git_log_config, NULL);
- if (diff_use_color_default == -1)
- diff_use_color_default = git_use_color_default;
-
init_revisions(&rev, prefix);
init_reflog_walk(&rev.reflog_info);
rev.verbo