summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore10
-rw-r--r--.mailmap13
-rw-r--r--Documentation/Makefile22
-rw-r--r--Documentation/RelNotes-1.5.0.4.txt2
-rw-r--r--Documentation/RelNotes-1.5.0.5.txt2
-rw-r--r--Documentation/RelNotes-1.5.0.6.txt1
-rw-r--r--Documentation/RelNotes-1.5.1.3.txt1
-rw-r--r--Documentation/RelNotes-1.5.3.txt279
-rw-r--r--Documentation/SubmittingPatches22
-rw-r--r--Documentation/asciidoc.conf2
-rwxr-xr-xDocumentation/cmd-list.perl7
-rw-r--r--Documentation/config.txt96
-rw-r--r--Documentation/core-intro.txt2
-rw-r--r--Documentation/core-tutorial.txt46
-rw-r--r--Documentation/diff-format.txt28
-rw-r--r--Documentation/diff-options.txt28
-rw-r--r--Documentation/diffcore.txt3
-rw-r--r--Documentation/docbook-xsl.css572
-rw-r--r--Documentation/docbook.xsl5
-rw-r--r--Documentation/fetch-options.txt1
-rw-r--r--Documentation/git-add.txt36
-rw-r--r--Documentation/git-am.txt13
-rw-r--r--Documentation/git-apply.txt1
-rw-r--r--Documentation/git-applymbox.txt98
-rw-r--r--Documentation/git-applypatch.txt53
-rw-r--r--Documentation/git-archimport.txt45
-rw-r--r--Documentation/git-bisect.txt3
-rw-r--r--Documentation/git-blame.txt7
-rw-r--r--Documentation/git-branch.txt17
-rw-r--r--Documentation/git-cat-file.txt1
-rw-r--r--Documentation/git-check-attr.txt1
-rw-r--r--Documentation/git-checkout-index.txt1
-rw-r--r--Documentation/git-checkout.txt7
-rw-r--r--Documentation/git-cherry-pick.txt1
-rw-r--r--Documentation/git-cherry.txt1
-rw-r--r--Documentation/git-citool.txt32
-rw-r--r--Documentation/git-clone.txt9
-rw-r--r--Documentation/git-commit-tree.txt5
-rw-r--r--Documentation/git-commit.txt62
-rw-r--r--Documentation/git-config.txt55
-rw-r--r--Documentation/git-convert-objects.txt1
-rw-r--r--Documentation/git-count-objects.txt1
-rw-r--r--Documentation/git-cvsexportcommit.txt20
-rw-r--r--Documentation/git-cvsimport.txt36
-rw-r--r--Documentation/git-cvsserver.txt43
-rw-r--r--Documentation/git-daemon.txt7
-rw-r--r--Documentation/git-describe.txt8
-rw-r--r--Documentation/git-diff-files.txt3
-rw-r--r--Documentation/git-diff-index.txt3
-rw-r--r--Documentation/git-diff-tree.txt1
-rw-r--r--Documentation/git-diff.txt30
-rw-r--r--Documentation/git-fast-import.txt59
-rw-r--r--Documentation/git-fetch.txt2
-rw-r--r--Documentation/git-filter-branch.txt278
-rw-r--r--Documentation/git-fmt-merge-msg.txt1
-rw-r--r--Documentation/git-format-patch.txt20
-rw-r--r--Documentation/git-fsck.txt12
-rw-r--r--Documentation/git-gc.txt16
-rw-r--r--Documentation/git-get-tar-commit-id.txt1
-rw-r--r--Documentation/git-grep.txt1
-rw-r--r--Documentation/git-gui.txt115
-rw-r--r--Documentation/git-hash-object.txt3
-rw-r--r--Documentation/git-http-fetch.txt1
-rw-r--r--Documentation/git-http-push.txt2
-rw-r--r--Documentation/git-index-pack.txt1
-rw-r--r--Documentation/git-init-db.txt3
-rw-r--r--Documentation/git-init.txt7
-rw-r--r--Documentation/git-instaweb.txt1
-rw-r--r--Documentation/git-local-fetch.txt3
-rw-r--r--Documentation/git-log.txt19
-rw-r--r--Documentation/git-ls-files.txt1
-rw-r--r--Documentation/git-ls-remote.txt1
-rw-r--r--Documentation/git-ls-tree.txt15
-rw-r--r--Documentation/git-mailinfo.txt3
-rw-r--r--Documentation/git-mailsplit.txt14
-rw-r--r--Documentation/git-merge-base.txt1
-rw-r--r--Documentation/git-merge-index.txt3
-rw-r--r--Documentation/git-merge-one-file.txt1
-rw-r--r--Documentation/git-merge-tree.txt1
-rw-r--r--Documentation/git-merge.txt27
-rw-r--r--Documentation/git-mergetool.txt3
-rw-r--r--Documentation/git-mktag.txt15
-rw-r--r--Documentation/git-mktree.txt1
-rw-r--r--Documentation/git-mv.txt1
-rw-r--r--Documentation/git-name-rev.txt8
-rw-r--r--Documentation/git-pack-objects.txt36
-rw-r--r--Documentation/git-pack-redundant.txt3
-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.txt3
-rw-r--r--Documentation/git-push.txt30
-rw-r--r--Documentation/git-quiltimport.txt1
-rw-r--r--Documentation/git-read-tree.txt9
-rw-r--r--Documentation/git-rebase.txt107
-rw-r--r--Documentation/git-receive-pack.txt10
-rw-r--r--Documentation/git-reflog.txt14
-rw-r--r--Documentation/git-relink.txt1
-rw-r--r--Documentation/git-remote.txt1
-rw-r--r--Documentation/git-repack.txt17
-rw-r--r--Documentation/git-request-pull.txt1
-rw-r--r--Documentation/git-rerere.txt4
-rw-r--r--Documentation/git-reset.txt16
-rw-r--r--Documentation/git-rev-list.txt48
-rw-r--r--Documentation/git-rev-parse.txt12
-rw-r--r--Documentation/git-revert.txt1
-rw-r--r--Documentation/git-rm.txt4
-rw-r--r--Documentation/git-runstatus.txt1
-rw-r--r--Documentation/git-send-email.txt30
-rw-r--r--Documentation/git-sh-setup.txt1
-rw-r--r--Documentation/git-shell.txt1
-rw-r--r--Documentation/git-shortlog.txt1
-rw-r--r--Documentation/git-show-index.txt1
-rw-r--r--Documentation/git-show.txt1
-rw-r--r--Documentation/git-ssh-fetch.txt3
-rw-r--r--Documentation/git-ssh-upload.txt3
-rw-r--r--Documentation/git-stash.txt165
-rw-r--r--Documentation/git-status.txt1
-rw-r--r--Documentation/git-stripspace.txt1
-rw-r--r--Documentation/git-submodule.txt77
-rw-r--r--Documentation/git-svn.txt7
-rw-r--r--Documentation/git-svnimport.txt1
-rw-r--r--Documentation/git-tag.txt13
-rw-r--r--Documentation/git-tar-tree.txt1
-rw-r--r--Documentation/git-unpack-file.txt1
-rw-r--r--Documentation/git-unpack-objects.txt1
-rw-r--r--Documentation/git-update-index.txt9
-rw-r--r--Documentation/git-update-ref.txt5
-rw-r--r--Documentation/git-update-server-info.txt1
-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-whatchanged.txt1
-rw-r--r--Documentation/git-write-tree.txt1
-rw-r--r--Documentation/git.txt60
-rw-r--r--Documentation/gitattributes.txt57
-rw-r--r--Documentation/gitignore.txt22
-rw-r--r--Documentation/gitk.txt1
-rw-r--r--Documentation/gitmodules.txt62
-rw-r--r--Documentation/hooks.txt13
-rw-r--r--Documentation/howto/rebase-and-edit.txt20
-rw-r--r--Documentation/howto/rebase-from-internal-branch.txt12
-rw-r--r--Documentation/howto/rebuild-from-update-hook.txt1
-rw-r--r--Documentation/howto/revert-branch-rebase.txt2
-rw-r--r--Documentation/howto/separating-topic-branches.txt13
-rw-r--r--Documentation/howto/use-git-daemon.txt1
-rwxr-xr-xDocumentation/install-doc-quick.sh12
-rw-r--r--Documentation/merge-options.txt5
-rw-r--r--Documentation/pretty-formats.txt3
-rw-r--r--Documentation/pretty-options.txt14
-rw-r--r--Documentation/pull-fetch-param.txt2
-rw-r--r--Documentation/repository-layout.txt1
-rw-r--r--Documentation/technical/pack-format.txt8
-rw-r--r--Documentation/tutorial.txt2
-rw-r--r--Documentation/urls-remotes.txt55
-rw-r--r--Documentation/urls.txt54
-rw-r--r--Documentation/user-manual.txt124
-rwxr-xr-xGIT-VERSION-GEN2
-rw-r--r--INSTALL26
-rw-r--r--Makefile183
l---------RelNotes2
-rw-r--r--archive-tar.c4
-rw-r--r--archive-zip.c2
-rw-r--r--arm/sha1.c4
-rw-r--r--arm/sha1_arm.S1
-rw-r--r--builtin-add.c69
-rw-r--r--builtin-annotate.c1
-rw-r--r--builtin-apply.c48
-rw-r--r--builtin-archive.c2
-rw-r--r--builtin-blame.c19
-rw-r--r--builtin-branch.c198
-rw-r--r--builtin-bundle.c1
-rw-r--r--builtin-checkout-index.c1
-rw-r--r--builtin-config.c84
-rw-r--r--builtin-count-objects.c2
-rw-r--r--builtin-describe.c14
-rw-r--r--builtin-diff-index.c2
-rw-r--r--builtin-diff.c1
-rw-r--r--builtin-fetch--tool.c3
-rw-r--r--builtin-fmt-merge-msg.c1
-rw-r--r--builtin-for-each-ref.c3
-rw-r--r--builtin-fsck.c90
-rw-r--r--builtin-gc.c37
-rw-r--r--builtin-init-db.c31
-rw-r--r--builtin-log.c128
-rw-r--r--builtin-ls-files.c10
-rw-r--r--builtin-ls-tree.c35
-rw-r--r--builtin-mailinfo.c68
-rw-r--r--builtin-mailsplit.c142
-rw-r--r--builtin-merge-base.c1
-rw-r--r--builtin-merge-file.c13
-rw-r--r--builtin-name-rev.c24
-rw-r--r--builtin-pack-objects.c798
-rw-r--r--builtin-pack-refs.c69
-rw-r--r--builtin-push.c324
-rw-r--r--builtin-read-tree.c3
-rw-r--r--builtin-reflog.c2
-rw-r--r--builtin-rerere.c56
-rw-r--r--builtin-rev-list.c24
-rw-r--r--builtin-rev-parse.c17
-rw-r--r--builtin-revert.c13
-rw-r--r--builtin-rm.c32
-rw-r--r--builtin-runstatus.c1
-rw-r--r--builtin-shortlog.c1
-rw-r--r--builtin-show-branch.c23
-rw-r--r--builtin-show-ref.c1
-rw-r--r--builtin-stripspace.c88
-rw-r--r--builtin-symbolic-ref.c2
-rw-r--r--builtin-update-index.c4
-rw-r--r--builtin-update-ref.c13
-rw-r--r--builtin-write-tree.c2
-rw-r--r--builtin.h4
-rw-r--r--cache-tree.c4
-rw-r--r--cache.h73
-rw-r--r--combine-diff.c3
-rw-r--r--commit.c437
-rw-r--r--commit.h6
-rw-r--r--compat/mmap.c1
-rw-r--r--config.c120
-rw-r--r--config.mak.in1
-rw-r--r--configure.ac14
-rw-r--r--connect.c311
-rw-r--r--contrib/README1
-rw-r--r--contrib/blameview/README1
-rwxr-xr-xcontrib/completion/git-completion.bash12
-rw-r--r--contrib/emacs/Makefile5
-rw-r--r--contrib/emacs/git.el239
-rw-r--r--contrib/emacs/vc-git.el65
-rwxr-xr-xcontrib/examples/git-gc.sh8
-rwxr-xr-xcontrib/examples/git-resolve.sh34
-rwxr-xr-xcontrib/fast-import/git-p41593
-rw-r--r--contrib/fast-import/git-p4.bat1
-rw-r--r--contrib/fast-import/git-p4.txt159
-rwxr-xr-xcontrib/gitview/gitview34
-rw-r--r--contrib/hooks/post-receive-email2
-rw-r--r--contrib/p4import/README1
-rw-r--r--contrib/p4import/git-p4import.py (renamed from git-p4import.py)1
-rw-r--r--contrib/p4import/git-p4import.txt (renamed from Documentation/git-p4import.txt)1
-rw-r--r--contrib/patches/docbook-xsl-manpages-charmap.patch21
-rw-r--r--contrib/remotes2config.sh6
-rwxr-xr-xcontrib/stats/git-common-hash26
-rwxr-xr-xcontrib/stats/mailmap.pl38
-rwxr-xr-xcontrib/stats/packinfo.pl212
-rwxr-xr-xcontrib/workdir/git-new-workdir17
-rw-r--r--convert-objects.c2
-rw-r--r--copy.c1
-rw-r--r--csum-file.c63
-rw-r--r--csum-file.h2
-rw-r--r--ctype.c1
-rw-r--r--daemon.c32
-rw-r--r--date.c46
-rw-r--r--delta.h7
-rw-r--r--diff-delta.c139
-rw-r--r--diff-lib.c4
-rw-r--r--diff.c236
-rw-r--r--diff.h3
-rw-r--r--diffcore-break.c3
-rw-r--r--diffcore-delta.c39
-rw-r--r--diffcore-pickaxe.c2
-rw-r--r--diffcore-rename.c37
-rw-r--r--diffcore.h8
-rw-r--r--dir.c96
-rw-r--r--dir.h12
-rw-r--r--entry.c6
-rw-r--r--environment.c50
-rw-r--r--fast-import.c166
-rw-r--r--fetch-pack.c4
-rw-r--r--fetch.c6
-rwxr-xr-xfixup-builtins16
-rwxr-xr-xgenerate-cmdlist.sh2
-rwxr-xr-xgit-add--interactive.perl19
-rwxr-xr-xgit-am.sh59
-rwxr-xr-xgit-applymbox.sh121
-rwxr-xr-xgit-applypatch.sh212
-rwxr-xr-xgit-archimport.perl175
-rwxr-xr-xgit-bisect.sh34
-rwxr-xr-xgit-checkout.sh53
-rwxr-xr-xgit-clean.sh4
-rwxr-xr-xgit-clone.sh94
-rwxr-xr-xgit-commit.sh173
-rw-r--r--git-compat-util.h16
-rwxr-xr-xgit-cvsexportcommit.perl15
-rwxr-xr-xgit-cvsimport.perl77
-rwxr-xr-xgit-cvsserver.perl166
-rwxr-xr-xgit-fetch.sh46
-rwxr-xr-xgit-filter-branch.sh397
-rwxr-xr-xgit-gui/GIT-VERSION-GEN2
-rw-r--r--git-gui/Makefile42
-rwxr-xr-xgit-gui/git-gui.sh935
-rw-r--r--git-gui/lib/blame.tcl111
-rw-r--r--git-gui/lib/branch.tcl562
-rw-r--r--git-gui/lib/branch_checkout.tcl89
-rw-r--r--git-gui/lib/branch_create.tcl220
-rw-r--r--git-gui/lib/branch_delete.tcl149
-rw-r--r--git-gui/lib/branch_rename.tcl128
-rw-r--r--git-gui/lib/browser.tcl88
-rw-r--r--git-gui/lib/checkout_op.tcl588
-rw-r--r--git-gui/lib/choose_rev.tcl627
-rw-r--r--git-gui/lib/class.tcl38
-rw-r--r--git-gui/lib/commit.tcl84
-rw-r--r--git-gui/lib/console.tcl69
-rw-r--r--git-gui/lib/database.tcl29
-rw-r--r--git-gui/lib/diff.tcl27
-rw-r--r--git-gui/lib/encoding.tcl276
-rw-r--r--git-gui/lib/error.tcl7
-rw-r--r--git-gui/lib/index.tcl50
-rw-r--r--git-gui/lib/merge.tcl285
-rw-r--r--git-gui/lib/option.tcl19
-rw-r--r--git-gui/lib/remote.tcl106
-rw-r--r--git-gui/lib/remote_branch_delete.tcl347
-rw-r--r--git-gui/lib/shortcut.tcl51
-rw-r--r--git-gui/lib/status_bar.tcl96
-rw-r--r--git-gui/lib/transport.tcl20
-rwxr-xr-xgit-lost-found.sh4
-rwxr-xr-xgit-ls-remote.sh4
-rwxr-xr-xgit-merge-octopus.sh14
-rwxr-xr-xgit-merge-one-file.sh30
-rwxr-xr-xgit-merge-ours.sh2
-rwxr-xr-xgit-merge-resolve.sh6
-rwxr-xr-xgit-merge-stupid.sh10
-rwxr-xr-xgit-merge.sh92
-rwxr-xr-xgit-mergetool.sh72
-rwxr-xr-xgit-parse-remote.sh24
-rwxr-xr-xgit-pull.sh19
-rwxr-xr-xgit-quiltimport.sh17
-rwxr-xr-xgit-rebase--interactive.sh483
-rwxr-xr-xgit-rebase.sh69
-rwxr-xr-xgit-remote.perl15
-rwxr-xr-xgit-repack.sh32
-rwxr-xr-xgit-request-pull.sh4
-rwxr-xr-xgit-reset.sh16
-rwxr-xr-xgit-send-email.perl71
-rwxr-xr-xgit-sh-setup.sh58
-rwxr-xr-xgit-stash.sh215
-rwxr-xr-xgit-submodule.sh322
-rwxr-xr-xgit-svn.perl248
-rwxr-xr-xgit-svnimport.perl30
-rwxr-xr-xgit-tag.sh96
-rwxr-xr-xgit-verify-tag.sh14
-rw-r--r--git.c158
-rw-r--r--git.spec.in46
-rwxr-xr-xgitk3660
-rw-r--r--gitweb/README1
-rw-r--r--gitweb/gitweb.css11
-rwxr-xr-xgitweb/gitweb.perl852
-rw-r--r--help.c2
-rw-r--r--http-fetch.c2
-rw-r--r--http-push.c3
-rw-r--r--http.c2
-rw-r--r--ident.c19
-rw-r--r--imap-send.c2
-rw-r--r--index-pack.c211
-rw-r--r--interpolate.c46
-rw-r--r--interpolate.h6
-rw-r--r--list-objects.c2
-rw-r--r--local-fetch.c8
-rw-r--r--lockfile.c112
-rw-r--r--log-tree.c38
-rw-r--r--mailmap.c1
-rw-r--r--match-trees.c1
-rw-r--r--merge-file.c1
-rw-r--r--merge-index.c2
-rw-r--r--merge-recursive.c2
-rw-r--r--merge-tree.c2
-rw-r--r--mktag.c11
-rw-r--r--mozilla-sha1/sha1.c19
-rw-r--r--mozilla-sha1/sha1.h18
-rw-r--r--object-refs.c2
-rw-r--r--object.h2
-rw-r--r--pack-check.c75
-rw-r--r--pack-redundant.c7
-rw-r--r--pack-write.c142
-rw-r--r--pack.h14
-rw-r--r--pager.c2
-rw-r--r--patch-id.c2
-rw-r--r--path-list.c1
-rw-r--r--path.c91
-rw-r--r--peek-remote.c2
-rw-r--r--perl/Makefile1
-rw-r--r--pkt-line.c2
-rw-r--r--ppc/sha1.c2
-rw-r--r--progress.c6
-rw-r--r--progress.h1
-rw-r--r--quote.c19
-rw-r--r--quote.h2
-rw-r--r--reachable.c4
-rw-r--r--read-cache.c57
-rw-r--r--receive-pack.c2
-rw-r--r--reflog-walk.c7
-rw-r--r--reflog-walk.h2
-rw-r--r--refs.c113
-rw-r--r--refs.h3
-rw-r--r--remote.c633
-rw-r--r--remote.h51
-rw-r--r--revision.c88
-rw-r--r--revision.h3
-rw-r--r--rsh.h2
-rw-r--r--run-command.c45
-rw-r--r--run-command.h9
-rw-r--r--send-pack.c59
-rw-r--r--server-info.c2
-rw-r--r--setup.c159
-rw-r--r--sha1_file.c145
-rw-r--r--sha1_name.c13
-rw-r--r--shallow.c1
-rw-r--r--ssh-upload.c10
-rw-r--r--strbuf.c1
-rw-r--r--t/Makefile4
-rw-r--r--t/lib-git-svn.sh34
-rw-r--r--t/lib-read-tree-m-3way.sh60
-rwxr-xr-xt/t0000-basic.sh122
-rwxr-xr-xt/t0022-crlf-rename.sh33
-rwxr-xr-xt/t0030-stripspace.sh395
-rwxr-xr-xt/t1000-read-tree-m-3way.sh172
-rwxr-xr-xt/t1001-read-tree-m-2way.sh176
-rwxr-xr-xt/t1002-read-tree-m-u-2way.sh174
-rwxr-xr-xt/t1003-read-tree-prefix.sh10
-rwxr-xr-xt/t1004-read-tree-m-u-wf.sh2
-rwxr-xr-xt/t1020-subdirectory.sh36
-rwxr-xr-xt/t1100-commit-tree-options.sh10
-rwxr-xr-xt/t1200-tutorial.sh25
-rwxr-xr-xt/t1300-repo-config.sh228
-rwxr-xr-xt/t1301-shared-repo.sh27
-rwxr-xr-xt/t1400-update-ref.sh74
-rwxr-xr-xt/t1420-lost-found.sh35
-rwxr-xr-xt/t1500-rev-parse.sh77
-rwxr-xr-xt/t1501-worktree.sh106
-rwxr-xr-xt/t2000-checkout-cache-clash.sh20
-rwxr-xr-xt/t2001-checkout-cache-clash.sh35
-rwxr-xr-xt/t2002-checkout-cache-u.sh26
-rwxr-xr-xt/t2003-checkout-cache-mkdir.sh18
-rwxr-xr-xt/t2004-checkout-cache-temp.sh48
-rwxr-xr-xt/t2005-checkout-index-symlinks.sh10
-rwxr-xr-xt/t2100-update-cache-badpath.sh12
-rwxr-xr-xt/t2101-update-index-reupdate.sh28
-rwxr-xr-xt/t2102-update-index-symlinks.sh14
-rwxr-xr-xt/t2200-add-update.sh14
-rwxr-xr-xt/t3000-ls-files-others.sh18
-rwxr-xr-xt/t3001-ls-files-others-exclude.sh16
-rwxr-xr-xt/t3002-ls-files-dashpath.sh24
-rwxr-xr-xt/t3010-ls-files-killed-modified.sh20
-rwxr-xr-xt/t3020-ls-files-error-unmatch.sh14
-rwxr-xr-xt/t3030-merge-recursive.sh1
-rwxr-xr-xt/t3100-ls-tree-restrict.sh32
-rwxr-xr-xt/t3101-ls-tree-dirname.sh24
-rwxr-xr-xt/t3200-branch.sh175
-rwxr-xr-xt/t3210-pack-refs.sh86
-rwxr-xr-xt/t3300-funny-names.sh76
-rwxr-xr-xt/t3400-rebase.sh45
-rwxr-xr-xt/t3401-rebase-partial.sh18
-rwxr-xr-xt/t3403-rebase-skip.sh3
-rwxr-xr-xt/t3404-rebase-interactive.sh277
-rwxr-xr-xt/t3405-rebase-malformed.sh48
-rwxr-xr-xt/t3500-cherry.sh22
-rwxr-xr-xt/t3600-rm.sh82
-rwxr-xr-xt/t3700-add.sh103
-rwxr-xr-xt/t3800-mktag.sh4
-rwxr-xr-xt/t3900-i18n-commit.sh32
-rwxr-xr-xt/t3901-i18n-patch.sh34
-rwxr-xr-xt/t3902-quoted.sh126
-rwxr-xr-xt/t3903-stash.sh76
-rwxr-xr-xt/t4000-diff-format.sh8
-rwxr-xr-xt/t4001-diff-rename.sh23
-rwxr-xr-xt/t4002-diff-basic.sh70
-rwxr-xr-xt/t4003-diff-rename-1.sh18
-rwxr-xr-xt/t4004-diff-rename-symlink.sh8
-rwxr-xr-xt/t4005-diff-rename-2.sh16
-rwxr-xr-xt/t4006-diff-mode.sh17
-rwxr-xr-xt/t4007-rename-3.sh16
-rwxr-xr-xt/t4008-diff-break-rewrite.sh38
-rwxr-xr-xt/t4009-diff-rename-4.sh16
-rwxr-xr-xt/t4010-diff-pathspec.sh16
-rwxr-xr-xt/t4011-diff-symlink.sh20
-rwxr-xr-xt/t4012-diff-binary.sh26
-rwxr-xr-xt/t4013-diff-various.sh2
-rw-r--r--t/t4013/diff.config_format.subjectprefix_DIFFERENT_PREFIX2
-rw-r--r--t/t4013/diff.format-patch_--inline_--stdout_initial..master^^60
-rwxr-xr-xt/t4015-diff-whitespace.sh16
-rw-r--r--t/t4018-diff-funcname.sh60
-rwxr-xr-xt/t4020-diff-external.sh12
-rwxr-xr-xt/t4100-apply-stat.sh17
-rwxr-xr-xt/t4101-apply-nonl.sh4
-rwxr-xr-xt/t4102-apply-rename.sh10
-rwxr-xr-xt/t4103-apply-binary.sh52
-rwxr-xr-xt/t4104-apply-boundary.sh2
-rwxr-xr-xt/t4109-apply-multifrag.sh14
-rwxr-xr-xt/t4110-apply-scan.sh7
-rwxr-xr-xt/t4112-apply-renames.sh24
-rwxr-xr-xt/t4113-apply-ending.sh10
-rwxr-xr-xt/t4114-apply-typechange.sh2
-rwxr-xr-xt/t4115-apply-symlink.sh2
-rwxr-xr-xt/t4116-apply-reverse.sh2
-rwxr-xr-xt/t4117-apply-reject.sh2
-rwxr-xr-xt/t4118-apply-empty-context.sh3
-rwxr-xr-xt/t4119-apply-config.sh4
-rwxr-xr-xt/t4120-apply-popt.sh2
-rwxr-xr-xt/t4121-apply-diffs.sh3
-rwxr-xr-xt/t4122-apply-symlink-inside.sh1
-rwxr-xr-xt/t4200-rerere.sh69
-rwxr-xr-xt/t4201-shortlog.sh2
-rwxr-xr-xt/t5000-tar-tree.sh57
-rwxr-xr-xt/t5100-mailinfo.sh6
-rwxr-xr-xt/t5300-pack-object.sh72
-rwxr-xr-xt/t5301-sliding-window.sh40
-rwxr-xr-xt/t5302-pack-index.sh56
-rwxr-xr-xt/t5400-send-pack.sh38
-rwxr-xr-xt/t5401-update-hooks.sh26
-rwxr-xr-xt/t5500-fetch-pack.sh30
-rwxr-xr-xt/t5516-fetch-push.sh247
-rwxr-xr-xt/t5520-pull.sh1
-rwxr-xr-xt/t5710-info-alternate.sh1
-rwxr-xr-xt/t6000lib.sh16
-rwxr-xr-xt/t6002-rev-list-bisect.sh46
-rwxr-xr-xt/t6003-rev-list-topo-order.sh76
-rwxr-xr-xt/t6004-rev-list-path-optim.sh8
-rwxr-xr-xt/t6005-rev-list-count.sh44
-rwxr-xr-xt/t6006-rev-list-format.sh10
-rwxr-xr-xt/t6007-rev-list-cherry-pick-file.sh43
-rwxr-xr-xt/t6010-merge-base.sh24
-rwxr-xr-xt/t6021-merge-criss-cross.sh2
-rwxr-xr-xt/t6023-merge-file.sh16
-rwxr-xr-xt/t6024-recursive-merge.sh8
-rwxr-xr-xt/t6025-merge-symlinks.sh14
-rwxr-xr-xt/t6030-bisect-porcelain.sh1
-rwxr-xr-xt/t6101-rev-parse-parents.sh39
-rwxr-xr-xt/t6120-describe.sh22
-rwxr-xr-xt/t7001-mv.sh32
-rwxr-xr-xt/t7003-filter-branch.sh162
-rwxr-xr-xt/t7004-tag.sh897
-rw-r--r--t/t7004/pubring.gpgbin0 -> 1164 bytes
-rw-r--r--t/t7004/random_seedbin0 -> 600 bytes
-rw-r--r--t/t7004/secring.gpgbin0 -> 1237 bytes
-rw-r--r--t/t7004/trustdb.gpgbin0 -> 1280 bytes
-rwxr-xr-xt/t7005-editor.sh91
-rwxr-xr-xt/t7101-reset.sh10
-rwxr-xr-xt/t7300-clean.sh6
-rwxr-xr-xt/t7400-submodule-basic.sh178
-rwxr-xr-xt/t7500-commit.sh96
-rwxr-xr-xt/t7500/add-comments4
-rwxr-xr-xt/t7500/add-content3
-rwxr-xr-xt/t7500/add-signed-off3
-rw-r--r--t/t7501-commit.sh134
-rwxr-xr-xt/t8001-annotate.sh2
-rwxr-xr-xt/t8002-blame.sh2
-rwxr-xr-xt/t9100-git-svn-basic.sh12
-rwxr-xr-xt/t9104-git-svn-follow-parent.sh30
-rwxr-xr-xt/t9107-git-svn-migrate.sh27
-rwxr-xr-xt/t9110-git-svn-use-svm-props.sh20
-rwxr-xr-xt/t9111-git-svn-use-svnsync-props.sh20
-rw-r--r--t/t9111/svnsync.dump2
-rwxr-xr-xt/t9113-git-svn-dcommit-new-file.sh40
-rwxr-xr-xt/t9114-git-svn-dcommit-merge.sh89
-rwxr-xr-xt/t9115-git-svn-dcommit-funky-renames.sh54
-rw-r--r--t/t9115/funky-names.dump103
-rwxr-xr-xt/t9200-git-cvsexportcommit.sh64
-rwxr-xr-xt/t9300-fast-import.sh251
-rwxr-xr-xt/t9400-git-cvsserver-server.sh284
-rwxr-xr-xt/t9500-gitweb-standalone-no-errors.sh552
-rw-r--r--t/test-lib.sh4
-rw-r--r--templates/Makefile5
-rw-r--r--templates/hooks--commit-msg1
-rw-r--r--templates/hooks--post-receive1
-rw-r--r--templates/hooks--pre-applypatch1
-rw-r--r--templates/hooks--pre-commit1
-rw-r--r--test-absolute-path.c11
-rw-r--r--tree-diff.c78
-rw-r--r--tree-walk.c1
-rw-r--r--tree-walk.h2
-rw-r--r--tree.c4
-rw-r--r--unpack-trees.c96
-rw-r--r--upload-pack.c4
-rw-r--r--var.c4
-rw-r--r--write_or_die.c40
-rw-r--r--wt-status.c2
-rw-r--r--xdiff-interface.c69
-rw-r--r--xdiff-interface.h2
-rw-r--r--xdiff/xdiff.h5
-rw-r--r--xdiff/xdiffi.c1
-rw-r--r--xdiff/xdiffi.h1
-rw-r--r--xdiff/xemit.c42
-rw-r--r--xdiff/xemit.h1
-rw-r--r--xdiff/xinclude.h1
-rw-r--r--xdiff/xmacros.h1
-rw-r--r--xdiff/xprepare.c1
-rw-r--r--xdiff/xprepare.h1
-rw-r--r--xdiff/xtypes.h1
-rw-r--r--xdiff/xutils.c1
-rw-r--r--xdiff/xutils.h1
589 files changed, 25795 insertions, 9187 deletions
diff --git a/.gitignore b/.gitignore
index b7546a5..63c918c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,8 +7,6 @@ git-add--interactive
git-am
git-annotate
git-apply
-git-applymbox
-git-applypatch
git-archimport
git-archive
git-bisect
@@ -42,6 +40,7 @@ git-fast-import
git-fetch
git-fetch--tool
git-fetch-pack
+git-filter-branch
git-findtags
git-fmt-merge-msg
git-for-each-ref
@@ -97,6 +96,7 @@ git-push
git-quiltimport
git-read-tree
git-rebase
+git-rebase--interactive
git-receive-pack
git-reflog
git-relink
@@ -124,8 +124,10 @@ git-ssh-fetch
git-ssh-pull
git-ssh-push
git-ssh-upload
+git-stash
git-status
git-stripspace
+git-submodule
git-svn
git-svnimport
git-symbolic-ref
@@ -146,19 +148,21 @@ git-write-tree
git-core-*/?*
gitk-wish
gitweb/gitweb.cgi
+test-absolute-path
test-chmtime
test-date
test-delta
test-dump-cache-tree
test-genrandom
test-match-trees
+test-sha1
common-cmds.h
*.tar.gz
*.dsc
*.deb
git.spec
*.exe
-*.[ao]
+*.[aos]
*.py[co]
config.mak
autom4te.cache
diff --git a/.mailmap b/.mailmap
index 4e0615e..5529b19 100644
--- a/.mailmap
+++ b/.mailmap
@@ -7,6 +7,8 @@
Aneesh Kumar K.V <aneesh.kumar@gmail.com>
Chris Shoemaker <c.shoemaker@cox.net>
+Dana L. How <danahow@gmail.com>
+Dana L. How <how@deathvalley.cswitch.com>
Daniel Barkalow <barkalow@iabervon.org>
David Kågedal <davidk@lysator.liu.se>
Fredrik Kuivinen <freku045@student.liu.se>
@@ -17,13 +19,16 @@ Horst H. von Brand <vonbrand@inf.utfsm.cl>
Joachim Berdal Haga <cjhaga@fys.uio.no>
Jon Loeliger <jdl@freescale.com>
Jon Seymour <jon@blackcubes.dyndns.org>
+Junio C Hamano <junio@twinsun.com>
Karl Hasselström <kha@treskal.com>
Kent Engstrom <kent@lysator.liu.se>
-Lars Doelle <lars.doelle@on-line.de>
Lars Doelle <lars.doelle@on-line ! de>
+Lars Doelle <lars.doelle@on-line.de>
Lukas Sandström <lukass@etek.chalmers.se>
Martin Langhoff <martin@catalyst.net.nz>
+Michael Coleman <tutufan@gmail.com>
Michele Ballabio <barra_cuda@katamail.com>
+Nanako Shiraishi <nanako3@bluebottle.com>
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Ramsay Allan Jones <ramsay@ramsay1.demon.co.uk>
René Scharfe <rene.scharfe@lsrfire.ath.cx>
@@ -34,12 +39,12 @@ Sean Estabrooks <seanlkml@sympatico.ca>
Shawn O. Pearce <spearce@spearce.org>
Theodore Ts'o <tytso@mit.edu>
Tony Luck <tony.luck@intel.com>
-Uwe Kleine-König <zeisberg@informatik.uni-freiburg.de>
Uwe Kleine-König <Uwe_Zeisberger@digi.com>
-Uwe Kleine-König <uzeisberger@io.fsforth.de>
Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de>
+Uwe Kleine-König <uzeisberger@io.fsforth.de>
+Uwe Kleine-König <zeisberg@informatik.uni-freiburg.de>
Ville Skyttä <scop@xemacs.org>
+William Pursell <bill.pursell@gmail.com>
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
anonymous <linux@horizon.com>
anonymous <linux@horizon.net>
-Dana L. How <how@deathvalley.cswitch.com>
diff --git a/Documentation/Makefile b/Documentation/Makefile
index 4edf788..443114b 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -2,7 +2,7 @@ MAN1_TXT= \
$(filter-out $(addsuffix .txt, $(ARTICLES) $(SP_ARTICLES)), \
$(wildcard git-*.txt)) \
gitk.txt
-MAN5_TXT=gitattributes.txt gitignore.txt
+MAN5_TXT=gitattributes.txt gitignore.txt gitmodules.txt
MAN7_TXT=git.txt
DOC_HTML=$(patsubst %.txt,%.html,$(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT))
@@ -29,7 +29,7 @@ DOC_MAN7=$(patsubst %.txt,%.7,$(MAN7_TXT))
prefix?=$(HOME)
bindir?=$(prefix)/bin
-mandir?=$(prefix)/man
+mandir?=$(prefix)/share/man
man1dir=$(mandir)/man1
man5dir=$(mandir)/man5
man7dir=$(mandir)/man7
@@ -41,6 +41,7 @@ ifdef ASCIIDOC8
ASCIIDOC_EXTRA += -a asciidoc7compatible
endif
INSTALL?=install
+RM ?= rm -f
DOC_REF = origin/man
-include ../config.mak.autogen
@@ -84,7 +85,7 @@ install: man
# Determine "include::" file references in asciidoc files.
#
doc.dep : $(wildcard *.txt) build-docdep.perl
- rm -f $@+ $@
+ $(RM) $@+ $@
perl ./build-docdep.perl >$@+
mv $@+ $@
@@ -109,20 +110,21 @@ cmd-list.made: cmd-list.perl $(MAN1_TXT)
git.7 git.html: git.txt core-intro.txt
clean:
- rm -f *.xml *.xml+ *.html *.html+ *.1 *.5 *.7 howto-index.txt howto/*.html doc.dep
- rm -f $(cmds_txt) *.made
+ $(RM) *.xml *.xml+ *.html *.html+ *.1 *.5 *.7 howto-index.txt howto/*.html doc.dep
+ $(RM) $(cmds_txt) *.made
%.html : %.txt
- rm -f $@+ $@
+ $(RM) $@+ $@
$(ASCIIDOC) -b xhtml11 -d manpage -f asciidoc.conf \
$(ASCIIDOC_EXTRA) -agit_version=$(GIT_VERSION) -o $@+ $<
mv $@+ $@
%.1 %.5 %.7 : %.xml
+ $(RM) $@
xmlto -m callouts.xsl man $<
%.xml : %.txt
- rm -f $@+ $@
+ $(RM) $@+ $@
$(ASCIIDOC) -b docbook -d manpage -f asciidoc.conf \
$(ASCIIDOC_EXTRA) -agit_version=$(GIT_VERSION) -o $@+ $<
mv $@+ $@
@@ -130,14 +132,14 @@ clean:
user-manual.xml: user-manual.txt user-manual.conf
$(ASCIIDOC) -b docbook -d book $<
-XSLT = http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl
+XSLT = docbook.xsl
XSLTOPTS = --xinclude --stringparam html.stylesheet docbook-xsl.css
user-manual.html: user-manual.xml
xsltproc $(XSLTOPTS) -o $@ $(XSLT) $<
howto-index.txt: howto-index.sh $(wildcard howto/*.txt)
- rm -f $@+ $@
+ $(RM) $@+ $@
sh ./howto-index.sh $(wildcard howto/*.txt) >$@+
mv $@+ $@
@@ -147,7 +149,7 @@ $(patsubst %,%.html,$(ARTICLES)) : %.html : %.txt
WEBDOC_DEST = /pub/software/scm/git/docs
$(patsubst %.txt,%.html,$(wildcard howto/*.txt)): %.html : %.txt
- rm -f $@+ $@
+ $(RM) $@+ $@
sed -e '1,/^$$/d' $< | $(ASCIIDOC) -b xhtml11 - >$@+
mv $@+ $@
diff --git a/Documentation/RelNotes-1.5.0.4.txt b/Documentation/RelNotes-1.5.0.4.txt
index b727a8d..feefa5d 100644
--- a/Documentation/RelNotes-1.5.0.4.txt
+++ b/Documentation/RelNotes-1.5.0.4.txt
@@ -20,5 +20,3 @@ Fixes since v1.5.0.3
* Documentation updates
* User manual updates
-
-
diff --git a/Documentation/RelNotes-1.5.0.5.txt b/Documentation/RelNotes-1.5.0.5.txt
index aa86149..eeec3d7 100644
--- a/Documentation/RelNotes-1.5.0.5.txt
+++ b/Documentation/RelNotes-1.5.0.5.txt
@@ -24,5 +24,3 @@ Fixes since v1.5.0.3
* Documentation updates
* User manual updates
-
-
diff --git a/Documentation/RelNotes-1.5.0.6.txt b/Documentation/RelNotes-1.5.0.6.txt
index e15447f..c02015a 100644
--- a/Documentation/RelNotes-1.5.0.6.txt
+++ b/Documentation/RelNotes-1.5.0.6.txt
@@ -19,4 +19,3 @@ Fixes since v1.5.0.5
- user-manual has better cross references.
- gitweb installation/deployment procedure is now documented.
-
diff --git a/Documentation/RelNotes-1.5.1.3.txt b/Documentation/RelNotes-1.5.1.3.txt
index 2ddeabd..876408b 100644
--- a/Documentation/RelNotes-1.5.1.3.txt
+++ b/Documentation/RelNotes-1.5.1.3.txt
@@ -43,4 +43,3 @@ Fixes since v1.5.1.2
description was given by the caller.
Also contains various documentation updates.
-
diff --git a/Documentation/RelNotes-1.5.3.txt b/Documentation/RelNotes-1.5.3.txt
new file mode 100644
index 0000000..21bb1fc
--- /dev/null
+++ b/Documentation/RelNotes-1.5.3.txt
@@ -0,0 +1,279 @@
+GIT v1.5.3 Release Notes
+========================
+
+Updates since v1.5.2
+--------------------
+
+* The commit walkers other than http are officially deprecated,
+ but still supported for now.
+
+* The submodule support has Porcelain layer.
+
+* There are a handful pack-objects changes to help you cope better
+ with repositories with pathologically large blobs in them.
+
+* For people who need to import from Perforce, a front-end for
+ fast-import is in contrib/fast-import/.
+
+* Comes with git-gui 0.8.0.
+
+* Comes with updated gitk.
+
+* New commands and options.
+
+ - "git log --date=<format>" can use more formats: iso8601, rfc2822.
+
+ - The hunk header output from "git diff" family can be customized
+ with the attributes mechanism. See gitattributes(5) for details.
+
+ - "git stash" allows you to quickly save away your work in
+ progress and replay it later on an updated state.
+
+ - "git rebase" learned an "interactive" mode that let you
+ pick and reorder which commits to rebuild.
+
+ - "git fsck" can save its findings in $GIT_DIR/lost-found, without a
+ separate invocation of "git lost-found" command. The blobs stored by
+ lost-found are stored in plain format to allow you to grep in them.
+
+ - $GIT_WORK_TREE environment variable can be used together with
+ $GIT_DIR to work in a subdirectory of a working tree that is
+ not located at "$GIT_DIR/..".
+
+ - Giving "--file=<file>" option to "git config" is the same as
+ running the command with GIT_CONFIG=<file> environment.
+
+ - "git log" learned a new option "--follow", to follow
+ renaming history of a single file.
+
+ - "git-filter-branch" lets you rewrite the revision history of
+ specified branches. You can specify a number of filters to
+ modify the commits, files and trees.
+
+ - "git-cvsserver" learned new options (--base-path, --export-all,
+ --strict-paths) inspired by git-daemon.
+
+ - "git daemon --base-path-relaxed" can help migrating a repository URL
+ that did not use to use --base-path to use --base-path.
+
+ - "git-commit" can use "-t templatefile" option and commit.template
+ configuration variable to prime the commit message given to you in the
+ editor.
+
+ - "git-submodule" command helps you manage the projects from
+ the superproject that contain them.
+
+ - In addition to core.compression configuration option,
+ core.loosecompression and pack.compression options can
+ independently tweak zlib compression levels used for loose
+ and packed objects.
+
+ - "git-ls-tree -l" shows size of blobs pointed at by the
+ tree entries, similar to "/bin/ls -l".
+
+ - "git-rev-list" learned --regexp-ignore-case and
+ --extended-regexp options to tweak its matching logic used
+ for --grep fitering.
+
+ - "git-describe --contains" is a handier way to call more
+ obscure command "git-name-rev --tags".
+
+ - "git gc --aggressive" tells the command to spend more cycles
+ to optimize the repository harder.
+
+ - "git repack" learned a "window-memory" limit which
+ dynamically reduces the window size to stay within the
+ specified memory usage.
+
+ - "git repack" can be told to split resulting packs to avoid
+ exceeding limit specified with "--max-pack-size".
+
+ - "git fsck" gained --verbose option. This is really really
+ verbose but it might help you identify exact commit that is
+ corrupt in your repository.
+
+ - "git format-patch" learned --numbered-files option. This
+ may be useful for MH users.
+
+ - "git format-patch" learned format.subjectprefix configuration
+ variable, which serves the same purpose as "--subject-prefix"
+ option.
+
+ - "git tag -n -l" shows tag annotations while listing tags.
+
+ - "git cvsimport" can optionally use the separate-remote layout.
+
+ - "git blame" can be told to see through commits that change
+ whitespaces and indentation levels with "-w" option.
+
+ - "git send-email" can be told not to thread the messages when
+ sending out more than one patches.
+
+ - "git config" learned NUL terminated output format via -z to
+ help scripts.
+
+ - "git init -q" makes the command quieter.
+
+* Updated behavior of existing commands.
+
+ - "gitweb" can offer multiple snapshot formats.
+
+ ***NOTE*** Unfortunately, this changes the format of the
+ $feature{snapshot}{default} entry in the per-site
+ configuration file 'gitweb_config.perl'. It used to be a
+ three-element tuple that describe a single format; with the
+ new configuration item format, you only have to say the name
+ of the format ('tgz', 'tbz2' or 'zip'). Please update the
+ your configuration file accordingly.
+
+ - "git diff" (but not the plumbing level "git diff-tree") now
+ recursively descends into trees by default.
+
+ - The editor to use with many interactive commands can be
+ overridden with GIT_EDITOR environment variable, or if it
+ does not exist, with core.editor configuration variable. As
+ before, if you have neither, environment variables VISUAL
+ and EDITOR are consulted in this order, and then finally we
+ fall back on "vi".
+
+ - "git rm --cached" does not complain when removing a newly
+ added file from the index anymore.
+
+ - Options to "git log" to affect how --grep/--author options look for
+ given strings now have shorter abbreviations. -i is for ignore case,
+ and -E is for extended regexp.
+
+ - "git svn dcommit" retains local merge information.
+
+ - "git config" to set values also honors type flags like --bool
+ and --int.
+
+ - core.quotepath configuration can be used to make textual git
+ output to emit most of the characters in the path literally.
+
+ - "git mergetool" chooses its backend more wisely, taking
+ notice of its environment such as use of X, Gnome/KDE, etc.
+
+ - "gitweb" shows merge commits a lot nicer than before. The
+ default view uses more compact --cc format, while the UI
+ allows to choose normal diff with any parent.
+
+ - snapshot files "gitweb" creates from a repository at
+ $path/$project/.git are more useful. We use $project part
+ in the filename, which we used to discard.
+
+ - "git cvsimport" creates lightweight tags; there is no
+ interesting information we can record in an annotated tag,
+ and the handcrafted ones the old code created was not
+ properly formed anyway.
+
+ - "git-push" pretends that you immediately fetched back from
+ the remote by updating corresponding remote tracking
+ branches if you have any.
+
+ - The diffstat given after a merge (or a pull) honors the
+ color.diff configuration.
+
+ - "git commit --amend" is now compatible with various message source
+ options such as -m/-C/-c/-F.
+
+ - "git-apply --whitespace=strip" removes blank lines added at
+ the end of the file.
+
+ - "git-fetch" over git native protocols with "-v" option shows
+ connection status, and the IP address of the other end, to
+ help diagnosing problems.
+
+ - We used to have core.legacyheaders configuration, when
+ set to false, allowed git to write loose objects in a format
+ that mimicks the format used by objects stored in packs. It
+ turns out that this was not so useful. Although we will
+ continue to read objects written in that format, we do not
+ honor that configuration anymore and create loose objects in
+ the legacy/traditional format.
+
+ - "--find-copies-harder" option to diff family can now be
+ spelled as "-C -C" for brevity.
+
+ - "git-mailsplit" (hence "git-am") can read from Maildir
+ formatted mailboxes.
+
+ - "git-cvsserver" does not barf upon seeing "cvs login"
+ request.
+
+ - "pack-objects" honors "delta" attribute set in
+ .gitattributes. It does not attempt to deltify blobs that
+ come from paths with delta attribute set to false.
+
+ - "new-workdir" script (in contrib) can now be used with a
+ bare repository.
+
+ - "git-mergetool" learned to use gvimdiff.
+
+ - "gitview" (in contrib) has a better blame interface.
+
+ - "git log" and friends did not handle a commit log message
+ that is larger than 16kB; they do now.
+
+ - "--pretty=oneline" output format for "git log" and friends
+ deals with "malformed" commit log messages that have more
+ than one lines in the first paragraph better. We used to
+ show the first line, cutting the title at mid-sentence; we
+ concatenate them into a single line and treat the result as
+ "oneline".
+
+ - "git p4import" has been demoted to contrib status. For
+ a superior option, checkout the git-p4 front end to
+ git-fast-import (also in contrib). The man page and p4
+ rpm have been removed as well.
+
+ - "git mailinfo" (hence "am") now tries to see if the message
+ is in utf-8 first, instead of assuming iso-8859-1, if
+ incoming e-mail does not say what encoding it is in.
+
+* Builds
+
+ - old-style function definitions (most notably, a function
+ without parameter defined with "func()", not "func(void)")
+ have been eradicated.
+
+* Performance Tweaks
+
+ - git-pack-objects avoids re-deltification cost by caching
+ small enough delta results it creates while looking for the
+ best delta candidates.
+
+ - git-pack-objects learned a new heuristcs to prefer delta
+ that is shallower in depth over the smallest delta
+ possible. This improves both overall packfile access
+ performance and packfile density.
+
+ - diff-delta code that is used for packing has been improved
+ to work better on big files.
+
+ - when there are more than one pack files in the repository,
+ the runtime used to try finding an object always from the
+ newest packfile; it now tries the same packfile as we found
+ the object requested the last time, which exploits the
+ locality of references.
+
+ - verifying pack contents done by "git fsck --full" got boost
+ by carefully choosing the order to verify objects in them.
+
+
+Fixes since v1.5.2
+------------------
+
+All of the fixes in v1.5.2 maintenance series are included in
+this release, unless otherwise noted.
+
+* Bugfixes
+
+ - "gitweb" had trouble handling non UTF-8 text with older
+ Encode.pm Perl module.
+
+--
+exec >/var/tmp/1
+O=v1.5.3-rc4
+echo O=`git describe refs/heads/master`
+git shortlog --no-merges $O..refs/heads/master ^refs/heads/maint
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
index b94d9a8..01354c2 100644
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -14,6 +14,8 @@ Checklist (and a short version for the impatient):
commit message (or just use the option "-s" when
committing) to confirm that you agree to the Developer's
Certificate of Origin
+ - make sure that you have tests for the bug you are fixing
+ - make sure that the test suite passes after your commit
Patch:
@@ -33,6 +35,8 @@ Checklist (and a short version for the impatient):
- if you change, add, or remove a command line option or
make some other user interface change, the associated
documentation should be updated as well.
+ - if your name is not writable in ASCII, make sure that
+ you send off a message in the correct encoding.
Long version:
@@ -239,7 +243,7 @@ One test you could do yourself if your MUA is set up correctly is:
$ git fetch http://kernel.org/pub/scm/git/git.git master:test-apply
$ git checkout test-apply
$ git reset --hard
- $ git applymbox a.patch
+ $ git am a.patch
If it does not apply correctly, there can be various reasons.
@@ -247,7 +251,7 @@ If it does not apply correctly, there can be various reasons.
does not have much to do with your MUA. Please rebase the
patch appropriately.
-* Your MUA corrupted your patch; applymbox would complain that
+* Your MUA corrupted your patch; "am" would complain that
the patch does not apply. Look at .dotest/ subdirectory and
see what 'patch' file contains and check for the common
corruption patterns mentioned above.
@@ -292,15 +296,15 @@ diff --git a/pico/pico.c b/pico/pico.c
--- a/pico/pico.c
+++ b/pico/pico.c
@@ -219,7 +219,9 @@ PICO *pm;
- switch(pico_all_done){ /* prepare for/handle final events */
- case COMP_EXIT : /* already confirmed */
- packheader();
+ switch(pico_all_done){ /* prepare for/handle final events */
+ case COMP_EXIT : /* already confirmed */
+ packheader();
+#if 0
- stripwhitespace();
+ stripwhitespace();
+#endif
- c |= COMP_EXIT;
- break;
-
+ c |= COMP_EXIT;
+ break;
+
(Daniel Barkalow)
diff --git a/Documentation/asciidoc.conf b/Documentation/asciidoc.conf
index a0d8459..af5b155 100644
--- a/Documentation/asciidoc.conf
+++ b/Documentation/asciidoc.conf
@@ -61,5 +61,3 @@ ifdef::backend-xhtml11[]
[gitlink-inlinemacro]
<a href="{target}.html">{target}{0?({0})}</a>
endif::backend-xhtml11[]
-
-
diff --git a/Documentation/cmd-list.perl b/Documentation/cmd-list.perl
index 443802a..2143995 100755
--- a/Documentation/cmd-list.perl
+++ b/Documentation/cmd-list.perl
@@ -72,8 +72,6 @@ __DATA__
git-add mainporcelain
git-am mainporcelain
git-annotate ancillaryinterrogators
-git-applymbox ancillaryinterrogators
-git-applypatch purehelpers
git-apply plumbingmanipulators
git-archimport foreignscminterface
git-archive mainporcelain
@@ -88,6 +86,7 @@ git-check-attr purehelpers
git-check-ref-format purehelpers
git-cherry ancillaryinterrogators
git-cherry-pick mainporcelain
+git-citool mainporcelain
git-clean mainporcelain
git-clone mainporcelain
git-commit mainporcelain
@@ -106,6 +105,7 @@ git-diff-tree plumbinginterrogators
git-fast-import ancillarymanipulators
git-fetch mainporcelain
git-fetch-pack synchingrepositories
+git-filter-branch ancillarymanipulators
git-fmt-merge-msg purehelpers
git-for-each-ref plumbinginterrogators
git-format-patch mainporcelain
@@ -113,6 +113,7 @@ git-fsck ancillaryinterrogators
git-gc mainporcelain
git-get-tar-commit-id ancillaryinterrogators
git-grep mainporcelain
+git-gui mainporcelain
git-hash-object plumbingmanipulators
git-http-fetch synchelpers
git-http-push synchelpers
@@ -178,8 +179,10 @@ git-show-ref plumbinginterrogators
git-sh-setup purehelpers
git-ssh-fetch synchingrepositories
git-ssh-upload synchingrepositories
+git-stash mainporcelain
git-status mainporcelain
git-stripspace purehelpers
+git-submodule mainporcelain
git-svn foreignscminterface
git-svnimport foreignscminterface
git-symbolic-ref plumbingmanipulators
diff --git a/Documentation/config.txt b/Documentation/config.txt
index a75f7f7..de9e72b 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -101,7 +101,7 @@ Example
# Proxy settings
[core]
- gitProxy="ssh" for "ssh://kernel.org/"
+ gitProxy="ssh" for "kernel.org"
gitProxy=default-proxy ; for the rest
Variables
@@ -117,6 +117,18 @@ core.fileMode::
the working copy are ignored; useful on broken filesystems like FAT.
See gitlink:git-update-index[1]. True by default.
+core.quotepath::
+ The commands that output paths (e.g. `ls-files`,
+ `diff`), when not given the `-z` option, will quote
+ "unusual" characters in the pathname by enclosing the
+ pathname in a double-quote pair and with backslashes the
+ same way strings in C source code are quoted. If this
+ variable is set to false, the bytes higher than 0x80 are
+ not quoted but output as verbatim. Note that double
+ quote, backslash and control characters are always
+ quoted without `-z` regardless of the setting of this
+ variable.
+
core.autocrlf::
If true, makes git convert `CRLF` at the end of lines in text files to
`LF` when reading from the filesystem, and convert in reverse when
@@ -172,6 +184,13 @@ repository that ends in "/.git" is assumed to be not bare (bare =
false), while all other repositories are assumed to be bare (bare
= true).
+core.worktree::
+ Set the path to the working tree. The value will not be
+ used in combination with repositories found automatically in
+ a .git directory (i.e. $GIT_DIR is not set).
+ This can be overriden by the GIT_WORK_TREE environment
+ variable and the '--work-tree' command line option.
+
core.logAllRefUpdates::
Updates to a ref <ref> is logged to the file
"$GIT_DIR/logs/<ref>", by appending the new and old
@@ -204,23 +223,16 @@ core.warnAmbiguousRefs::
and might match multiple refs in the .git/refs/ tree. True by default.
core.compression::
+ An integer -1..9, indicating a default compression level.
+ -1 is the zlib default. 0 means no compression,
+ and 1..9 are various speed/size tradeoffs, 9 being slowest.
+
+core.loosecompression::
An integer -1..9, indicating the compression level for objects that
- are not in a pack file. -1 is the zlib and git default. 0 means no
+ are not in a pack file. -1 is the zlib default. 0 means no
compression, and 1..9 are various speed/size tradeoffs, 9 being
- slowest.
-
-core.legacyheaders::
- A boolean which
- changes the format of loose objects so that they are more
- efficient to pack and to send out of the repository over git
- native protocol, since v1.4.2. However, loose objects
- written in the new format cannot be read by git older than
- that version; people fetching from your repository using
- older versions of git over dumb transports (e.g. http)
- will also be affected.
-+
-To let git use the new loose object format, you have to
-set core.legacyheaders to false.
+ slowest. If not set, defaults to core.compression. If that is
+ not set, defaults to 0 (best speed).
core.packedGitWindowSize::
Number of bytes of a pack file to map into memory in a
@@ -269,6 +281,18 @@ core.excludesfile::
of files which are not meant to be tracked. See
gitlink:gitignore[5].
+core.editor::
+ Commands such as `commit` and `tag` that lets you edit
+ messages by lauching an editor uses the value of this
+ variable when it is set, and the environment variable
+ `GIT_EDITOR` is not set. The order of preference is
+ `GIT_EDITOR` environment, `core.editor`, `VISUAL` and
+ `EDITOR` environment variables and then finally `vi`.
+
+core.pager::
+ The command that git will use to paginate output. Can be overridden
+ with the `GIT_PAGER` environment variable.
+
alias.*::
Command aliases for the gitlink:git[1] command wrapper - e.g.
after defining "alias.last = cat-file commit HEAD", the invocation
@@ -369,6 +393,9 @@ color.status.<slot>::
or `untracked` (files which are not tracked by git). The values of
these variables may be specified as in color.branch.<slot>.
+commit.template::
+ Specify a file to use as the template for new commit messages.
+
diff.renameLimit::
The number of files to consider when performing the copy/rename
detection; equivalent to the git diff option '-l'.
@@ -397,6 +424,11 @@ format.suffix::
`.patch`. Use this variable to change that suffix (make sure to
include the dot if you want it).
+gc.aggressiveWindow::
+ The window size parameter used in the delta compression
+ algorithm used by 'git gc --aggressive'. This defaults
+ to 10.
+
gc.packrefs::
`git gc` does not run `git pack-refs` in a bare repository by
default so that older dumb-transport clients can still fetch
@@ -427,6 +459,11 @@ gc.rerereunresolved::
kept for this many days when `git rerere gc` is run.
The default is 15 days. See gitlink:git-rerere[1].
+rerere.enabled::
+ Activate recording of resolved conflicts, so that identical
+ conflict hunks can be resolved automatically, should they
+ be encountered again. See gitlink:git-rerere[1].
+
gitcvs.enabled::
Whether the cvs server interface is enabled for this repository.
See gitlink:git-cvsserver[1].
@@ -533,7 +570,7 @@ merge.summary::
merge.tool::
Controls which merge resolution program is used by
gitlink:git-mergetool[l]. Valid values are: "kdiff3", "tkdiff",
- "meld", "xxdiff", "emerge", "vimdiff", and "opendiff"
+ "meld", "xxdiff", "emerge", "vimdiff", "gvimdiff", and "opendiff".
merge.verbosity::
Controls the amount of output shown by the recursive merge
@@ -541,6 +578,7 @@ merge.verbosity::
message if conflicts were detected. Level 1 outputs only
conflicts, 2 outputs conflicts and file changes. Level 5 and
above outputs debugging information. The default is level 2.
+ Can be overriden by 'GIT_MERGE_VERBOSITY' environment variable.
merge.<driver>.name::
Defines a human readable name for a custom low-level
@@ -563,6 +601,28 @@ pack.depth::
The maximum delta depth used by gitlink:git-pack-objects[1] when no
maximum depth is given on the command line. Defaults to 50.
+pack.windowMemory::
+ The window memory size limit used by gitlink:git-pack-objects[1]
+ when no limit is given on the command line. The value can be
+ suffixed with "k", "m", or "g". Defaults to 0, meaning no
+ limit.
+
+pack.compression::
+ An integer -1..9, indicating the compression level for objects
+ in a pack file. -1 is the zlib default. 0 means no
+ compression, and 1..9 are various speed/size tradeoffs, 9 being
+ slowest. If not set, defaults to core.compression. If that is
+ not set, defaults to -1.
+
+pack.deltaCacheSize::
+ The maxium memory in bytes used for caching deltas in
+ gitlink:git-pack-objects[1].
+ A value of 0 means no limit. Defaults to 0.
+
+pack.deltaCacheLimit::
+ The maxium size of a delta, that is cached in
+ gitlink:git-pack-objects[1]. Defaults to 1000.
+
pull.octopus::
The default merge strategy to use when pulling multiple branches
at once.
@@ -668,5 +728,3 @@ receive.denyNonFastForwards::
transfer.unpackLimit::
When `fetch.unpackLimit` or `receive.unpackLimit` are
not set, the value of this variable is used instead.
-
-
diff --git a/Documentation/core-intro.txt b/Documentation/core-intro.txt
index eea44d9..f3cc223 100644
--- a/Documentation/core-intro.txt
+++ b/Documentation/core-intro.txt
@@ -528,7 +528,7 @@ paths that have been trivially merged.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sadly, many merges aren't trivial. If there are files that have
-been added.moved or removed, or if both branches have modified the
+been added, moved or removed, or if both branches have modified the
same file, you will be left with an index tree that contains "merge
entries" in it. Such an index tree can 'NOT' be written out to a tree
object, and you will have to resolve any such merge clashes using
diff --git a/Documentation/core-tutorial.txt b/Documentation/core-tutorial.txt
index 6b9b9ad..4fb6f41 100644
--- a/Documentation/core-tutorial.txt
+++ b/Documentation/core-tutorial.txt
@@ -9,11 +9,11 @@ repository, mainly because being hands-on and using explicit examples is
often the best way of explaining what is going on.
In normal life, most people wouldn't use the "core" git programs
-directly, but rather script around them to make them more palatable.
+directly, but rather script around them to make them more palatable.
Understanding the core git stuff may help some people get those scripts
done, though, and it may also be instructive in helping people
understand what it is that the higher-level helper scripts are actually
-doing.
+doing.
The core git is often called "plumbing", with the prettier user
interfaces on top of it called "porcelain". You may not want to use the
@@ -41,7 +41,7 @@ Creating a new git repository couldn't be easier: all git repositories start
out empty, and the only thing you need to do is find yourself a
subdirectory that you want to use as a working tree - either an empty
one for a totally new project, or an existing working tree that you want
-to import into git.
+to import into git.
For our first example, we're going to start a totally new repository from
scratch, with no pre-existing files, and we'll call it `git-tutorial`.
@@ -169,7 +169,7 @@ $ ls .git/objects/??/*
and see two files:
----------------
-.git/objects/55/7db03de997c86a4a028e1ebd3a1ceb225be238
+.git/objects/55/7db03de997c86a4a028e1ebd3a1ceb225be238
.git/objects/f2/4c74a2e500f5ee1332c86b94199f52b1d1d962
----------------
@@ -220,7 +220,7 @@ you have not actually really "checked in" your files into git so far,
you've only *told* git about them.
However, since git knows about them, you can now start using some of the
-most basic git commands to manipulate the files or look at their status.
+most basic git commands to manipulate the files or look at their status.
In particular, let's not even check in the two files into git yet, we'll
start off by adding another line to `hello` first:
@@ -350,7 +350,7 @@ Making a change
Remember how we did the `git-update-index` on file `hello` and then we
changed `hello` afterward, and could compare the new state of `hello` with the
-state we saved in the index file?
+state we saved in the index file?
Further, remember how I said that `git-write-tree` writes the contents
of the *index* file to the tree, and thus what we just committed was in
@@ -370,7 +370,7 @@ file and the working tree, `git-diff-index` shows the differences
between a committed *tree* and either the index file or the working
tree. In other words, `git-diff-index` wants a tree to be diffed
against, and before we did the commit, we couldn't do that, because we
-didn't have anything to diff against.
+didn't have anything to diff against.
But now we can do
@@ -379,7 +379,7 @@ $ git-diff-index -p HEAD
----------------
(where `-p` has the same meaning as it did in `git-diff-files`), and it
-will show us the same difference, but for a totally different reason.
+will show us the same difference, but for a totally different reason.
Now we're comparing the working tree not against the index file,
but against the tree we just wrote. It just so happens that those two
are obviously the same, so we get the same result.
@@ -398,7 +398,7 @@ working tree, but when given the `\--cached` flag, it is told to
instead compare against just the index cache contents, and ignore the
current working tree state entirely. Since we just wrote the index
file to HEAD, doing `git-diff-index \--cached -p HEAD` should thus return
-an empty set of differences, and that's exactly what it does.
+an empty set of differences, and that's exactly what it does.
[NOTE]
================
@@ -549,7 +549,7 @@ $ git-whatchanged -p --root
----------------
and you will see exactly what has changed in the repository over its
-short history.
+short history.
[NOTE]
The `\--root` flag is a flag to `git-diff-tree` to tell it to
@@ -637,7 +637,7 @@ So the mental model of "the git information is always tied directly to
the working tree that it describes" may not be technically 100%
accurate, but it's a good model for all normal use.
-This has two implications:
+This has two implications:
- if you grow bored with the tutorial repository you created (or you've
made a mistake and want to start all over), you can just do simple
@@ -705,7 +705,7 @@ Many (most?) public remote repositories will not contain any of
the checked out files or even an index file, and will *only* contain the
actual core git files. Such a repository usually doesn't even have the
`.git` subdirectory, but has all the git files directly in the
-repository.
+repository.
To create your own local live copy of such a "raw" git repository, you'd
first create your own subdirectory for the project, and then copy the
@@ -718,7 +718,7 @@ $ cd my-git
$ rsync -rL rsync://rsync.kernel.org/pub/scm/git/git.git/ .git
----------------
-followed by
+followed by
----------------
$ git-read-tree HEAD
@@ -738,7 +738,7 @@ up-to-date (so that you don't have to refresh it afterward), and the
`-a` flag means "check out all files" (if you have a stale copy or an
older version of a checked out tree you may also need to add the `-f`
flag first, to tell git-checkout-index to *force* overwriting of any old
-files).
+files).
Again, this can all be simplified with
@@ -751,7 +751,7 @@ $ git checkout
which will end up doing all of the above for you.
You have now successfully copied somebody else's (mine) remote
-repository, and checked it out.
+repository, and checked it out.
Creating a new branch
@@ -760,14 +760,14 @@ Creating a new branch
Branches in git are really nothing more than pointers into the git
object database from within the `.git/refs/` subdirectory, and as we
already discussed, the `HEAD` branch is nothing but a symlink to one of
-these object pointers.
+these object pointers.
You can at any time create a new branch by just picking an arbitrary
point in the project history, and just writing the SHA1 name of that
object into a file under `.git/refs/heads/`. You can use any filename you
want (and indeed, subdirectories), but the convention is that the
"normal" branch is called `master`. That's just a convention, though,
-and nothing enforces it.
+and nothing enforces it.
To show that as an example, let's go back to the git-tutorial repository we
used earlier, and create a branch in it. You do that by simply just
@@ -778,7 +778,7 @@ $ git checkout -b mybranch
------------
will create a new branch based at the current `HEAD` position, and switch
-to it.
+to it.
[NOTE]
================================================
@@ -825,7 +825,7 @@ checking it out and switching to it. If so, just use the command
$ git branch <branchname> [startingpoint]
------------
-which will simply _create_ the branch, but will not do anything further.
+which will simply _create_ the branch, but will not do anything further.
You can then later -- once you decide that you want to actually develop
on that branch -- switch to that branch with a regular `git checkout`
with the branchname as the argument.
@@ -884,7 +884,7 @@ $ gitk --all
will show you graphically both of your branches (that's what the `\--all`
means: normally it will just show you your current `HEAD`) and their
histories. You can also see exactly how they came to be from a common
-source.
+source.
Anyway, let's exit `gitk` (`^Q` or the File menu), and decide that we want
to merge the work we did on the `mybranch` branch into the `master`
@@ -905,8 +905,8 @@ of it as it can automatically (which in this case is just merge the `example`
file, which had no differences in the `mybranch` branch), and say:
----------------
- Auto-merging hello
- CONFLICT (content): Merge conflict in hello
+ Auto-merging hello
+ CONFLICT (content): Merge conflict in hello
Automatic merge failed; fix up by hand
----------------
@@ -1387,7 +1387,7 @@ repository. Kernel.org mirror network takes care of the
propagation to other publicly visible machines:
------------
-$ git push master.kernel.org:/pub/scm/git/git.git/
+$ git push master.kernel.org:/pub/scm/git/git.git/
------------
diff --git a/Documentation/diff-format.txt b/Documentation/diff-format.txt
index e38a1f1..0015032 100644
--- a/Documentation/diff-format.txt
+++ b/Documentation/diff-format.txt
@@ -1,7 +1,7 @@
The output format from "git-diff-index", "git-diff-tree" and
"git-diff-files" are very similar.
-These commands all compare two sets of things; what is
+These commands all compare two sets of things; what is
compared differs:
git-diff-index <tree-ish>::
@@ -126,6 +126,13 @@ the file that rename/copy produces, respectively.
If there is need for such substitution then the whole
pathname is put in double quotes.
+The similarity index is the percentage of unchanged lines, and
+the dissimilarity index is the percentage of changed lines. It
+is a rounded down integer, followed by a percent sign. The
+similarity index value of 100% is thus reserved for two equal
+files, while 100% dissimilarity means that no line from the old
+file made it into the new one.
+
combined diff format
--------------------
@@ -139,28 +146,28 @@ index fabadb8,cc95eb0..4866510
--- a/describe.c
+++ b/describe.c
@@@ -98,20 -98,12 +98,20 @@@
- return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1;
+ return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1;
}
-
+
- static void describe(char *arg)
-static void describe(struct commit *cmit, int last_one)
++static void describe(char *arg, int last_one)
{
+ unsigned char sha1[20];
+ struct commit *cmit;
- struct commit_list *list;
- static int initialized = 0;
- struct commit_name *n;
-
+ struct commit_list *list;
+ static int initialized = 0;
+ struct commit_name *n;
+
+ if (get_sha1(arg, sha1) < 0)
+ usage(describe_usage);
+ cmit = lookup_commit_reference(sha1);
+ if (!cmit)
+ usage(describe_usage);
+
- if (!initialized) {
- initialized = 1;
- for_each_ref(get_name);
+ if (!initialized) {
+ initialized = 1;
+ for_each_ref(get_name);
------------
1. It is preceded with a "git diff" header, that looks like
@@ -233,4 +240,3 @@ parents). When shown by `git diff-files -c`, it compares the
two unresolved merge parents with the working tree file
(i.e. file1 is stage 2 aka "our version", file2 is stage 3 aka
"their version").
-
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 1689c74..228ccaf 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -4,6 +4,13 @@
-u::
Synonym for "-p".
+-U<n>::
+ Shorthand for "--unified=<n>".
+
+--unified=<n>::
+ Generate diffs with <n> lines of context instead of
+ the usual three. Implies "-p".
+
--raw::
Generate the raw format.
@@ -36,7 +43,9 @@
Synonym for "-p --stat".
-z::
- \0 line termination on output
+ NUL-line termination on output. This affects the --raw
+ output field terminator. Also output from commands such
+ as "git-log" will be delimited with NUL between commits.
--name-only::
Show only names of changed files.
@@ -86,7 +95,7 @@
Detect renames.
-C::
- Detect copies as well as renames.
+ Detect copies as well as renames. See also `--find-copies-harder`.
--diff-filter=[ACDMRTUXB*]::
Select only files that are Added (`A`), Copied (`C`),
@@ -100,12 +109,13 @@
that matches other criteria, nothing is selected.
--find-copies-harder::
- For performance reasons, by default, -C option finds copies only
- if the original file of the copy was modified in the same
+ For performance reasons, by default, `-C` option finds copies only
+ if the original file of the copy was modified in the same
changeset. This flag makes the command
inspect unmodified files as candidates for the source of
copy. This is a very expensive operation for large
- projects, so use it with caution.
+ projects, so use it with caution. Giving more than one
+ `-C` option has the same effect.
-l<num>::
-M and -C options require O(n^2) processing time where n
@@ -167,5 +177,13 @@
--quiet::
Disable all output of the program. Implies --exit-code.
+--ext-diff::
+ Allow an external diff helper to be executed. If you set an
+ external diff driver with gitlink:gitattributes(5), you need
+ to use this option with gitlink:git-log(1) and friends.
+
+--no-ext-diff::
+ Disallow external diff drivers.
+
For more detailed explanation on these common options, see also
link:diffcore.html[diffcore documentation].
diff --git a/Documentation/diffcore.txt b/Documentation/diffcore.txt
index 34cd306..c6a983a 100644
--- a/Documentation/diffcore.txt
+++ b/Documentation/diffcore.txt
@@ -71,7 +71,7 @@ The first transformation in the chain is diffcore-pathspec, and
is controlled by giving the pathname parameters to the
git-diff-* commands on the command line. The pathspec is used
to limit the world diff operates in. It removes the filepairs
-outside the specified set of pathnames. E.g. If the input set
+outside the specified set of pathnames. E.g. If the input set
of filepairs included:
------------------------------------------------
@@ -269,4 +269,3 @@ Documentation
*.c
t
------------------------------------------------
-
diff --git a/Documentation/docbook-xsl.css b/Documentation/docbook-xsl.css
index 8821e30..b878b38 100644
--- a/Documentation/docbook-xsl.css
+++ b/Documentation/docbook-xsl.css
@@ -1,286 +1,286 @@
-/*
- CSS stylesheet for XHTML produced by DocBook XSL stylesheets.
- Tested with XSL stylesheets 1.61.2, 1.67.2
-*/
-
-span.strong {
- font-weight: bold;
-}
-
-body blockquote {
- margin-top: .75em;
- line-height: 1.5;
- margin-bottom: .75em;
-}
-
-html body {
- margin: 1em 5% 1em 5%;
- line-height: 1.2;
-}
-
-body div {
- margin: 0;
-}
-
-h1, h2, h3, h4, h5, h6,
-div.toc p b,
-div.list-of-figures p b,
-div.list-of-tables p b,
-div.abstract p.title
-{
- color: #527bbd;
- font-family: tahoma, verdana, sans-serif;
-}
-
-div.toc p:first-child,
-div.list-of-figures p:first-child,
-div.list-of-tables p:first-child,
-div.example p.title
-{
- margin-bottom: 0.2em;
-}
-
-body h1 {
- margin: .0em 0 0 -4%;
- line-height: 1.3;
- border-bottom: 2px solid silver;
-}
-
-body h2 {
- margin: 0.5em 0 0 -4%;
- line-height: 1.3;
- border-bottom: 2px solid silver;
-}
-
-body h3 {
- margin: .8em 0 0 -3%;
- line-height: 1.3;
-}
-
-body h4 {
- margin: .8em 0 0 -3%;
- line-height: 1.3;
-}
-
-body h5 {
- margin: .8em 0 0 -2%;
- line-height: 1.3;
-}
-
-body h6 {
- margin: .8em 0 0 -1%;
- line-height: 1.3;
-}
-
-body hr {
- border: none; /* Broken on IE6 */
-}
-div.footnotes hr {
- border: 1px solid silver;
-}
-
-div.navheader th, div.navheader td, div.navfooter td {
- font-family: sans-serif;
- font-size: 0.9em;
- font-weight: bold;
- color: #527bbd;
-}
-div.navheader img, div.navfooter img {
- border-style: none;
-}
-div.navheader a, div.navfooter a {
- font-weight: normal;
-}
-div.navfooter hr {
- border: 1px solid silver;
-}
-
-body td {
- line-height: 1.2
-}
-
-body th {
- line-height: 1.2;
-}
-
-ol {
- line-height: 1.2;
-}
-
-ul, body dir, body menu {
- line-height: 1.2;
-}
-
-html {
- margin: 0;
- padding: 0;
-}
-
-body h1, body h2, body h3, body h4, body h5, body h6 {
- margin-left: 0
-}
-
-body pre {
- margin: 0.5em 10% 0.5em 1em;
- line-height: 1.0;
- color: navy;
-}
-
-tt.literal, code.literal {
- color: navy;
-}
-
-div.literallayout p {
- padding: 0em;
- margin: 0em;
-}
-
-div.literallayout {
- font-family: monospace;
-# margin: 0.5em 10% 0.5em 1em;
- margin: 0em;
- color: navy;
- border: 1px solid silver;
- background: #f4f4f4;
- padding: 0.5em;
-}
-
-.programlisting, .screen {
- border: 1px solid silver;
- background: #f4f4f4;
- margin: 0.5em 10% 0.5em 0;
- padding: 0.5em 1em;
-}
-
-div.sidebar {
- background: #ffffee;
- margin: 1.0em 10% 0.5em 0;
- padding: 0.5em 1em;
- border: 1px solid silver;
-}
-div.sidebar * { padding: 0; }
-div.sidebar div { margin: 0; }
-div.sidebar p.title {
- font-family: sans-serif;
- margin-top: 0.5em;
- margin-bottom: 0.2em;
-}
-
-div.bibliomixed {
- margin: 0.5em 5% 0.5em 1em;
-}
-
-div.glossary dt {
- font-weight: bold;
-}
-div.glossary dd p {
- margin-top: 0.2em;
-}
-
-dl {
- margin: .8em 0;
- line-height: 1.2;
-}
-
-dt {
- margin-top: 0.5em;
-}
-
-dt span.term {
- font-style: italic;
-}
-
-div.variablelist dd p {
- margin-top: 0;
-}
-
-div.itemizedlist li, div.orderedlist li {
- margin-left: -0.8em;
- margin-top: 0.5em;
-}
-
-ul, ol {
- list-style-position: outside;
-}
-
-div.sidebar ul, div.sidebar ol {
- margin-left: 2.8em;
-}
-
-div.itemizedlist p.title,
-div.orderedlist p.title,
-div.variablelist p.title
-{
- margin-bottom: -0.8em;
-}
-
-div.revhistory table {
- border-collapse: collapse;
- border: none;
-}
-div.revhistory th {
- border: none;
- color: #527bbd;
- font-family: tahoma, verdana, sans-serif;
-}
-div.revhistory td {
- border: 1px solid silver;
-}
-
-/* Keep TOC and index lines close together. */
-div.toc dl, div.toc dt,
-div.list-of-figures dl, div.list-of-figures dt,
-div.list-of-tables dl, div.list-of-tables dt,
-div.indexdiv dl, div.indexdiv dt
-{
- line-height: normal;
- margin-top: 0;
- margin-bottom: 0;
-}
-
-/*
- Table styling does not work because of overriding attributes in
- generated HTML.
-*/
-div.table table,
-div.informaltable table
-{
- margin-left: 0;
- margin-right: 5%;
- margin-bottom: 0.8em;
-}
-div.informaltable table
-{
- margin-top: 0.4em
-}
-div.table thead,
-div.table tfoot,
-div.table tbody,
-div.informaltable thead,
-div.informaltable tfoot,
-div.informaltable tbody
-{
- /* No effect in IE6. */
- border-top: 2px solid #527bbd;
- border-bottom: 2px solid #527bbd;
-}
-div.table thead, div.table tfoot,
-div.informaltable thead, div.informaltable tfoot
-{
- font-weight: bold;
-}
-
-div.mediaobject img {
- border: 1px solid silver;
- margin-bottom: 0.8em;
-}
-div.figure p.title,
-div.table p.title
-{
- margin-top: 1em;
- margin-bottom: 0.4em;
-}
-
-@media print {
- div.navheader, div.navfooter { display: none; }
-}
+/*
+ CSS stylesheet for XHTML produced by DocBook XSL stylesheets.
+ Tested with XSL stylesheets 1.61.2, 1.67.2
+*/
+
+span.strong {
+ font-weight: bold;
+}
+
+body blockquote {
+ margin-top: .75em;
+ line-height: 1.5;
+ margin-bottom: .75em;
+}
+
+html body {
+ margin: 1em 5% 1em 5%;
+ line-height: 1.2;
+}
+
+body div {
+ margin: 0;
+}
+
+h1, h2, h3, h4, h5, h6,
+div.toc p b,
+div.list-of-figures p b,
+div.list-of-tables p b,
+div.abstract p.title
+{
+ color: #527bbd;
+ font-family: tahoma, verdana, sans-serif;
+}
+
+div.toc p:first-child,
+div.list-of-figures p:first-child,
+div.list-of-tables p:first-child,
+div.example p.title
+{
+ margin-bottom: 0.2em;
+}
+
+body h1 {
+ margin: .0em 0 0 -4%;
+ line-height: 1.3;
+ border-bottom: 2px solid silver;
+}
+
+body h2 {
+ margin: 0.5em 0 0 -4%;
+ line-height: 1.3;
+ border-bottom: 2px solid silver;
+}
+
+body h3 {
+ margin: .8em 0 0 -3%;
+ line-height: 1.3;
+}
+
+body h4 {
+ margin: .8em 0 0 -3%;
+ line-height: 1.3;
+}
+
+body h5 {
+ margin: .8em 0 0 -2%;
+ line-height: 1.3;
+}
+
+body h6 {
+ margin: .8em 0 0 -1%;
+ line-height: 1.3;
+}
+
+body hr {
+ border: none; /* Broken on IE6 */
+}
+div.footnotes hr {
+ border: 1px solid silver;
+}
+
+div.navheader th, div.navheader td, div.navfooter td {
+ font-family: sans-serif;
+ font-size: 0.9em;
+ font-weight: bold;
+ color: #527bbd;
+}
+div.navheader img, div.navfooter img {
+ border-style: none;
+}
+div.navheader a, div.navfooter a {
+ font-weight: normal;
+}
+div.navfooter hr {
+ border: 1px solid silver;
+}
+
+body td {
+ line-height: 1.2
+}
+
+body th {
+ line-height: 1.2;
+}
+
+ol {
+ line-height: 1.2;
+}
+
+ul, body dir, body menu {
+ line-height: 1.2;
+}
+
+html {
+ margin: 0;
+ padding: 0;
+}
+
+body h1, body h2, body h3, body h4, body h5, body h6 {
+ margin-left: 0
+}
+
+body pre {
+ margin: 0.5em 10% 0.5em 1em;
+ line-height: 1.0;
+ color: navy;
+}
+
+tt.literal, code.literal {
+ color: navy;
+}
+
+div.literallayout p {
+ padding: 0em;
+ margin: 0em;
+}
+
+div.literallayout {
+ font-family: monospace;
+# margin: 0.5em 10% 0.5em 1em;
+ margin: 0em;
+ color: navy;
+ border: 1px solid silver;
+ background: #f4f4f4;
+ padding: 0.5em;
+}
+
+.programlisting, .screen {
+ border: 1px solid silver;
+ background: #f4f4f4;
+ margin: 0.5em 10% 0.5em 0;
+ padding: 0.5em 1em;
+}
+
+div.sidebar {
+ background: #ffffee;
+ margin: 1.0em 10% 0.5em 0;
+ padding: 0.5em 1em;
+ border: 1px solid silver;
+}
+div.sidebar * { padding: 0; }
+div.sidebar div { margin: 0; }
+div.sidebar p.title {
+ font-family: sans-serif;
+ margin-top: 0.5em;
+ margin-bottom: 0.2em;
+}
+
+div.bibliomixed {
+ margin: 0.5em 5% 0.5em 1em;
+}
+
+div.glossary dt {
+ font-weight: bold;
+}
+div.glossary dd p {
+ margin-top: 0.2em;
+}
+
+dl {
+ margin: .8em 0;
+ line-height: 1.2;
+}
+
+dt {
+ margin-top: 0.5em;
+}
+
+dt span.term {
+ font-style: italic;
+}
+
+div.variablelist dd p {
+ margin-top: 0;
+}
+
+div.itemizedlist li, div.orderedlist li {
+ margin-left: -0.8em;
+ margin-top: 0.5em;
+}
+
+ul, ol {
+ list-style-position: outside;
+}
+
+div.sidebar ul, div.sidebar ol {
+ margin-left: 2.8em;
+}
+
+div.itemizedlist p.title,
+div.orderedlist p.title,
+div.variablelist p.title
+{
+ margin-bottom: -0.8em;
+}
+
+div.revhistory table {
+ border-collapse: collapse;
+ border: none;
+}
+div.revhistory th {
+ border: none;
+ color: #527bbd;
+ font-family: tahoma, verdana, sans-serif;
+}
+div.revhistory td {
+ border: 1px solid silver;
+}
+
+/* Keep TOC and index lines close together. */
+div.toc dl, div.toc dt,
+div.list-of-figures dl, div.list-of-figures dt,
+div.list-of-tables dl, div.list-of-tables dt,
+div.indexdiv dl, div.indexdiv dt
+{
+ line-height: normal;
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+/*
+ Table styling does not work because of overriding attributes in
+ generated HTML.
+*/
+div.table table,
+div.informaltable table
+{
+ margin-left: 0;
+ margin-right: 5%;
+ margin-bottom: 0.8em;
+}
+div.informaltable table
+{
+ margin-top: 0.4em
+}
+div.table thead,
+div.table tfoot,
+div.table tbody,
+div.informaltable thead,
+div.informaltable tfoot,
+div.informaltable tbody
+{
+ /* No effect in IE6. */
+ border-top: 2px solid #527bbd;
+ border-bottom: 2px solid #527bbd;
+}
+div.table thead, div.table tfoot,
+div.informaltable thead, div.informaltable tfoot
+{
+ font-weight: bold;
+}
+
+div.mediaobject img {
+ border: 1px solid silver;
+ margin-bottom: 0.8em;
+}
+div.figure p.title,
+div.table p.title
+{
+ margin-top: 1em;
+ margin-bottom: 0.4em;
+}
+
+@media print {
+ div.navheader, div.navfooter { display: none; }
+}
diff --git a/Documentation/docbook.xsl b/Documentation/docbook.xsl
new file mode 100644
index 0000000..9a6912c
--- /dev/null
+++ b/Documentation/docbook.xsl
@@ -0,0 +1,5 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version='1.0'>
+ <xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl"/>
+ <xsl:output method="html" encoding="UTF-8" indent="no" />
+</xsl:stylesheet>
diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt
index bdc7332..da03422 100644
--- a/Documentation/fetch-options.txt
+++ b/Documentation/fetch-options.txt
@@ -52,4 +52,3 @@
Deepen the history of a 'shallow' repository created by
`git clone` with `--depth=<depth>` option (see gitlink:git-clone[1])
by the specified number of commits.
-
diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt
index a0c9f68..4af3a9b 100644
--- a/Documentation/git-add.txt
+++ b/Documentation/git-add.txt
@@ -3,7 +3,7 @@ git-add(1)
NAME
----
-git-add - Add file contents to the changeset to be committed next
+git-add - Add file contents to the index
SYNOPSIS
--------
@@ -11,24 +11,27 @@ SYNOPSIS
DESCRIPTION
-----------
-All the changed file contents to be committed together in a single set
-of changes must be "added" with the 'add' command before using the
-'commit' command. This is not only for adding new files. Even modified
-files must be added to the set of changes about to be committed.
+This command adds the current content of new or modified files to the
+index, thus staging that content for inclusion in the next commit.
-This command can be performed multiple times before a commit. The added
-content corresponds to the state of specified file(s) at the time the
-'add' command is used. This means the 'commit' command will not consider
-subsequent changes to already added content if it is not added again before
-the commit.
+The "index" holds a snapshot of the content of the working tree, and it
+is this snapshot that is taken as the contents of the next commit. Thus
+after making any changes to the working directory, and before running
+the commit command, you must use the 'add' command to add any new or
+modified files to the index.
-The 'git status' command can be used to obtain a summary of what is included
-for the next commit.
+This command can be performed multiple times before a commit. It only
+adds the content of the specified file(s) at the time the add command is
+run; if you want subsequent changes included in the next commit, then
+you must run 'git add' again to add the new content to the index.
-This command can be used to add ignored files with `-f` (force)
-option, but they have to be
-explicitly and exactly specified from the command line. File globbing
-and recursive behaviour do not add ignored files.
+The 'git status' command can be used to obtain a summary of which
+files have changes that are staged for the next commit.
+
+The 'add' command can be used to add ignored files with `-f` (force)
+option, but they have to be explicitly and exactly specified from the
+command line. File globbing and recursive behaviour do not add ignored
+files.
Please see gitlink:git-commit[1] for alternative ways to add content to a
commit.
@@ -228,4 +231,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-am.txt b/Documentation/git-am.txt
index ba79773..e4a6b3a 100644
--- a/Documentation/git-am.txt
+++ b/Documentation/git-am.txt
@@ -12,7 +12,7 @@ SYNOPSIS
'git-am' [--signoff] [--dotest=<dir>] [--keep] [--utf8 | --no-utf8]
[--3way] [--interactive] [--binary]
[--whitespace=<option>] [-C<n>] [-p<n>]
- <mbox>...
+ <mbox>|<Maildir>...
'git-am' [--skip | --resolved]
DESCRIPTION
@@ -23,9 +23,10 @@ current branch.
OPTIONS
-------
-<mbox>...::
+<mbox>|<Maildir>...::
The list of mailbox files to read patches from. If you do not
- supply this argument, reads from the standard input.
+ supply this argument, reads from the standard input. If you supply
+ directories, they'll be treated as Maildirs.
-s, --signoff::
Add `Signed-off-by:` line to the commit message, using
@@ -126,8 +127,7 @@ is terminated before the first occurrence of such a line.
When initially invoking it, you give it names of the mailboxes
to crunch. Upon seeing the first patch that does not apply, it
-aborts in the middle, just like 'git-applymbox' does. You can
-recover from this in one of two ways:
+aborts in the middle,. You can recover from this in one of two ways:
. skip the current patch by re-running the command with '--skip'
option.
@@ -144,7 +144,7 @@ names.
SEE ALSO
--------
-gitlink:git-applymbox[1], gitlink:git-applypatch[1], gitlink:git-apply[1].
+gitlink:git-apply[1].
Author
@@ -158,4 +158,3 @@ Documentation by Petr Baudis, Junio C Hamano and the git-list <git@vger.kernel.o
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt
index 3bd2c99..f03f661 100644
--- a/Documentation/git-apply.txt
+++ b/Documentation/git-apply.txt
@@ -183,4 +183,3 @@ Documentation by Junio C Hamano
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-applymbox.txt b/Documentation/git-applymbox.txt
deleted file mode 100644
index ea919ba..0000000
--- a/Documentation/git-applymbox.txt
+++ /dev/null
@@ -1,98 +0,0 @@
-git-applymbox(1)
-================
-
-NAME
-----
-git-applymbox - Apply a series of patches in a mailbox
-
-
-SYNOPSIS
---------
-'git-applymbox' [-u] [-k] [-q] [-m] ( -c .dotest/<num> | <mbox> ) [ <signoff> ]
-
-DESCRIPTION
------------
-Splits mail messages in a mailbox into commit log message,
-authorship information and patches, and applies them to the
-current branch.
-
-
-OPTIONS
--------
--q::
- Apply patches interactively. The user will be given
- opportunity to edit the log message and the patch before
- attempting to apply it.
-
--k::
- Usually the program 'cleans up' the Subject: header line
- to extract the title line for the commit log message,
- among which (1) remove 'Re:' or 're:', (2) leading
- whitespaces, (3) '[' up to ']', typically '[PATCH]', and
- then prepends "[PATCH] ". This flag forbids this
- munging, and is most useful when used to read back 'git
- format-patch -k' output.
-
--m::
- Patches are applied with `git-apply` command, and unless
- it cleanly applies without fuzz, the processing fails.
- With this flag, if a tree that the patch applies cleanly
- is found in a repository, the patch is applied to the
- tree and then a 3-way merge between the resulting tree
- and the current tree.
-
--u::
- Pass `-u` flag to `git-mailinfo` (see gitlink:git-mailinfo[1]).
- The proposed commit log message taken from the e-mail
- are re-coded into UTF-8 encoding (configuration variable
- `i18n.commitencoding` can be used to specify project's
- preferred encoding if it is not UTF-8). This used to be
- optional but now it is the default.
-+
-Note that the patch is always used as-is without charset
-conversion, even with this flag.
-
--n::
- Pass `-n` flag to `git-mailinfo` (see
- gitlink:git-mailinfo[1]).
-
--c .dotest/<num>::
- When the patch contained in an e-mail does not cleanly
- apply, the command exits with an error message. The
- patch and extracted message are found in .dotest/, and
- you could re-run 'git applymbox' with '-c .dotest/<num>'
- flag to restart the process after inspecting and fixing
- them.
-
-<mbox>::
- The name of the file that contains the e-mail messages
- with patches. This file should be in the UNIX mailbox
- format. See 'SubmittingPatches' document to learn about
- the formatting convention for e-mail submission.
-
-<signoff>::
- The name of the file that contains your "Signed-off-by"
- line. See 'SubmittingPatches' document to learn what
- "Signed-off-by" line means. You can also just say
- 'yes', 'true', 'me', or 'please' to use an automatically
- generated "Signed-off-by" line based on your committer
- identity.
-
-
-SEE ALSO
---------
-gitlink:git-am[1], gitlink:git-applypatch[1].
-
-
-Author
-------
-Written by Linus Torvalds <torvalds@osdl.org>
-
-Documentation
---------------
-Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
-
-GIT
----
-Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-applypatch.txt b/Documentation/git-applypatch.txt
deleted file mode 100644
index 451434a..0000000
--- a/Documentation/git-applypatch.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-git-applypatch(1)
-=================
-
-NAME
-----
-git-applypatch - Apply one patch extracted from an e-mail
-
-
-SYNOPSIS
---------
-'git-applypatch' <msg> <patch> <info> [<signoff>]
-
-DESCRIPTION
------------
-This is usually not what an end user wants to run directly. See
-gitlink:git-am[1] instead.
-
-Takes three files <msg>, <patch>, and <info> prepared from an
-e-mail message by 'git-mailinfo', and creates a commit. It is
-usually not necessary to use this command directly.
-
-This command can run `applypatch-msg`, `pre-applypatch`, and
-`post-applypatch` hooks. See link:hooks.html[hooks] for more
-information.
-
-
-OPTIONS
--------
-<msg>::
- Commit log message (sans the first line, which comes
- from e-mail Subject stored in <info>).
-
-<patch>::
- The patch to apply.
-
-<info>::
- Author and subject information extracted from e-mail,
- used on "author" line and as the first line of the
- commit log message.
-
-
-Author
-------
-Written by Linus Torvalds <torvalds@osdl.org>
-
-Documentation
---------------
-Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
-
-GIT
----
-Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-archimport.txt b/Documentation/git-archimport.txt
index 82cb41d..7091b8d 100644
--- a/Documentation/git-archimport.txt
+++ b/Documentation/git-archimport.txt
@@ -17,26 +17,26 @@ DESCRIPTION
Imports a project from one or more Arch repositories. It will follow branches
and repositories within the namespaces defined by the <archive/branch>
parameters supplied. If it cannot find the remote branch a merge comes from
-it will just import it as a regular commit. If it can find it, it will mark it
-as a merge whenever possible (see discussion below).
+it will just import it as a regular commit. If it can find it, it will mark it
+as a merge whenever possible (see discussion below).
-The script expects you to provide the key roots where it can start the import
-from an 'initial import' or 'tag' type of Arch commit. It will follow and
-import new branches within the provided roots.
+The script expects you to provide the key roots where it can start the import
+from an 'initial import' or 'tag' type of Arch commit. It will follow and
+import new branches within the provided roots.
-It expects to be dealing with one project only. If it sees
-branches that have different roots, it will refuse to run. In that case,
-edit your <archive/branch> parameters to define clearly the scope of the
-import.
+It expects to be dealing with one project only. If it sees
+branches that have different roots, it will refuse to run. In that case,
+edit your <archive/branch> parameters to define clearly the scope of the
+import.
-`git-archimport` uses `tla` extensively in the background to access the
+`git-archimport` uses `tla` extensively in the background to access the
Arch repository.
Make sure you have a recent version of `tla` available in the path. `tla` must
-know about the repositories you pass to `git-archimport`.
+know about the repositories you pass to `git-archimport`.
-For the initial import `git-archimport` expects to find itself in an empty
-directory. To follow the development of a project that uses Arch, rerun
-`git-archimport` with the same parameters as the initial import to perform
+For the initial import `git-archimport` expects to find itself in an empty
+directory. To follow the development of a project that uses Arch, rerun
+`git-archimport` with the same parameters as the initial import to perform
incremental imports.
While git-archimport will try to create sensible branch names for the
@@ -54,15 +54,15 @@ convert Arch repositories that had been rotated periodically.
MERGES
------
-Patch merge data from Arch is used to mark merges in git as well. git
+Patch merge data from Arch is used to mark merges in git as well. git
does not care much about tracking patches, and only considers a merge when a
branch incorporates all the commits since the point they forked. The end result
-is that git will have a good idea of how far branches have diverged. So the
+is that git will have a good idea of how far branches have diverged. So the
import process does lose some patch-trading metadata.
-Fortunately, when you try and merge branches imported from Arch,
-git will find a good merge base, and it has a good chance of identifying
-patches that have been traded out-of-sequence between the branches.
+Fortunately, when you try and merge branches imported from Arch,
+git will find a good merge base, and it has a good chance of identifying
+patches that have been traded out-of-sequence between the branches.
OPTIONS
-------
@@ -71,10 +71,10 @@ OPTIONS
Display usage.
-v::
- Verbose output.
+ Verbose output.
-T::
- Many tags. Will create a tag for every commit, reflecting the commit
+ Many tags. Will create a tag for every commit, reflecting the commit
name in the Arch repository.
-f::
@@ -104,7 +104,7 @@ OPTIONS
<archive/branch>::
- Archive/branch identifier in a format that `tla log` understands.
+ Archive/branch identifier in a format that `tla log` understands.
Author
@@ -118,4 +118,3 @@ Documentation by Junio C Hamano, Martin Langhoff and the git-list <git@vger.kern
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt
index 5f68ee1..1072fb8 100644
--- a/Documentation/git-bisect.txt
+++ b/Documentation/git-bisect.txt
@@ -8,7 +8,7 @@ git-bisect - Find the change that introduced a bug by binary search
SYNOPSIS
--------
-'git bisect' <subcommand> <options>
+'git bisect' <subcommand> <options>
DESCRIPTION
-----------
@@ -200,4 +200,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-blame.txt b/Documentation/git-blame.txt
index 44678b0..66f1203 100644
--- a/Documentation/git-blame.txt
+++ b/Documentation/git-blame.txt
@@ -8,7 +8,7 @@ git-blame - Show what revision and author last modified each line of a file
SYNOPSIS
--------
[verse]
-'git-blame' [-c] [-b] [--root] [-s] [-l] [-t] [-f] [-n] [-p] [--incremental] [-L n,m]
+'git-blame' [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-p] [-w] [--incremental] [-L n,m]
[-S <revs-file>] [-M] [-C] [-C] [--since=<date>]
[<rev> | --contents <file>] [--] <file>
@@ -63,6 +63,11 @@ include::blame-options.txt[]
-s::
Suppress author name and timestamp from the output.
+-w::
+ Ignore whitespace when comparing parent's version and
+ child's to find where the lines came from.
+
+
THE PORCELAIN FORMAT
--------------------
diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index 8dc5171..33bc31b 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -41,7 +41,7 @@ to happen.
With a `-d` or `-D` option, `<branchname>` will be deleted. You may
specify more than one branch for deletion. If the branch currently
-has a ref log then the ref log will also be deleted. Use -r together with -d
+has a reflog then the reflog will also be deleted. Use -r together with -d
to delete remote-tracking branches.
@@ -54,9 +54,9 @@ OPTIONS
Delete a branch irrespective of its index status.
-l::
- Create the branch's ref log. This activates recording of
- all changes to made the branch ref, enabling use of date
- based sha1 expressions such as "<branchname>@{yesterday}".
+ 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}".
-f::
Force the creation of a new branch even if it means deleting
@@ -130,12 +130,12 @@ Delete unneeded branch::
------------
$ git clone git://git.kernel.org/.../git.git my.git
$ cd my.git
-$ git branch -d -r todo html man <1>
-$ git branch -D test <2>
+$ git branch -d -r origin/todo origin/html origin/man <1>
+$ git branch -D test <2>
------------
+
-<1> delete remote-tracking branches "todo", "html", "man"
-<2> delete "test" branch even if the "master" branch does not have all
+<1> Delete remote-tracking branches "todo", "html", "man"
+<2> Delete "test" branch even if the "master" branch does not have all
commits from test branch.
@@ -158,4 +158,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-cat-file.txt b/Documentation/git-cat-file.txt
index 075c0d0..afa095c 100644
--- a/Documentation/git-cat-file.txt
+++ b/Documentation/git-cat-file.txt
@@ -71,4 +71,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-check-attr.txt b/Documentation/git-check-attr.txt
index ceb5195..856d2af 100644
--- a/Documentation/git-check-attr.txt
+++ b/Documentation/git-check-attr.txt
@@ -34,4 +34,3 @@ Documentation by James Bowes.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-checkout-index.txt b/Documentation/git-checkout-index.txt
index 6dd6db0..b1a8ce1 100644
--- a/Documentation/git-checkout-index.txt
+++ b/Documentation/git-checkout-index.txt
@@ -182,4 +182,3 @@ Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 918d8ee..818b720 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -62,9 +62,9 @@ OPTIONS
configuration variable.
-l::
- Create the new branch's ref log. This activates recording of
- all changes to made the branch ref, enabling use of date
- based sha1 expressions such as "<branchname>@{yesterday}".
+ Create the new 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}".
-m::
If you have local modifications to one or more files that
@@ -215,4 +215,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-cherry-pick.txt b/Documentation/git-cherry-pick.txt
index 68bba98..47b1e8c 100644
--- a/Documentation/git-cherry-pick.txt
+++ b/Documentation/git-cherry-pick.txt
@@ -68,4 +68,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-cherry.txt b/Documentation/git-cherry.txt
index 8c7d967..e694382 100644
--- a/Documentation/git-cherry.txt
+++ b/Documentation/git-cherry.txt
@@ -67,4 +67,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-citool.txt b/Documentation/git-citool.txt
new file mode 100644
index 0000000..5217ab2
--- /dev/null
+++ b/Documentation/git-citool.txt
@@ -0,0 +1,32 @@
+git-citool(1)
+=============
+
+NAME
+----
+git-citool - Graphical alternative to git-commit
+
+SYNOPSIS
+--------
+'git citool'
+
+DESCRIPTION
+-----------
+A Tcl/Tk based graphical interface to review modified files, stage
+them into the index, enter a commit message and record the new
+commit onto the current branch. This interface is an alternative
+to the less interactive gitlink:git-commit[1] program.
+
+git-citool is actually a standard alias for 'git gui citool'.
+See gitlink:git-gui[1] for more details.
+
+Author
+------
+Written by Shawn O. Pearce <spearce@spearce.org>.
+
+Documentation
+--------------
+Documentation by Shawn O. Pearce <spearce@spearce.org>.
+
+GIT
+---
+Part of the gitlink:git[7] suite
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index ac938d3..a0a10e3 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -64,6 +64,7 @@ OPTIONS
Operate quietly. This flag is passed to "rsync" and
"git-fetch-pack" commands when given.
+--no-checkout::
-n::
No checkout of HEAD is performed after the clone is complete.
@@ -106,8 +107,9 @@ OPTIONS
as patches.
<repository>::
- The (possibly remote) repository to clone from. It can
- be any URL git-fetch supports.
+ The (possibly remote) repository to clone from. See the
+ <<URLS,URLS>> section below for more information on specifying
+ repositories.
<directory>::
The name of a new directory to clone into. The "humanish"
@@ -116,6 +118,8 @@ OPTIONS
for "host.xz:foo/.git"). Cloning into an existing directory
is not allowed.
+include::urls.txt[]
+
Examples
--------
@@ -175,4 +179,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-commit-tree.txt b/Documentation/git-commit-tree.txt
index 504a3aa..5870c2c 100644
--- a/Documentation/git-commit-tree.txt
+++ b/Documentation/git-commit-tree.txt
@@ -40,7 +40,7 @@ OPTIONS
-p <parent commit>::
Each '-p' indicates the id of a parent commit object.
-
+
Commit Information
------------------
@@ -72,7 +72,7 @@ GIT_AUTHOR_EMAIL:
name = "Your Name"
email = "your@email.address.xz"
-A commit comment is read from stdin (max 999 chars). If a changelog
+A commit comment is read from stdin. If a changelog
entry is not provided via "<" redirection, "git-commit-tree" will just wait
for one to be entered and terminated with ^D.
@@ -107,4 +107,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt
index 53a7bb0..63599d3 100644
--- a/Documentation/git-commit.txt
+++ b/Documentation/git-commit.txt
@@ -8,33 +8,33 @@ git-commit - Record changes to the repository
SYNOPSIS
--------
[verse]
-'git-commit' [-a | --interactive] [-s] [-v]
+'git-commit' [-a | --interactive] [-s] [-v] [-u]
[(-c | -C) <commit> | -F <file> | -m <msg> | --amend]
[--no-verify] [-e] [--author <author>]
[--] [[-i | -o ]<file>...]
DESCRIPTION
-----------
-Use 'git commit' when you want to record your changes into the repository
-along with a log message describing what the commit is about. All changes
-to be committed must be explicitly identified using one of the following
-methods:
+Use 'git commit' to store the current contents of the index in a new
+commit along with a log message describing the changes you have made.
+The content to be added can be specified in several ways:
1. by using gitlink:git-add[1] to incrementally "add" changes to the
- next commit before using the 'commit' command (Note: even modified
+ index before using the 'commit' command (Note: even modified
files must be "added");
-2. by using gitlink:git-rm[1] to identify content removal for the next
- commit, again before using the 'commit' command;
+2. by using gitlink:git-rm[1] to remove files from the working tree
+ and the index, again before using the 'commit' command;
-3. by directly listing files containing changes to be committed as arguments
- to the 'commit' command, in which cases only those files alone will be
- considered for the commit;
+3. by listing files as arguments to the 'commit' command, in which
+ case the commit will ignore changes staged in the index, and instead
+ record the current content of the listed files;
-4. by using the -a switch with the 'commit' command to automatically "add"
- changes from all known files i.e. files that have already been committed
- before, and to automatically "rm" files that have been
- removed from the working tree, and perform the actual commit.
+4. by using the -a switch with the 'commit' command to automatically
+ "add" changes from all known files (i.e. all files that are already
+ listed in the index) and to automatically "rm" files in the index
+ that have been removed from the working tree, and then perform the
+ actual commit;
5. by using the --interactive switch with the 'commit' command to decide one
by one which files should be part of the commit, before finalizing the
@@ -71,9 +71,16 @@ OPTIONS
Override the author name used in the commit. Use
`A U Thor <author@example.com>` format.
--m <msg>::
+-m <msg>|--message=<msg>::
Use the given <msg> as the commit message.
+-t <file>|--template=<file>::
+ Use the contents of the given file as the initial version
+ of the commit message. The editor is invoked and you can
+ make subsequent changes. If a message is specified using
+ the `-m` or `-F` options, this option has no effect. This
+ overrides the `commit.template` configuration variable.
+
-s|--signoff::
Add Signed-off-by line at the end of the commit message.
@@ -115,6 +122,19 @@ but can be used to amend a merge commit.
as well. This is usually not what you want unless you
are concluding a conflicted merge.
+-u|--untracked-files::
+ Show all untracked files, also those in uninteresting
+ directories, in the "Untracked files:" section of commit
+ message template. Without this option only its name and
+ a trailing slash are displayed for each untracked
+ directory.
+
+-v|--verbose::
+ Show unified diff between the HEAD commit and what
+ would be committed at the bottom of the commit message
+ template. Note that this diff output doesn't have its
+ lines prefixed with '#'.
+
-q|--quiet::
Suppress commit summary message.
@@ -231,10 +251,12 @@ on the Subject: line and the rest of the commit in the body.
include::i18n.txt[]
-ENVIRONMENT VARIABLES
----------------------
-The command specified by either the VISUAL or EDITOR environment
-variables is used to edit the commit log message.
+ENVIRONMENT AND CONFIGURATION VARIABLES
+---------------------------------------
+The editor used to edit the commit log message will be chosen from the
+GIT_EDITOR environment variable, the core.editor configuration variable, the
+VISUAL environment variable, or the EDITOR environment variable (in that
+order).
HOOKS
-----
diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt
index 387d7bc..c3dffff 100644
--- a/Documentation/git-config.txt
+++ b/Documentation/git-config.txt
@@ -9,17 +9,17 @@ git-config - Get and set repository or global options
SYNOPSIS
--------
[verse]
-'git-config' [--system | --global] name [value [value_regex]]
-'git-config' [--system | --global] --add name value
-'git-config' [--system | --global] --replace-all name [value [value_regex]]
-'git-config' [--system | --global] [type] --get name [value_regex]
-'git-config' [--system | --global] [type] --get-all name [value_regex]
-'git-config' [--system | --global] [type] --get-regexp name_regex [value_regex]
-'git-config' [--system | --global] --unset name [value_regex]
-'git-config' [--system | --global] --unset-all name [value_regex]
-'git-config' [--system | --global] --rename-section old_name new_name
-'git-config' [--system | --global] --remove-section name
-'git-config' [--system | --global] -l | --list
+'git-config' [<file-option>] [type] [-z|--null] name [value [value_regex]]
+'git-config' [<file-option>] [type] --add name value
+'git-config' [<file-option>] [type] --replace-all name [value [value_regex]]
+'git-config' [<file-option>] [type] [-z|--null] --get name [value_regex]
+'git-config' [<file-option>] [type] [-z|--null] --get-all name [value_regex]
+'git-config' [<file-option>] [type] [-z|--null] --get-regexp name_regex [value_regex]
+'git-config' [<file-option>] --unset name [value_regex]
+'git-config' [<file-option>] --unset-all name [value_regex]
+'git-config' [<file-option>] --rename-section old_name new_name
+'git-config' [<file-option>] --remove-section name
+'git-config' [<file-option>] [-z|--null] -l | --list
DESCRIPTION
-----------
@@ -37,14 +37,19 @@ prepend a single exclamation mark in front (see also <<EXAMPLES>>).
The type specifier can be either '--int' or '--bool', which will make
'git-config' ensure that the variable(s) are of the given type and
convert the value to the canonical form (simple decimal number for int,
-a "true" or "false" string for bool). Type specifiers currently only
-take effect for reading operations. If no type specifier is passed,
+a "true" or "false" string for bool). If no type specifier is passed,
no checks or transformations are performed on the value.
+The file-option can be one of '--system', '--global' or '--file'
+which specify where the values will be read from or written to.
+The default is to assume the config file of the current repository,
+.git/config unless defined otherwise with GIT_DIR and GIT_CONFIG
+(see <<FILES>>).
+
This command will fail if:
-. The .git/config file is invalid,
-. Can not write to .git/config,
+. The config file is invalid,
+. Can not write to the config file,
. no section was provided,
. the section or key is invalid,
. you try to unset an option which does not exist,
@@ -94,6 +99,9 @@ rather than from all available files.
+
See also <<FILES>>.
+-f config-file, --file config-file::
+ Use the given config file instead of the one specified by GIT_CONFIG.
+
--remove-section::
Remove the given section from the configuration file.
@@ -118,13 +126,21 @@ See also <<FILES>>.
in the config file will cause the value to be multiplied
by 1024, 1048576, or 1073741824 prior to output.
+-z, --null::
+ For all options that output values and/or keys, always
+ end values with with the null character (instead of a
+ newline). Use newline instead as a delimiter between
+ key and value. This allows for secure parsing of the
+ output without getting confused e.g. by values that
+ contain line breaks.
+
[[FILES]]
FILES
-----
-There are three files where git-config will search for configuration
-options:
+If not set explicitely with '--file', there are three files where
+git-config will search for configuration options:
.git/config::
Repository specific configuration file. (The filename is
@@ -198,9 +214,7 @@ Given a .git/config like this:
; Proxy settings
[core]
- gitproxy="ssh" for "ssh://kernel.org/"
gitproxy="proxy-command" for kernel.org
- gitproxy="myprotocol-command" for "my://"
gitproxy=default-proxy ; for all the rest
you can set the filemode to true with
@@ -275,7 +289,7 @@ To actually match only values with an exclamation mark, you have to
To add a new proxy, without altering any of the existing ones, use
------------
-% git config core.gitproxy '"proxy" for example.com'
+% git config core.gitproxy '"proxy-command" for example.com'
------------
@@ -293,4 +307,3 @@ Documentation by Johannes Schindelin, Petr Baudis and the git-list <git@vger.ker
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-convert-objects.txt b/Documentation/git-convert-objects.txt
index b1220c0..9718abf 100644
--- a/Documentation/git-convert-objects.txt
+++ b/Documentation/git-convert-objects.txt
@@ -26,4 +26,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-count-objects.txt b/Documentation/git-count-objects.txt
index 91c8c92..8161411 100644
--- a/Documentation/git-count-objects.txt
+++ b/Documentation/git-count-objects.txt
@@ -35,4 +35,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-cvsexportcommit.txt b/Documentation/git-cvsexportcommit.txt
index f3590de..6c423e3 100644
--- a/Documentation/git-cvsexportcommit.txt
+++ b/Documentation/git-cvsexportcommit.txt
@@ -8,25 +8,25 @@ git-cvsexportcommit - Export a single commit to a CVS checkout
SYNOPSIS
--------
-'git-cvsexportcommit' [-h] [-v] [-c] [-P] [-p] [-a] [-d cvsroot] [-f] [-m msgprefix] [PARENTCOMMIT] COMMITID
+'git-cvsexportcommit' [-h] [-u] [-v] [-c] [-P] [-p] [-a] [-d cvsroot] [-f] [-m msgprefix] [PARENTCOMMIT] COMMITID
DESCRIPTION
-----------
Exports a commit from GIT to a CVS checkout, making it easier
-to merge patches from a git repository into a CVS repository.
+to merge patches from a git repository into a CVS repository.
-Execute it from the root of the CVS working copy. GIT_DIR must be defined.
+Execute it from the root of the CVS working copy. GIT_DIR must be defined.
See examples below.
-It does its best to do the safe thing, it will check that the files are
-unchanged and up to date in the CVS checkout, and it will not autocommit
+It does its best to do the safe thing, it will check that the files are
+unchanged and up to date in the CVS checkout, and it will not autocommit
by default.
Supports file additions, removals, and commits that affect binary files.
If the commit is a merge commit, you must tell git-cvsexportcommit what parent
-should the changeset be done against.
+should the changeset be done against.
OPTIONS
-------
@@ -55,9 +55,12 @@ OPTIONS
Force the parent commit, even if it is not a direct parent.
-m::
- Prepend the commit message with the provided prefix.
+ Prepend the commit message with the provided prefix.
Useful for patch series and the like.
+-u::
+ Update affected files from cvs repository before attempting export.
+
-v::
Verbose.
@@ -70,7 +73,7 @@ Merge one patch into CVS::
$ export GIT_DIR=~/project/.git
$ cd ~/project_cvs_checkout
$ git-cvsexportcommit -v <commit-sha1>
-$ cvs commit -F .mgs <files>
+$ cvs commit -F .mgs <files>
------------
Merge pending patches into CVS automatically -- only if you really know what you are doing::
@@ -92,4 +95,3 @@ Documentation by Martin Langhoff <martin@catalyst.net.nz>
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-cvsimport.txt b/Documentation/git-cvsimport.txt
index e0be856..fdd7ec7 100644
--- a/Documentation/git-cvsimport.txt
+++ b/Documentation/git-cvsimport.txt
@@ -13,7 +13,7 @@ SYNOPSIS
[-A <author-conv-file>] [-p <options-for-cvsps>] [-P <file>]
[-C <git_repository>] [-z <fuzz>] [-i] [-k] [-u] [-s <subst>]
[-a] [-m] [-M <regex>] [-S <regex>] [-L <commitlimit>]
- [<CVS_module>]
+ [-r <remote>] [<CVS_module>]
DESCRIPTION
@@ -25,10 +25,12 @@ Splitting the CVS log into patch sets is done by 'cvsps'.
At least version 2.1 is required.
You should *never* do any work of your own on the branches that are
-created by git-cvsimport. The initial import will create and populate a
+created by git-cvsimport. By default initial import will create and populate a
"master" branch from the CVS repository's main branch which you're free
to work with; after that, you need to 'git merge' incremental imports, or
-any CVS branches, yourself.
+any CVS branches, yourself. It is advisable to specify a named remote via
+-r to separate and protect the incoming branches.
+
OPTIONS
-------
@@ -37,7 +39,7 @@ OPTIONS
-d <CVSROOT>::
The root of the CVS archive. May be local (a simple path) or remote;
- currently, only the :local:, :ext: and :pserver: access methods
+ currently, only the :local:, :ext: and :pserver: access methods
are supported. If not given, git-cvsimport will try to read it
from `CVS/Root`. If no such file exists, it checks for the
`CVSROOT` environment variable.
@@ -51,10 +53,19 @@ OPTIONS
The git repository to import to. If the directory doesn't
exist, it will be created. Default is the current directory.
+-r <remote>::
+ The git remote to import this CVS repository into.
+ Moves all CVS branches into remotes/<remote>/<branch>
+ akin to the git-clone --use-separate-remote option.
+
-o <branch-for-HEAD>::
- The 'HEAD' branch from CVS is imported to the 'origin' branch within
- the git repository, as 'HEAD' already has a special meaning for git.
- Use this option if you want to import into a different branch.
+ When no remote is specified (via -r) the 'HEAD' branch
+ from CVS is imported to the 'origin' branch within the git
+ repository, as 'HEAD' already has a special meaning for git.
+ When a remote is specified the 'HEAD' branch is named
+ remotes/<remote>/master mirroring git-clone behaviour.
+ Use this option if you want to import into a different
+ branch.
+
Use '-o master' for continuing an import that was initially done by
the old cvs2git tool.
@@ -67,7 +78,7 @@ the old cvs2git tool.
-k::
Kill keywords: will extract files with '-kk' from the CVS archive
to avoid noisy changesets. Highly recommended, but off by default
- to preserve compatibility with early imported trees.
+ to preserve compatibility with early imported trees.
-u::
Convert underscores in tag and branch names to dots.
@@ -89,15 +100,15 @@ If you need to pass multiple options, separate them with a comma.
Instead of calling cvsps, read the provided cvsps output file. Useful
for debugging or when cvsps is being handled outside cvsimport.
--m::
+-m::
Attempt to detect merges based on the commit message. This option
- will enable default regexes that try to capture the name source
- branch name from the commit message.
+ will enable default regexes that try to capture the name source
+ branch name from the commit message.
-M <regex>::
Attempt to detect merges based on the commit message with a custom
regex. It can be used with '-m' to also see the default regexes.
- You must escape forward slashes.
+ You must escape forward slashes.
-S <regex>::
Skip paths matching the regex.
@@ -156,4 +167,3 @@ Documentation by Matthias Urlichs <smurf@smurf.noris.de>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt
index e5005f0..60d0bcf 100644
--- a/Documentation/git-cvsserver.txt
+++ b/Documentation/git-cvsserver.txt
@@ -7,10 +7,53 @@ git-cvsserver - A CVS server emulator for git
SYNOPSIS
--------
+
+SSH:
+
[verse]
export CVS_SERVER=git-cvsserver
'cvs' -d :ext:user@server/path/repo.git co <HEAD_name>
+pserver (/etc/inetd.conf):
+
+[verse]
+cvspserver stream tcp nowait nobody /usr/bin/git-cvsserver git-cvsserver pserver
+
+Usage:
+
+[verse]
+'git-cvsserver' [options] [pserver|server] [<directory> ...]
+
+OPTIONS
+-------
+
+All these options obviously only make sense if enforced by the server side.
+They have been implemented to resemble the gitlink:git-daemon[1] options as
+closely as possible.
+
+--base-path <path>::
+Prepend 'path' to requested CVSROOT
+
+--strict-paths::
+Don't allow recursing into subdirectories
+
+--export-all::
+Don't check for `gitcvs.enabled` in config. You also have to specify a list
+of allowed directories (see below) if you want to use this option.
+
+--version, -V::
+Print version information and exit
+
+--help, -h, -H::
+Print usage information and exit
+
+<directory>::
+You can specify a list of allowed directories. If no directories
+are given, all are allowed. This is an additional restriction, gitcvs
+access still needs to be enabled by the `gitcvs.enabled` config option
+unless '--export-all' was given, too.
+
+
DESCRIPTION
-----------
diff --git a/Documentation/git-daemon.txt b/Documentation/git-daemon.txt
index 9ddab71..f902161 100644
--- a/Documentation/git-daemon.txt
+++ b/Documentation/git-daemon.txt
@@ -54,6 +54,12 @@ OPTIONS
'git://example.com/hello.git', `git-daemon` will interpret the path
as '/srv/git/hello.git'.
+--base-path-relaxed::
+ If --base-path is enabled and repo lookup fails, with this option
+ `git-daemon` will attempt to lookup without prefixing the base path.
+ This is useful for switching to --base-path usage, while still
+ allowing the old paths.
+
--interpolated-path=pathtemplate::
To support virtual hosting, an interpolated path template can be
used to dynamically construct alternate paths. The template
@@ -235,4 +241,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-describe.txt b/Documentation/git-describe.txt
index 47a583d..ac23e28 100644
--- a/Documentation/git-describe.txt
+++ b/Documentation/git-describe.txt
@@ -8,7 +8,7 @@ git-describe - Show the most recent tag that is reachable from a commit
SYNOPSIS
--------
-'git-describe' [--all] [--tags] [--abbrev=<n>] <committish>...
+'git-describe' [--all] [--tags] [--contains] [--abbrev=<n>] <committish>...
DESCRIPTION
-----------
@@ -31,6 +31,11 @@ OPTIONS
Instead of using only the annotated tags, use any tag
found in `.git/refs/tags`.
+--contains::
+ Instead of finding the tag that predates the commit, find
+ the tag that comes after the commit, and thus contains it.
+ Automatically implies --tags.
+
--abbrev=<n>::
Instead of using the default 8 hexadecimal digits as the
abbreviated object name, use <n> digits.
@@ -119,4 +124,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-diff-files.txt b/Documentation/git-diff-files.txt
index 2e1e29e..d8a0a86 100644
--- a/Documentation/git-diff-files.txt
+++ b/Documentation/git-diff-files.txt
@@ -26,7 +26,7 @@ include::diff-options.txt[]
branch" respectively. With these options, diffs for
merged entries are not shown.
+
-The default is to diff against our branch (-2) and the
+The default is to diff against our branch (-2) and the
cleanly resolved paths. The option -0 can be given to
omit diff output for unmerged entries and just show "Unmerged".
@@ -58,4 +58,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-diff-index.txt b/Documentation/git-diff-index.txt
index 2df581c..7bd262c 100644
--- a/Documentation/git-diff-index.txt
+++ b/Documentation/git-diff-index.txt
@@ -75,7 +75,7 @@ actually doing a "git-write-tree" and comparing that. Except this one is much
nicer for the case where you just want to check where you are.
So doing a "git-diff-index --cached" is basically very useful when you are
-asking yourself "what have I already marked for being committed, and
+asking yourself "what have I already marked for being committed, and
what's the difference to a previous tree".
Non-cached Mode
@@ -130,4 +130,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-diff-tree.txt b/Documentation/git-diff-tree.txt
index 6e660e2..6b3f74e 100644
--- a/Documentation/git-diff-tree.txt
+++ b/Documentation/git-diff-tree.txt
@@ -166,4 +166,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-diff.txt b/Documentation/git-diff.txt
index 044cee9..b36e705 100644
--- a/Documentation/git-diff.txt
+++ b/Documentation/git-diff.txt
@@ -76,10 +76,10 @@ $ git diff --cached <2>
$ git diff HEAD <3>
------------
+
-<1> changes in the working tree not yet staged for the next commit.
-<2> changes between the index and your last commit; what you
+<1> Changes in the working tree not yet staged for the next commit.
+<2> Changes between the index and your last commit; what you
would be committing if you run "git commit" without "-a" option.
-<3> changes in the working tree since your last commit; what you
+<3> Changes in the working tree since your last commit; what you
would be committing if you run "git commit -a"
Comparing with arbitrary commits::
@@ -90,30 +90,27 @@ $ git diff HEAD -- ./test <2>
$ git diff HEAD^ HEAD <3>
------------
+
-<1> instead of using the tip of the current branch, compare with the
+<1> Instead of using the tip of the current branch, compare with the
tip of "test" branch.
-<2> instead of comparing with the tip of "test" branch, compare with
+<2> Instead of comparing with the tip of "test" branch, compare with
the tip of the current branch, but limit the comparison to the
file "test".
-<3> compare the version before the last commit and the last commit.
+<3> Compare the version before the last commit and the last commit.
Limiting the diff output::
+
------------
$ git diff --diff-filter=MRC <1>
-$ git diff --name-status -r <2>
+$ git diff --name-status <2>
$ git diff arch/i386 include/asm-i386 <3>
------------
+
-<1> show only modification, rename and copy, but not addition
+<1> Show only modification, rename and copy, but not addition
nor deletion.
-<2> show only names and the nature of change, but not actual
-diff output. --name-status disables usual patch generation
-which in turn also disables recursive behavior, so without -r
-you would only see the directory name if there is a change in a
-file in a subdirectory.
-<3> limit diff output to named subtrees.
+<2> Show only names and the nature of change, but not actual
+diff output.
+<3> Limit diff output to named subtrees.
Munging the diff output::
+
@@ -122,9 +119,9 @@ $ git diff --find-copies-harder -B -C <1>
$ git diff -R <2>
------------
+
-<1> spend extra cycles to find renames, copies and complete
+<1> Spend extra cycles to find renames, copies and complete
rewrites (very expensive).
-<2> output diff in reverse.
+<2> Output diff in reverse.
Author
@@ -138,4 +135,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt
index 87e70fe..30ee98d 100644
--- a/Documentation/git-fast-import.txt
+++ b/Documentation/git-fast-import.txt
@@ -302,7 +302,7 @@ change to the project.
data
('from' SP <committish> LF)?
('merge' SP <committish> LF)?
- (filemodify | filedelete | filedeleteall)*
+ (filemodify | filedelete | filecopy | filerename | filedeleteall)*
LF
....
@@ -325,11 +325,13 @@ commit message use a 0 length data. Commit messages are free-form
and are not interpreted by Git. Currently they must be encoded in
UTF-8, as fast-import does not permit other encodings to be specified.
-Zero or more `filemodify`, `filedelete` and `filedeleteall` commands
+Zero or more `filemodify`, `filedelete`, `filecopy`, `filerename`
+and `filedeleteall` commands
may be included to update the contents of the branch prior to
creating the commit. These commands may be supplied in any order.
However it is recommended that a `filedeleteall` command preceed
-all `filemodify` commands in the same commit, as `filedeleteall`
+all `filemodify`, `filecopy` and `filerename` commands in the same
+commit, as `filedeleteall`
wipes the branch clean (see below).
`author`
@@ -495,6 +497,56 @@ here `<path>` is the complete path of the file or subdirectory to
be removed from the branch.
See `filemodify` above for a detailed description of `<path>`.
+`filecopy`
+^^^^^^^^^^^^
+Recursively copies an existing file or subdirectory to a different
+location within the branch. The existing file or directory must
+exist. If the destination exists it will be completely replaced
+by the content copied from the source.
+
+....
+ 'C' SP <path> SP <path> LF
+....
+
+here the first `<path>` is the source location and the second
+`<path>` is the destination. See `filemodify` above for a detailed
+description of what `<path>` may look like. To use a source path
+that contains SP the path must be quoted.
+
+A `filecopy` command takes effect immediately. Once the source
+location has been copied to the destination any future commands
+applied to the source location will not impact the destination of
+the copy.
+
+`filerename`
+^^^^^^^^^^^^
+Renames an existing file or subdirectory to a different location
+within the branch. The existing file or directory must exist. If
+the destination exists it will be replaced by the source directory.
+
+....
+ 'R' SP <path> SP <path> LF
+....
+
+here the first `<path>` is the source location and the second
+`<path>` is the destination. See `filemodify` above for a detailed
+description of what `<path>` may look like. To use a source path
+that contains SP the path must be quoted.
+
+A `filerename` command takes effect immediately. Once the source
+location has been renamed to the destination any future commands
+applied to the source location will create new files there and not
+impact the destination of the rename.
+
+Note that a `filerename` is the same as a `filecopy` followed by a
+`filedelete` of the source location. There is a slight performance
+advantage to using `filerename`, but the advantage is so small
+that it is never worth trying to convert a delete/add pair in
+source material into a rename for fast-import. This `filerename`
+command is provided just to simplify frontends that already have
+rename information and don't want bother with decomposing it into a
+`filecopy` followed by a `filedelete`.
+
`filedeleteall`
^^^^^^^^^^^^^^^
Included in a `commit` command to remove all files (and also all
@@ -910,4 +962,3 @@ Documentation by Shawn O. Pearce <spearce@spearce.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-fetch.txt b/Documentation/git-fetch.txt
index 5fbeab7..9003473 100644
--- a/Documentation/git-fetch.txt
+++ b/Documentation/git-fetch.txt
@@ -35,7 +35,7 @@ include::fetch-options.txt[]
include::pull-fetch-param.txt[]
-include::urls.txt[]
+include::urls-remotes.txt[]
SEE ALSO
--------
diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt
new file mode 100644
index 0000000..915258f
--- /dev/null
+++ b/Documentation/git-filter-branch.txt
@@ -0,0 +1,278 @@
+git-filter-branch(1)
+====================
+
+NAME
+----
+git-filter-branch - Rewrite branches
+
+SYNOPSIS
+--------
+[verse]
+'git-filter-branch' [--env-filter <command>] [--tree-filter <command>]
+ [--index-filter <command>] [--parent-filter <command>]
+ [--msg-filter <command>] [--commit-filter <command>]
+ [--tag-name-filter <command>] [--subdirectory-filter <directory>]
+ [-d <directory>] [-f | --force] [<rev-list options>...]
+
+DESCRIPTION
+-----------
+Lets you rewrite git revision history by creating a new branch from
+your current branch, applying custom filters on each revision.
+Those filters can modify each tree (e.g. removing a file or running
+a perl rewrite on all files) or information about each commit.
+Otherwise, all information (including original commit times or merge
+information) will be preserved.
+
+The command takes the new branch name as a mandatory argument and
+the filters as optional arguments. If you specify no filters, the
+commits will be recommitted without any 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.
+
+*WARNING*! The rewritten history will have different object names for all
+the objects and will not converge with the original branch. You will not
+be able to easily push and distribute the rewritten branch on top of the
+original branch. Please do not use this command if you do not know the
+full implications, and avoid using it anyway, if a simple single commit
+would suffice to fix your problem.
+
+Always verify that the rewritten version is correct: The original refs,
+if different from the rewritten ones, will be stored in the namespace
+'refs/original/'.
+
+Note that since this operation is extensively I/O expensive, it might
+be a good idea to redirect the temporary directory off-disk, e.g. on
+tmpfs. Reportedly the speedup is very noticeable.
+
+
+Filters
+~~~~~~~
+
+The filters are applied in the order as listed below. The <command>
+argument is always evaluated in shell using the 'eval' command (with the
+notable exception of the commit filter, for technical reasons).
+Prior to that, the $GIT_COMMIT environment variable will be set to contain
+the id of the commit being rewritten. Also, GIT_AUTHOR_NAME,
+GIT_AUTHOR_EMAIL, GIT_AUTHOR_DATE, GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL,
+and GIT_COMMITTER_DATE are set according to the current commit.
+
+A 'map' function is available that takes an "original sha1 id" argument
+and outputs a "rewritten sha1 id" if the commit has been already
+rewritten, and "original sha1 id" otherwise; the 'map' function can
+return several ids on separate lines if your commit filter emitted
+multiple commits.
+
+
+OPTIONS
+-------
+
+--env-filter <command>::
+ This is the filter for modifying the environment in which
+ the commit will be performed. Specifically, you might want
+ to rewrite the author/committer name/email/time environment
+ variables (see gitlink:git-commit[1] for details). Do not forget
+ to re-export the variables.
+
+--tree-filter <command>::
+ This is the filter for rewriting the tree and its contents.
+ The argument is evaluated in shell with the working
+ directory set to the root of the checked out tree. The new tree
+ is then used as-is (new files are auto-added, disappeared files
+ are auto-removed - neither .gitignore files nor any other ignore
+ rules *HAVE ANY EFFECT*!).
+
+--index-filter <command>::
+ This is the filter for rewriting the index. It is similar to the
+ tree filter but does not check out the tree, which makes it much
+ faster. For hairy cases, see gitlink:git-update-index[1].
+
+--parent-filter <command>::
+ This is the filter for rewriting the commit's parent list.
+ It will receive the parent string on stdin and shall output
+ the new parent string on stdout. The parent string is in
+ a format accepted by gitlink:git-commit-tree[1]: empty for
+ the initial commit, "-p parent" for a normal commit and
+ "-p parent1 -p parent2 -p parent3 ..." for a merge commit.
+
+--msg-filter <command>::
+ This is the filter for rewriting the commit messages.
+ The argument is evaluated in the shell with the original
+ commit message on standard input; its standard output is
+ used as the new commit message.
+
+--commit-filter <command>::
+ This is the filter for performing the commit.
+ If this filter is specified, it will be called instead of the
+ gitlink:git-commit-tree[1] command, with arguments of the form
+ "<TREE_ID> [-p <PARENT_COMMIT_ID>]..." and the log message on
+ stdin. The commit id is expected on stdout.
++
+As a special extension, the commit filter may emit multiple
+commit ids; in that case, ancestors of the original commit will
+have all of them as parents.
+
+--tag-name-filter <command>::
+ This is the filter for rewriting tag names. When passed,
+ it will be called for every tag ref that points to a rewritten
+ object (or to a tag object which points to a rewritten object).
+ The original tag name is passed via standard input, and the new
+ tag name is expected on standard output.
++
+The original tags are not deleted, but can be overwritten;
+use "--tag-name-filter=cat" to simply update the tags. In this
+case, be very careful and make sure you have the old tags
+backed up in case the conversion has run afoul.
++
+Note that there is currently no support for proper rewriting of
+tag objects; in layman terms, if the tag has a message or signature
+attached, the rewritten tag won't have it. Sorry. (It is by
+definition impossible to preserve signatures at any rate.)
+
+--subdirectory-filter <directory>::
+ Only look at the history which touches the given subdirectory.
+ The result will contain that directory (and only that) as its
+ project root.
+
+-d <directory>::
+ Use this option to set the path to the temporary directory used for
+ rewriting. When applying a tree filter, the command needs to
+ temporary checkout the tree to some directory, which may consume
+ considerable space in case of large projects. By default it
+ does this in the '.git-rewrite/' directory but you can override
+ that choice by this parameter.
+
+-f\|--force::
+ `git filter-branch` refuses to start with an existing temporary
+ directory or when there are already refs starting with
+ 'refs/original/', unless forced.
+
+<rev-list-options>::
+ When options are given after the new branch name, they will
+ be passed to gitlink:git-rev-list[1]. Only commits in the resulting
+ output will be filtered, although the filtered commits can still
+ reference parents which are outside of that set.
+
+
+Examples
+--------
+
+Suppose you want to remove a file (containing confidential information
+or copyright violation) from all commits:
+
+-------------------------------------------------------
+git filter-branch --tree-filter 'rm filename' HEAD
+-------------------------------------------------------
+
+A significantly faster version:
+
+--------------------------------------------------------------------------
+git filter-branch --index-filter 'git update-index --remove filename' HEAD
+--------------------------------------------------------------------------
+
+Now, you will get the rewritten history saved in the branch 'newbranch'
+(your current branch is left untouched).
+
+To set a commit (which typically is at the tip of another
+history) to be the parent of the current initial commit, in
+order to paste the other history behind the current history:
+
+-------------------------------------------------------------------
+git filter-branch --parent-filter 'sed "s/^\$/-p <graft-id>/"' HEAD
+-------------------------------------------------------------------
+
+(if the parent string is empty - therefore we are dealing with the
+initial commit - add graftcommit as a parent). Note that this assumes
+history with a single root (that is, no merge without common ancestors
+happened). If this is not the case, use:
+
+--------------------------------------------------------------------------
+git filter-branch --parent-filter \
+ 'cat; test $GIT_COMMIT = <commit-id> && echo "-p <graft-id>"' HEAD
+--------------------------------------------------------------------------
+
+or even simpler:
+
+-----------------------------------------------
+echo "$commit-id $graft-id" >> .git/info/grafts
+git filter-branch $graft-id..HEAD
+-----------------------------------------------
+
+To remove commits authored by "Darl McBribe" from the history:
+
+------------------------------------------------------------------------------
+git filter-branch --commit-filter '
+ if [ "$GIT_AUTHOR_NAME" = "Darl McBribe" ];
+ then
+ shift;
+ while [ -n "$1" ];
+ do
+ shift;
+ echo "$1";
+ shift;
+ done;
+ else
+ git commit-tree "$@";
+ fi' HEAD
+------------------------------------------------------------------------------
+
+The shift magic first throws away the tree id and then the -p
+parameters. Note that this handles merges properly! In case Darl
+committed a merge between P1 and P2, it will be propagated properly
+and all children of the merge will become merge commits with P1,P2
+as their parents instead of the merge commit.
+
+To restrict rewriting to only part of the history, specify a revision
+range in addition to the new branch name. The new branch name will
+point to the top-most revision that a 'git rev-list' of this range
+will print.
+
+Note that the changes introduced by the commits, and not reverted by
+subsequent commits, will still be in the rewritten branch. If you want
+to throw out _changes_ together with the commits, you should use the
+interactive mode of gitlink:git-rebase[1].
+
+Consider this history:
+
+------------------
+ D--E--F--G--H
+ / /
+A--B-----C
+------------------
+
+To rewrite only commits D,E,F,G,H, but leave A, B and C alone, use:
+
+--------------------------------
+git filter-branch ... C..H
+--------------------------------
+
+To rewrite commits E,F,G,H, use one of these:
+
+----------------------------------------
+git filter-branch ... C..H --not D
+git filter-branch ... D..H --not C
+----------------------------------------
+
+To move the whole tree into a subdirectory, or remove it from there:
+
+---------------------------------------------------------------
+git filter-branch --index-filter \
+ 'git ls-files -s | sed "s-\t-&newsubdir/-" |
+ GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
+ git update-index --index-info &&
+ mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE' HEAD
+---------------------------------------------------------------
+
+
+Author
+------
+Written by Petr "Pasky" Baudis <pasky@suse.cz>,
+and the git list <git@vger.kernel.org>
+
+Documentation
+--------------
+Documentation by Petr Baudis and the git list.
+
+GIT
+---
+Part of the gitlink:git[7] suite
diff --git a/Documentation/git-fmt-merge-msg.txt b/Documentation/git-fmt-merge-msg.txt
index 4913c25..6affc5b 100644
--- a/Documentation/git-fmt-merge-msg.txt
+++ b/Documentation/git-fmt-merge-msg.txt
@@ -60,4 +60,3 @@ Documentation by Petr Baudis, Junio C Hamano and the git-list <git@vger.kernel.o
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt
index 0ca58a7..6cbcf93 100644
--- a/Documentation/git-format-patch.txt
+++ b/Documentation/git-format-patch.txt
@@ -11,7 +11,8 @@ SYNOPSIS
[verse]
'git-format-patch' [-n | -k] [-o <dir> | --stdout] [--thread]
[--attach[=<boundary>] | --inline[=<boundary>]]
- [-s | --signoff] [<common diff options>] [--start-number <n>]
+ [-s | --signoff] [<common diff options>]
+ [--start-number <n>] [--numbered-files]
[--in-reply-to=Message-Id] [--suffix=.<sfx>]
[--ignore-if-in-upstream]
[--subject-prefix=Subject-Prefix]
@@ -30,9 +31,11 @@ gitlink:git-rev-parse[1].
The output of this command is convenient for e-mail submission or
for use with gitlink:git-am[1].
-Each output file is numbered sequentially from 1, and uses the
+By default, each output file is numbered sequentially from 1, and uses the
first line of the commit message (massaged for pathname safety) as
-the filename. The names of the output files are printed to standard
+the filename. With the --numbered-files option, the output file names
+will only be numbers, without the first line of the commit appended.
+The names of the output files are printed to standard
output, unless the --stdout option is specified.
If -o is specified, output files are created in <dir>. Otherwise
@@ -63,6 +66,11 @@ include::diff-options.txt[]
--start-number <n>::
Start numbering the patches at <n> instead of 1.
+--numbered-files::
+ Output file names will be a simple number sequence
+ without the default first line of the commit appended.
+ Mutually exclusive with the --stdout option.
+
-k|--keep-subject::
Do not strip/add '[PATCH]' from the first line of the
commit log message.
@@ -121,12 +129,13 @@ not add any suffix.
CONFIGURATION
-------------
You can specify extra mail header lines to be added to each
-message in the repository configuration. Also you can specify
-the default suffix different from the built-in one:
+message in the repository configuration. You can also specify
+new defaults for the subject prefix and file suffix.
------------
[format]
headers = "Organization: git-foo\n"
+ subjectprefix = CHANGE
suffix = .txt
------------
@@ -173,4 +182,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-fsck.txt b/Documentation/git-fsck.txt
index 8c68cf0..45c0bee 100644
--- a/Documentation/git-fsck.txt
+++ b/Documentation/git-fsck.txt
@@ -10,7 +10,7 @@ SYNOPSIS
--------
[verse]
'git-fsck' [--tags] [--root] [--unreachable] [--cache] [--no-reflogs]
- [--full] [--strict] [<object>*]
+ [--full] [--strict] [--verbose] [--lost-found] [<object>*]
DESCRIPTION
-----------
@@ -61,6 +61,15 @@ index file and all SHA1 references in .git/refs/* as heads.
objects that triggers this check, but it is recommended
to check new projects with this flag.
+--verbose::
+ Be chatty.
+
+--lost-found::
+ Write dangling objects into .git/lost-found/commit/ or
+ .git/lost-found/other/, depending on type. If the object is
+ a blob, the contents are written into the file, rather than
+ its object name.
+
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
@@ -142,4 +151,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-gc.txt b/Documentation/git-gc.txt
index bc16584..c7742ca 100644
--- a/Documentation/git-gc.txt
+++ b/Documentation/git-gc.txt
@@ -8,7 +8,7 @@ git-gc - Cleanup unnecessary files and optimize the local repository
SYNOPSIS
--------
-'git-gc' [--prune]
+'git-gc' [--prune] [--aggressive]
DESCRIPTION
-----------
@@ -35,6 +35,13 @@ OPTIONS
repository at the same time (e.g. never use this option
in a cron script).
+--aggressive::
+ Usually 'git-gc' runs very quickly while providing good disk
+ space utilization and performance. This option will cause
+ git-gc to more aggressively optimize the repository at the expense
+ of taking much more time. The effects of this optimization are
+ persistent, so this option only needs to be used occasionally; every
+ few hundred changesets or so.
Configuration
-------------
@@ -67,6 +74,13 @@ The optional configuration variable 'gc.packrefs' determines if
is not run in bare repositories by default, to allow older dumb-transport
clients fetch from the repository, but this will change in the future.
+The optional configuration variable 'gc.aggressiveWindow' controls how
+much time is spent optimizing the delta compression of the objects in
+the repository when the --aggressive option is specified. The larger
+the value, the more time is spent optimizing the delta compression. See
+the documentation for the --window' option in gitlink:git-repack[1] for
+more details. This defaults to 10.
+
See Also
--------
gitlink:git-prune[1]
diff --git a/Documentation/git-get-tar-commit-id.txt b/Documentation/git-get-tar-commit-id.txt
index 48805b6..9b5f86f 100644
--- a/Documentation/git-get-tar-commit-id.txt
+++ b/Documentation/git-get-tar-commit-id.txt
@@ -34,4 +34,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt
index c5a5dad..97faaa1 100644
--- a/Documentation/git-grep.txt
+++ b/Documentation/git-grep.txt
@@ -144,4 +144,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-gui.txt b/Documentation/git-gui.txt
new file mode 100644
index 0000000..bd613b2
--- /dev/null
+++ b/Documentation/git-gui.txt
@@ -0,0 +1,115 @@
+git-gui(1)
+==========
+
+NAME
+----
+git-gui - A portable graphical interface to Git
+
+SYNOPSIS
+--------
+'git gui' [<command>] [arguments]
+
+DESCRIPTION
+-----------
+A Tcl/Tk based graphical user interface to Git. git-gui focuses
+on allowing users to make changes to their repository by making
+new commits, amending existing ones, creating branches, performing
+local merges, and fetching/pushing to remote repositories.
+
+Unlike gitlink:gitk[1], git-gui focuses on commit generation
+and single file annotation, and does not show project history.
+It does however supply menu actions to start a gitk session from
+within git-gui.
+
+git-gui is known to work on all popular UNIX systems, Mac OS X,
+and Windows (under both Cygwin and MSYS). To the extent possible
+OS specific user interface guidelines are followed, making git-gui
+a fairly native interface for users.
+
+COMMANDS
+--------
+blame::
+ Start a blame viewer on the specified file on the given
+ version (or working directory if not specified).
+
+browser::
+ Start a tree browser showing all files in the specified
+ commit (or 'HEAD' by default). Files selected through the
+ browser are opened in the blame viewer.
+
+citool::
+ Start git-gui and arrange to make exactly one commit before
+ exiting and returning to the shell. The interface is limited
+ to only commit actions, slightly reducing the application's
+ startup time and simplifying the menubar.
+
+version::
+ Display the currently running version of git-gui.
+
+
+Examples
+--------
+git gui blame Makefile::
+
+ Show the contents of the file 'Makefile' in the current
+ working directory, and provide annotations for both the
+ original author of each line, and who moved the line to its
+ current location. The uncommitted file is annotated, and
+ uncommitted changes (if any) are explicitly attributed to
+ 'Not Yet Committed'.
+
+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 citool::
+
+ Make one commit and return to the shell when it is complete.
+
+git citool::
+
+ Same as 'git gui citool' (above).
+
+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
+ blame viewer.
+
+See Also
+--------
+'gitk(1)'::
+ The git repository browser. Shows branches, commit history
+ and file differences. gitk is the utility started by
+ git-gui's Repository Visualize actions.
+
+Other
+-----
+git-gui is actually maintained as an independent project, but stable
+versions are distributed as part of the Git suite for the convience
+of end users.
+
+A git-gui development repository can be obtained from:
+
+ git clone git://repo.or.cz/git-gui.git
+
+or
+
+ git clone http://repo.or.cz/r/git-gui.git
+
+or browsed online at http://repo.or.cz/w/git-gui.git/[].
+
+Author
+------
+Written by Shawn O. Pearce <spearce@spearce.org>.
+
+Documentation
+--------------
+Documentation by Shawn O. Pearce <spearce@spearce.org>.
+
+GIT
+---
+Part of the gitlink:git[7] suite
diff --git a/Documentation/git-hash-object.txt b/Documentation/git-hash-object.txt
index 5edc36f..616f196 100644
--- a/Documentation/git-hash-object.txt
+++ b/Documentation/git-hash-object.txt
@@ -18,7 +18,7 @@ work tree), and optionally writes the resulting object into the
object database. Reports its object ID to its standard output.
This is used by "git-cvsimport" to update the index
without modifying files in the work tree. When <type> is not
-specified, it defaults to "blob".
+specified, it defaults to "blob".
OPTIONS
-------
@@ -43,4 +43,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-http-fetch.txt b/Documentation/git-http-fetch.txt
index 4deabc3..45e4845 100644
--- a/Documentation/git-http-fetch.txt
+++ b/Documentation/git-http-fetch.txt
@@ -54,4 +54,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-http-push.txt b/Documentation/git-http-push.txt
index a15cf5b..9afb860 100644
--- a/Documentation/git-http-push.txt
+++ b/Documentation/git-http-push.txt
@@ -52,7 +52,7 @@ Specifying the Refs
A '<ref>' specification can be either a single pattern, or a pair
of such patterns separated by a colon ":" (this means that a ref name
-cannot have a colon in it). A single pattern '<name>' is just a
+cannot have a colon in it). A single pattern '<name>' is just a
shorthand for '<name>:<name>'.
Each pattern pair consists of the source side (before the colon)
diff --git a/Documentation/git-index-pack.txt b/Documentation/git-index-pack.txt
index 2269269..a8a7f6f 100644
--- a/Documentation/git-index-pack.txt
+++ b/Documentation/git-index-pack.txt
@@ -98,4 +98,3 @@ Documentation by Sergey Vlasov
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-init-db.txt b/Documentation/git-init-db.txt
index 5412135..d4e01cb 100644
--- a/Documentation/git-init-db.txt
+++ b/Documentation/git-init-db.txt
@@ -8,7 +8,7 @@ git-init-db - Creates an empty git repository
SYNOPSIS
--------
-'git-init-db' [--template=<template_directory>] [--shared[=<permissions>]]
+'git-init-db' [-q | --quiet] [--template=<template_directory>] [--shared[=<permissions>]]
DESCRIPTION
@@ -16,4 +16,3 @@ DESCRIPTION
This is a synonym for gitlink:git-init[1]. Please refer to the
documentation of that command.
-
diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
index 1b64d3a..07484a4 100644
--- a/Documentation/git-init.txt
+++ b/Documentation/git-init.txt
@@ -8,7 +8,7 @@ git-init - Create an empty git repository or reinitialize an existing one
SYNOPSIS
--------
-'git-init' [--template=<template_directory>] [--shared[=<permissions>]]
+'git-init' [-q | --quiet] [--template=<template_directory>] [--shared[=<permissions>]]
OPTIONS
@@ -16,6 +16,10 @@ OPTIONS
--
+-q, \--quiet::
+
+Only print error and warning messages, all other output will be suppressed.
+
--template=<template_directory>::
Provide the directory from which templates will be used. The default template
@@ -108,4 +112,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-instaweb.txt b/Documentation/git-instaweb.txt
index 9df0ab2..cec60ee 100644
--- a/Documentation/git-instaweb.txt
+++ b/Documentation/git-instaweb.txt
@@ -82,4 +82,3 @@ Documentation by Eric Wong <normalperson@yhbt.net>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-local-fetch.txt b/Documentation/git-local-fetch.txt
index 51389ef..141b767 100644
--- a/Documentation/git-local-fetch.txt
+++ b/Documentation/git-local-fetch.txt
@@ -14,6 +14,8 @@ SYNOPSIS
DESCRIPTION
-----------
+THIS COMMAND IS DEPRECATED.
+
Duplicates another git repository on a local system.
OPTIONS
@@ -62,4 +64,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt
index 0f353f6..63c1dbe 100644
--- a/Documentation/git-log.txt
+++ b/Documentation/git-log.txt
@@ -52,7 +52,17 @@ include::pretty-options.txt[]
See also gitlink:git-reflog[1].
--decorate::
- Print out the ref names of any commits that are shown.
+ Print out the ref names of any commits that are shown.
+
+--full-diff::
+ Without this flag, "git log -p <paths>..." shows commits that
+ touch the specified paths, and diffs about the same specified
+ paths. With this, the full diff is shown for commits that touch
+ the specified paths; this means that "<paths>..." limits only
+ commits, and doesn't limit diff for those commits.
+
+--follow::
+ Continue listing the history of a file beyond renames.
<paths>...::
Show only commits that affect the specified paths.
@@ -84,6 +94,12 @@ git log -r --name-status release..test::
in the "release" branch, along with the list of paths
each commit modifies.
+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.
+
Discussion
----------
@@ -101,4 +117,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt
index a78a9ff..9975945 100644
--- a/Documentation/git-ls-files.txt
+++ b/Documentation/git-ls-files.txt
@@ -180,4 +180,3 @@ Documentation by David Greaves, Junio C Hamano, Josh Triplett, and the git-list
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-ls-remote.txt b/Documentation/git-ls-remote.txt
index c254005..93e9a60 100644
--- a/Documentation/git-ls-remote.txt
+++ b/Documentation/git-ls-remote.txt
@@ -70,4 +70,3 @@ Written by Junio C Hamano <junkio@cox.net>
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-ls-tree.txt b/Documentation/git-ls-tree.txt
index 7899394..7b78599 100644
--- a/Documentation/git-ls-tree.txt
+++ b/Documentation/git-ls-tree.txt
@@ -9,7 +9,7 @@ git-ls-tree - List the contents of a tree object
SYNOPSIS
--------
[verse]
-'git-ls-tree' [-d] [-r] [-t] [-z]
+'git-ls-tree' [-d] [-r] [-t] [-l] [-z]
[--name-only] [--name-status] [--full-name] [--abbrev=[<n>]]
<tree-ish> [paths...]
@@ -36,6 +36,10 @@ OPTIONS
Show tree entries even when going to recurse them. Has no effect
if '-r' was not passed. '-d' implies '-t'.
+-l::
+--long::
+ Show object size of blob (file) entries.
+
-z::
\0 line termination on output.
@@ -65,6 +69,14 @@ Output Format
When the `-z` option is not used, TAB, LF, and backslash characters
in pathnames are represented as `\t`, `\n`, and `\\`, respectively.
+When the `-l` option is used, format changes to
+
+ <mode> SP <type> SP <object> SP <object size> TAB <file>
+
+Object size identified by <object> is given in bytes, and right-justified
+with minimum width of 7 characters. Object size is given only for blobs
+(file) entries; for other entries `-` character is used in place of size.
+
Author
------
@@ -80,4 +92,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-mailinfo.txt b/Documentation/git-mailinfo.txt
index 8eadceb..64aa6a1 100644
--- a/Documentation/git-mailinfo.txt
+++ b/Documentation/git-mailinfo.txt
@@ -16,7 +16,7 @@ DESCRIPTION
Reading a single e-mail message from the standard input, and
writes the commit log message in <msg> file, and the patches in
<patch> file. The author name, e-mail and e-mail subject are
-written out to the standard output to be used by git-applypatch
+written out to the standard output to be used by git-am
to create a commit. It is usually not necessary to use this
command directly. See gitlink:git-am[1] instead.
@@ -67,4 +67,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-mailsplit.txt b/Documentation/git-mailsplit.txt
index c11d6a5..c4f4cab 100644
--- a/Documentation/git-mailsplit.txt
+++ b/Documentation/git-mailsplit.txt
@@ -7,12 +7,15 @@ git-mailsplit - Simple UNIX mbox splitter program
SYNOPSIS
--------
-'git-mailsplit' [-b] [-f<nn>] [-d<prec>] -o<directory> [--] [<mbox>...]
+'git-mailsplit' [-b] [-f<nn>] [-d<prec>] -o<directory> [--] [<mbox>|<Maildir>...]
DESCRIPTION
-----------
-Splits a mbox file into a list of files: "0001" "0002" .. in the specified
-directory so you can process them further from there.
+Splits a mbox file or a Maildir into a list of files: "0001" "0002" .. in the
+specified directory so you can process them further from there.
+
+IMPORTANT: Maildir splitting relies upon filenames being sorted to output
+patches in the correct order.
OPTIONS
-------
@@ -20,6 +23,10 @@ OPTIONS
Mbox file to split. If not given, the mbox is read from
the standard input.
+<Maildir>::
+ Root of the Maildir to split. This directory should contain the cur, tmp
+ and new subdirectories.
+
<directory>::
Directory in which to place the individual messages.
@@ -49,4 +56,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-merge-base.txt b/Documentation/git-merge-base.txt
index 3190aed..6b71880 100644
--- a/Documentation/git-merge-base.txt
+++ b/Documentation/git-merge-base.txt
@@ -40,4 +40,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-merge-index.txt b/Documentation/git-merge-index.txt
index b8ee1ff..17e9f10 100644
--- a/Documentation/git-merge-index.txt
+++ b/Documentation/git-merge-index.txt
@@ -59,7 +59,7 @@ Examples:
This is modified MM in the branch B. # merge2
This is modified MM in the branch B. # current contents
-or
+or
torvalds@ppc970:~/merge-test> git-merge-index cat AA MM
cat: : No such file or directory
@@ -85,4 +85,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-merge-one-file.txt b/Documentation/git-merge-one-file.txt
index f80ab3b..f35d0e1 100644
--- a/Documentation/git-merge-one-file.txt
+++ b/Documentation/git-merge-one-file.txt
@@ -27,4 +27,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-merge-tree.txt b/Documentation/git-merge-tree.txt
index 35fb4fb..6892fda 100644
--- a/Documentation/git-merge-tree.txt
+++ b/Documentation/git-merge-tree.txt
@@ -34,4 +34,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt
index 9c08efa..144bc16 100644
--- a/Documentation/git-merge.txt
+++ b/Documentation/git-merge.txt
@@ -9,7 +9,7 @@ git-merge - Join two or more development histories together
SYNOPSIS
--------
[verse]
-'git-merge' [-n] [--no-commit] [--squash] [-s <strategy>]...
+'git-merge' [-n] [--summary] [--no-commit] [--squash] [-s <strategy>]...
[-m <msg>] <remote> <remote>...
DESCRIPTION
@@ -43,6 +43,21 @@ If you tried a merge which resulted in a complex conflicts and
would want to start over, you can recover with
gitlink:git-reset[1].
+CONFIGURATION
+-------------
+
+merge.summary::
+ Whether to include summaries of merged commits in newly
+ created merge commit. False by default.
+
+merge.verbosity::
+ Controls the amount of output shown by the recursive merge
+ strategy. Level 0 outputs nothing except a final error
+ message if conflicts were detected. Level 1 outputs only
+ conflicts, 2 outputs conflicts and file changes. Level 5 and
+ above outputs debugging information. The default is level 2.
+ Can be overriden by 'GIT_MERGE_VERBOSITY' environment variable.
+
HOW MERGE WORKS
---------------
@@ -92,11 +107,11 @@ pull after you are done and ready.
When things cleanly merge, these things happen:
-1. the results are updated both in the index file and in your
- working tree,
-2. index file is written out as a tree,
-3. the tree gets committed, and
-4. the `HEAD` pointer gets advanced.
+1. The results are updated both in the index file and in your
+ working tree;
+2. Index file is written out as a tree;
+3. The tree gets committed; and
+4. The `HEAD` pointer gets advanced.
Because of 2., we require that the original state of the index
file to match exactly the current `HEAD` commit; otherwise we
diff --git a/Documentation/git-mergetool.txt b/Documentation/git-mergetool.txt
index add01e8..6c32c6d 100644
--- a/Documentation/git-mergetool.txt
+++ b/Documentation/git-mergetool.txt
@@ -25,7 +25,7 @@ OPTIONS
-t or --tool=<tool>::
Use the merge resolution program specified by <tool>.
Valid merge tools are:
- kdiff3, tkdiff, meld, xxdiff, emerge, vimdiff, and opendiff
+ kdiff3, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff, and opendiff
+
If a merge resolution program is not specified, 'git mergetool'
will use the configuration variable merge.tool. If the
@@ -43,4 +43,3 @@ Documentation by Theodore Y Ts'o.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
index 2860a3d..ea7a752 100644
--- a/Documentation/git-mktag.txt
+++ b/Documentation/git-mktag.txt
@@ -19,18 +19,18 @@ The output is the new tag's <object> identifier.
Tag Format
----------
-A tag signature file has a very simple fixed format: three lines of
+A tag signature file has a very simple fixed format: four lines of
object <sha1>
type <typename>
tag <tagname>
+ tagger <tagger>
-followed by some 'optional' free-form signature that git itself
-doesn't care about, but that can be verified with gpg or similar.
-
-The size of the full object is artificially limited to 8kB. (Just
-because I'm a lazy bastard, and if you can't fit a signature in that
-size, you're doing something wrong)
+followed by some 'optional' free-form message (some tags created
+by older git may not have `tagger` line). The message, when
+exists, is separated by a blank line from the header. The
+message part may contain a signature that git itself doesn't
+care about, but that can be verified with gpg.
Author
@@ -44,4 +44,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-mktree.txt b/Documentation/git-mktree.txt
index 5f9ee60..638abc7 100644
--- a/Documentation/git-mktree.txt
+++ b/Documentation/git-mktree.txt
@@ -32,4 +32,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-mv.txt b/Documentation/git-mv.txt
index 6756b76..2c9cf74 100644
--- a/Documentation/git-mv.txt
+++ b/Documentation/git-mv.txt
@@ -51,4 +51,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-name-rev.txt b/Documentation/git-name-rev.txt
index d6c8bf8..91eede1 100644
--- a/Documentation/git-name-rev.txt
+++ b/Documentation/git-name-rev.txt
@@ -34,6 +34,13 @@ OPTIONS
Read from stdin, append "(<rev_name>)" to all sha1's of nameable
commits, and pass to stdout
+--name-only::
+ Instead of printing both the SHA-1 and the name, print only
+ the name. If given with --tags the usual tag prefix of
+ "tags/" is also ommitted from the name, matching the output
+ of gitlink::git-describe[1] more closely. This option
+ cannot be combined with --stdin.
+
EXAMPLE
-------
@@ -69,4 +76,3 @@ Documentation by Johannes Schindelin.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-pack-objects.txt b/Documentation/git-pack-objects.txt
index bd3ee45..6f17cff 100644
--- a/Documentation/git-pack-objects.txt
+++ b/Documentation/git-pack-objects.txt
@@ -85,6 +85,22 @@ base-name::
times to get to the necessary object.
The default value for --window is 10 and --depth is 50.
+--window-memory=[N]::
+ This option provides an additional limit on top of `--window`;
+ the window size will dynamically scale down so as to not take
+ up more than N bytes in memory. This is useful in
+ repositories with a mix of large and small objects to not run
+ out of memory with a large window, but still be able to take
+ advantage of the large window for the smaller objects. The
+ size can be suffixed with "k", "m", or "g".
+ `--window-memory=0` makes memory usage unlimited, which is the
+ default.
+
+--max-pack-size=<n>::
+ Maximum size of each output packfile, expressed in MiB.
+ If specified, multiple packfiles may be created.
+ The default is unlimited.
+
--incremental::
This flag causes an object already in a pack ignored
even if it appears in the standard input.
@@ -127,6 +143,25 @@ base-name::
This flag tells the command not to reuse existing deltas
but compute them from scratch.
+--no-reuse-object::
+ This flag tells the command not to reuse existing object data at all,
+ including non deltified object, forcing recompression of everything.
+ This implies --no-reuse-delta. Useful only in the obscure case where
+ wholesale enforcement of a different compression level on the
+ packed data is desired.
+
+--compression=[N]::
+ Specifies compression level for newly-compressed data in the
+ generated pack. If not specified, pack compression level is
+ determined first by pack.compression, then by core.compression,
+ and defaults to -1, the zlib default, if neither is set.
+ Data copied from loose objects will be recompressed
+ if core.legacyheaders was true when they were created or if
+ the loose compression level (see core.loosecompression and
+ core.compression) is now a different value than the pack
+ compression level. Add --no-reuse-object if you want to force
+ a uniform compression level on all data no matter the source.
+
--delta-base-offset::
A packed archive can express base object of a delta as
either 20-byte object name or as an offset in the
@@ -161,4 +196,3 @@ gitlink:git-prune-packed[1]
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-pack-redundant.txt b/Documentation/git-pack-redundant.txt
index 94bbea0..f2ceeba 100644
--- a/Documentation/git-pack-redundant.txt
+++ b/Documentation/git-pack-redundant.txt
@@ -17,7 +17,7 @@ are redundant. The output is suitable for piping to
'xargs rm' if you are in the root of the repository.
git-pack-redundant accepts a list of objects on standard input. Any objects
-given will be ignored when checking which packs are required. This makes the
+given will be ignored when checking which packs are required. This makes the
following command useful when wanting to remove packs which contain unreachable
objects.
@@ -55,4 +55,3 @@ gitlink:git-prune-packed[1]
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-patch-id.txt b/Documentation/git-patch-id.txt
index a7e9fd0..ad528a9 100644
--- a/Documentation/git-patch-id.txt
+++ b/Documentation/git-patch-id.txt
@@ -40,4 +40,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-peek-remote.txt b/Documentation/git-peek-remote.txt
index 74f37bd..abc1712 100644
--- a/Documentation/git-peek-remote.txt
+++ b/Documentation/git-peek-remote.txt
@@ -52,4 +52,3 @@ Documentation by Junio C Hamano.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-prune-packed.txt b/Documentation/git-prune-packed.txt
index 310033e..3800edb 100644
--- a/Documentation/git-prune-packed.txt
+++ b/Documentation/git-prune-packed.txt
@@ -50,4 +50,3 @@ gitlink:git-repack[1]
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-prune.txt b/Documentation/git-prune.txt
index b8166a2..0ace233 100644
--- a/Documentation/git-prune.txt
+++ b/Documentation/git-prune.txt
@@ -58,4 +58,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt
index 94478ed..e1eb2c1 100644
--- a/Documentation/git-pull.txt
+++ b/Documentation/git-pull.txt
@@ -29,7 +29,7 @@ include::fetch-options.txt[]
include::pull-fetch-param.txt[]
-include::urls.txt[]
+include::urls-remotes.txt[]
include::merge-strategies.txt[]
@@ -165,4 +165,3 @@ Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index e9ad106..0dd9caf 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -53,9 +53,8 @@ side are updated.
+
`tag <tag>` means the same as `refs/tags/<tag>:refs/tags/<tag>`.
+
-A parameter <ref> without a colon is equivalent to
-<ref>`:`<ref>, hence updates <ref> in the destination from <ref>
-in the source.
+A parameter <ref> without a colon pushes the <ref> from the source
+repository to the destination repository under the same name.
+
Pushing an empty <src> allows you to delete the <dst> ref from
the remote repository.
@@ -80,7 +79,7 @@ the remote repository.
-f, \--force::
Usually, the command refuses to update a remote ref that is
- not a descendant of the local ref used to overwrite it.
+ not an ancestor of the local ref used to overwrite it.
This flag disables the check. This can cause the
remote repository to lose commits; use it with care.
@@ -96,7 +95,27 @@ the remote repository.
-v::
Run verbosely.
-include::urls.txt[]
+include::urls-remotes.txt[]
+
+
+Examples
+--------
+
+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.
+
+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 master:satellite/master::
+ Find a ref that matches `master` in the source repository
+ (most likely, it would find `refs/heads/master`), and update
+ the ref that matches `satellite/master` (most likely, it would
+ be `refs/remotes/satellite/master`) in `origin` repository with it.
Author
------
@@ -110,4 +129,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-quiltimport.txt b/Documentation/git-quiltimport.txt
index 296937a..1c3ef4c 100644
--- a/Documentation/git-quiltimport.txt
+++ b/Documentation/git-quiltimport.txt
@@ -58,4 +58,3 @@ Documentation by Eric Biederman <ebiederm@lnxi.com>
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-read-tree.txt b/Documentation/git-read-tree.txt
index acb5744..74c5478 100644
--- a/Documentation/git-read-tree.txt
+++ b/Documentation/git-read-tree.txt
@@ -8,7 +8,7 @@ git-read-tree - Reads tree information into the index
SYNOPSIS
--------
-'git-read-tree' (<tree-ish> | [[-m [--aggressive] | --reset | --prefix=<prefix>] [-u | -i]] [--exclude-per-directory=<gitignore>] [--index-output=<file>] <tree-ish1> [<tree-ish2> [<tree-ish3>]])
+'git-read-tree' (<tree-ish> | [[-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>] [-u | -i]] [--exclude-per-directory=<gitignore>] [--index-output=<file>] <tree-ish1> [<tree-ish2> [<tree-ish3>]])
DESCRIPTION
@@ -50,6 +50,12 @@ OPTIONS
trees that are not directly related to the current
working tree status into a temporary index file.
+--trivial::
+ Restrict three-way merge by `git-read-tree` to happen
+ only if there is no file-level merging required, instead
+ of resolving merge for trivial cases and leaving
+ conflicting files unresolved in the index.
+
--aggressive::
Usually a three-way merge by `git-read-tree` resolves
the merge for really trivial cases and leaves other
@@ -356,4 +362,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 753b275..96907d4 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -8,7 +8,8 @@ git-rebase - Forward-port local commits to the updated upstream head
SYNOPSIS
--------
[verse]
-'git-rebase' [-v] [--merge] [-C<n>] [--onto <newbase>] <upstream> [<branch>]
+'git-rebase' [-i | --interactive] [-v | --verbose] [--merge] [-C<n>]
+ [-p | --preserve-merges] [--onto <newbase>] <upstream> [<branch>]
'git-rebase' --continue | --skip | --abort
DESCRIPTION
@@ -208,6 +209,14 @@ OPTIONS
context exist they all must match. By default no context is
ever ignored.
+-i, \--interactive::
+ Make a list of the commits which are about to be rebased. Let the
+ user edit that list before rebasing.
+
+-p, \--preserve-merges::
+ Instead of ignoring merges, try to recreate them. This option
+ only works in interactive mode.
+
include::merge-strategies.txt[]
NOTES
@@ -226,9 +235,100 @@ pre-rebase hook script for an example.
You must be in the top directory of your project to start (or continue)
a rebase. Upon completion, <branch> will be the current branch.
-Author
+INTERACTIVE MODE
+----------------
+
+Rebasing interactively means that you have a chance to edit the commits
+which are rebased. You can reorder the commits, and you can
+remove them (weeding out bad or otherwise unwanted patches).
+
+The interactive mode is meant for this type of workflow:
+
+1. have a wonderful idea
+2. hack on the code
+3. prepare a series for submission
+4. submit
+
+where point 2. consists of several instances of
+
+a. regular use
+ 1. finish something worthy of a commit
+ 2. commit
+b. independent fixup
+ 1. realize that something does not work
+ 2. fix that
+ 3. commit it
+
+Sometimes the thing fixed in b.2. cannot be amended to the not-quite
+perfect commit it fixes, because that commit is buried deeply in a
+patch series. That is exactly what interactive rebase is for: use it
+after plenty of "a"s and "b"s, by rearranging and editing
+commits, and squashing multiple commits into one.
+
+Start it with the last commit you want to retain as-is:
+
+ git rebase -i <after-this-commit>
+
+An editor will be fired up with all the commits in your current branch
+(ignoring merge commits), which come after the given commit. You can
+reorder the commits in this list to your heart's content, and you can
+remove them. The list looks more or less like this:
+
+-------------------------------------------
+pick deadbee The oneline of this commit
+pick fa1afe1 The oneline of the next commit
+...
+-------------------------------------------
+
+The oneline descriptions are purely for your pleasure; `git-rebase` will
+not look at them but at the commit names ("deadbee" and "fa1afe1" in this
+example), so do not delete or edit the names.
+
+By replacing the command "pick" with the command "edit", you can tell
+`git-rebase` to stop after applying that commit, so that you can edit
+the files and/or the commit message, amend the commit, and continue
+rebasing.
+
+If you want to fold two or more commits into one, replace the command
+"pick" with "squash" for the second and subsequent commit. If the
+commits had different authors, it will attribute the squashed commit to
+the author of the last commit.
+
+In both cases, or when a "pick" does not succeed (because of merge
+errors), the loop will stop to let you fix things, and you can continue
+the loop with `git rebase --continue`.
+
+For example, if you want to reorder the last 5 commits, such that what
+was HEAD~4 becomes the new HEAD. To achieve that, you would call
+`git-rebase` like this:
+
+----------------------
+$ git rebase -i HEAD~5
+----------------------
+
+And move the first patch to the end of the list.
+
+You might want to preserve merges, if you have a history like this:
+
+------------------
+ X
+ \
+ A---M---B
+ /
+---o---O---P---Q
+------------------
+
+Suppose you want to rebase the side branch starting at "A" to "Q". Make
+sure that the current HEAD is "B", and call
+
+-----------------------------
+$ git rebase -i -p --onto Q O
+-----------------------------
+
+Authors
------
-Written by Junio C Hamano <junkio@cox.net>
+Written by Junio C Hamano <junkio@cox.net> and
+Johannes E. Schindelin <johannes.schindelin@gmx.de>
Documentation
--------------
@@ -237,4 +337,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-receive-pack.txt b/Documentation/git-receive-pack.txt
index 6914aa5..4ef1840 100644
--- a/Documentation/git-receive-pack.txt
+++ b/Documentation/git-receive-pack.txt
@@ -48,8 +48,8 @@ standard input of the hook will be one line per ref to be updated:
The refname value is relative to $GIT_DIR; e.g. for the master
head this is "refs/heads/master". The two sha1 values before
each refname are the object names for the refname before and after
-the update. Refs to be created will have sha1-old equal to 0{40},
-while refs to be deleted will have sha1-new equal to 0{40}, otherwise
+the update. Refs to be created will have sha1-old equal to 0\{40},
+while refs to be deleted will have sha1-new equal to 0\{40}, otherwise
sha1-old and sha1-new should be valid objects in the repository.
This hook is called before any refname is updated and before any
@@ -71,7 +71,7 @@ The refname parameter is relative to $GIT_DIR; e.g. for the master
head this is "refs/heads/master". The two sha1 arguments are
the object names for the refname before and after the update.
Note that the hook is called before the refname is updated,
-so either sha1-old is 0{40} (meaning there is no such ref yet),
+so either sha1-old is 0\{40} (meaning there is no such ref yet),
or it should match what is recorded in refname.
The hook should exit with non-zero status if it wants to disallow
@@ -96,8 +96,8 @@ The refname value is relative to $GIT_DIR; e.g. for the master
head this is "refs/heads/master". The two sha1 values before
each refname are the object names for the refname before and after
the update. Refs that were created will have sha1-old equal to
-0{40}, while refs that were deleted will have sha1-new equal to
-0{40}, otherwise sha1-old and sha1-new should be valid objects in
+0\{40}, while refs that were deleted will have sha1-new equal to
+0\{40}, otherwise sha1-old and sha1-new should be valid objects in
the repository.
Using this hook, it is easy to generate mails describing the updates
diff --git a/Documentation/git-reflog.txt b/Documentation/git-reflog.txt
index 1e343bc..89bc9c5 100644
--- a/Documentation/git-reflog.txt
+++ b/Documentation/git-reflog.txt
@@ -39,6 +39,19 @@ the current branch. It is basically an alias for 'git log -g --abbrev-commit
OPTIONS
-------
+--stale-fix::
+ This revamps the logic -- the definition of "broken commit"
+ becomes: a commit that is not reachable from any of the refs and
+ there is a missing object among the commit, tree, or blob
+ objects reachable from it that is not reachable from any of the
+ refs.
++
+This computation involves traversing all the reachable objects, i.e. it
+has the same cost as 'git prune'. Fortunately, once this is run, we
+should not have to ever worry about missing objects, because the current
+prune and pack-objects know about reflogs and protect objects referred by
+them.
+
--expire=<time>::
Entries older than this time are pruned. Without the
option it is taken from configuration `gc.reflogExpire`,
@@ -65,4 +78,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-relink.txt b/Documentation/git-relink.txt
index aca6012..fe631bb 100644
--- a/Documentation/git-relink.txt
+++ b/Documentation/git-relink.txt
@@ -34,4 +34,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt
index b35c65b..61a6022 100644
--- a/Documentation/git-remote.txt
+++ b/Documentation/git-remote.txt
@@ -135,4 +135,3 @@ Documentation by J. Bruce Fields and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-repack.txt b/Documentation/git-repack.txt
index c57013b..5283ef8 100644
--- a/Documentation/git-repack.txt
+++ b/Documentation/git-repack.txt
@@ -68,6 +68,22 @@ OPTIONS
to be applied that many times to get to the necessary object.
The default value for --window is 10 and --depth is 50.
+--window-memory=[N]::
+ This option provides an additional limit on top of `--window`;
+ the window size will dynamically scale down so as to not take
+ up more than N bytes in memory. This is useful in
+ repositories with a mix of large and small objects to not run
+ out of memory with a large window, but still be able to take
+ advantage of the large window for the smaller objects. The
+ size can be suffixed with "k", "m", or "g".
+ `--window-memory=0` makes memory usage unlimited, which is the
+ default.
+
+--max-pack-size=<n>::
+ Maximum size of each output packfile, expressed in MiB.
+ If specified, multiple packfiles may be created.
+ The default is unlimited.
+
Configuration
-------------
@@ -99,4 +115,3 @@ gitlink:git-prune-packed[1]
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-request-pull.txt b/Documentation/git-request-pull.txt
index 478a5fd..087eeb7 100644
--- a/Documentation/git-request-pull.txt
+++ b/Documentation/git-request-pull.txt
@@ -37,4 +37,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-rerere.txt b/Documentation/git-rerere.txt
index 7ff9b05..c4d4263 100644
--- a/Documentation/git-rerere.txt
+++ b/Documentation/git-rerere.txt
@@ -23,7 +23,7 @@ initial manual merge, and later by noticing the same automerge
results and applying the previously recorded hand resolution.
[NOTE]
-You need to create `$GIT_DIR/rr-cache` directory to enable this
+You need to set the config variable rerere.enabled to enable this
command.
@@ -171,7 +171,7 @@ records it if it is a new conflict, or reuses the earlier hand
resolve when it is not. `git-commit` also invokes `git-rerere`
when recording a merge result. What this means is that you do
not have to do anything special yourself (Note: you still have
-to create `$GIT_DIR/rr-cache` directory to enable this command).
+to set the config variable rerere.enabled to enable this command).
In our example, when you did the test merge, the manual
resolution is recorded, and it will be reused when you do the
diff --git a/Documentation/git-reset.txt b/Documentation/git-reset.txt
index 19c5b9b..15e3aca 100644
--- a/Documentation/git-reset.txt
+++ b/Documentation/git-reset.txt
@@ -63,7 +63,7 @@ $ git commit -a -c ORIG_HEAD <3>
<1> This is most often done when you remembered what you
just committed is incomplete, or you misspelled your commit
message, or both. Leaves working tree as it was before "reset".
-<2> make corrections to working tree files.
+<2> Make corrections to working tree files.
<3> "reset" copies the old head to .git/ORIG_HEAD; redo the
commit by starting with its log message. If you do not need to
edit the message further, you can give -C option instead.
@@ -106,17 +106,17 @@ $ git reset <3>
$ git pull git://info.example.com/ nitfol <4>
------------
+
-<1> you are happily working on something, and find the changes
+<1> You are happily working on something, and find the changes
in these files are in good order. You do not want to see them
when you run "git diff", because you plan to work on other files
and changes with these files are distracting.
-<2> somebody asks you to pull, and the changes sounds worthy of merging.
-<3> however, you already dirtied the index (i.e. your index does
+<2> Somebody asks you to pull, and the changes sounds worthy of merging.
+<3> However, you already dirtied the index (i.e. your index does
not match the HEAD commit). But you know the pull you are going
to make does not affect frotz.c nor filfre.c, so you revert the
index changes for these two files. Your changes in working tree
remain there.
-<4> then you can pull and merge, leaving frotz.c and filfre.c
+<4> Then you can pull and merge, leaving frotz.c and filfre.c
changes still in the working tree.
Undo a merge or pull::
@@ -133,15 +133,15 @@ Fast forward
$ git reset --hard ORIG_HEAD <4>
------------
+
-<1> try to update from the upstream resulted in a lot of
+<1> Try to update from the upstream resulted in a lot of
conflicts; you were not ready to spend a lot of time merging
right now, so you decide to do that later.
<2> "pull" has not made merge commit, so "git reset --hard"
which is a synonym for "git reset --hard HEAD" clears the mess
from the index file and the working tree.
-<3> merge a topic branch into the current branch, which resulted
+<3> Merge a topic branch into the current branch, which resulted
in a fast forward.
-<4> but you decided that the topic branch is not ready for public
+<4> But you decided that the topic branch is not ready for public
consumption yet. "pull" or "merge" always leaves the original
tip of the current branch in ORIG_HEAD, so resetting hard to it
brings your index file and the working tree back to that state,
diff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt
index c3c2043..1c19781 100644
--- a/Documentation/git-rev-list.txt
+++ b/Documentation/git-rev-list.txt
@@ -16,16 +16,20 @@ SYNOPSIS
[ \--sparse ]
[ \--no-merges ]
[ \--remove-empty ]
+ [ \--full-history ]
[ \--not ]
[ \--all ]
[ \--stdin ]
[ \--topo-order ]
[ \--parents ]
+ [ \--timestamp ]
[ \--left-right ]
[ \--cherry-pick ]
[ \--encoding[=<encoding>] ]
[ \--(author|committer|grep)=<pattern> ]
- [ \--date={local|relative|default} ]
+ [ \--regexp-ignore-case | \-i ]
+ [ \--extended-regexp | \-E ]
+ [ \--date={local|relative|default|iso|rfc|short} ]
[ [\--objects | \--objects-edge] [ \--unpacked ] ]
[ \--pretty | \--header ]
[ \--bisect ]
@@ -33,6 +37,7 @@ SYNOPSIS
[ \--merge ]
[ \--reverse ]
[ \--walk-reflogs ]
+ [ \--no-walk ] [ \--do-walk ]
<commit>... [ \-- <paths>... ]
DESCRIPTION
@@ -93,7 +98,7 @@ include::pretty-options.txt[]
Synonym for `--date=relative`.
---date={relative,local,default}::
+--date={relative,local,default,iso,rfc}::
Only takes effect for dates shown in human-readable format, such
as when using "--pretty".
@@ -103,6 +108,13 @@ e.g. "2 hours ago".
+
`--date=local` shows timestamps in user's local timezone.
+
+`--date=iso` (or `--date=iso8601`) shows timestamps in ISO 8601 format.
++
+`--date=rfc` (or `--date=rfc2822`) shows timestamps in RFC 2822
+format, often found in E-mail messages.
++
+`--date=short` shows only date but not time, in `YYYY-MM-DD` fomat.
++
`--date=default` shows timestamps in the original timezone
(either committer's or author's).
@@ -115,6 +127,9 @@ e.g. "2 hours ago".
Print the parents of the commit.
+--timestamp::
+ Print the raw commit timestamp.
+
--left-right::
Mark which side of a symmetric diff a commit is reachable from.
@@ -214,10 +229,27 @@ limiting may be applied.
Limit the commits output to ones with log message that
matches the specified pattern (regular expression).
+-i, --regexp-ignore-case::
+
+ Match the regexp limiting patterns without regard to letters case.
+
+-E, --extended-regexp::
+
+ Consider the limiting patterns to be extended regular expressions
+ instead of the default basic regular expressions.
+
--remove-empty::
Stop when a given path disappears from the tree.
+--full-history::
+
+ Show also parts of history irrelevant to current state of a given
+ path. This turns off history simplification, which removed merges
+ which didn't change anything at all at some child. It will still actually
+ simplify away merges that didn't change anything at all into either
+ child.
+
--no-merges::
Do not print commits with more than one parent.
@@ -261,9 +293,9 @@ excluded from the output.
+
With '\--pretty' format other than oneline (for obvious reasons),
this causes the output to have two extra lines of information
-taken from the reflog. By default, 'commit@{Nth}' notation is
+taken from the reflog. By default, 'commit@\{Nth}' notation is
used in the output. When the starting commit is specified as
-'commit@{now}', output also uses 'commit@{timestamp}' notation
+'commit@{now}', output also uses 'commit@\{timestamp}' notation
instead. Under '\--pretty=oneline', the commit message is
prefixed with this information on the same line.
@@ -367,6 +399,14 @@ These options are mostly targeted for packing of git repositories.
Only useful with '--objects'; print the object IDs that are not
in packs.
+--no-walk::
+
+ Only show the given revs, but do not traverse their ancestors.
+
+--do-walk::
+
+ Overrides a previous --no-walk.
+
include::pretty-formats.txt[]
diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index 7757abe..eea9c9c 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -89,6 +89,17 @@ OPTIONS
--git-dir::
Show `$GIT_DIR` if defined else show the path to the .git directory.
+--is-inside-git-dir::
+ When the current working directory is below the repository
+ directory print "true", otherwise "false".
+
+--is-inside-work-tree::
+ When the current working directory is inside the work tree of the
+ repository print "true", otherwise "false".
+
+--is-bare-repository::
+ When the repository is bare print "true", otherwise "false".
+
--short, --short=number::
Instead of outputting the full SHA1 values of object names try to
abbreviate them to a shorter unique name. When no length is specified
@@ -286,4 +297,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-revert.txt b/Documentation/git-revert.txt
index 8081bba..69db498 100644
--- a/Documentation/git-revert.txt
+++ b/Documentation/git-revert.txt
@@ -56,4 +56,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-rm.txt b/Documentation/git-rm.txt
index a65f24a..be61a82 100644
--- a/Documentation/git-rm.txt
+++ b/Documentation/git-rm.txt
@@ -14,7 +14,8 @@ DESCRIPTION
Remove files from the working tree and from the index. The
files have to be identical to the tip of the branch, and no
updates to its contents must have been placed in the staging
-area (aka index).
+area (aka index). When --cached is given, the staged content has to
+match either the tip of the branch *or* the file on disk.
OPTIONS
@@ -95,4 +96,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-runstatus.txt b/Documentation/git-runstatus.txt
index 8bb52f4..dee5d0d 100644
--- a/Documentation/git-runstatus.txt
+++ b/Documentation/git-runstatus.txt
@@ -66,4 +66,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt
index 7ae39fd..d243ed1 100644
--- a/Documentation/git-send-email.txt
+++ b/Documentation/git-send-email.txt
@@ -44,8 +44,8 @@ The --cc option must be repeated for each user you want on the cc list.
value; if that is unspecified, default to --chain-reply-to.
--compose::
- Use $EDITOR to edit an introductory message for the
- patch series.
+ Use $GIT_EDITOR, core.editor, $VISUAL, or $EDITOR to edit an
+ introductory message for the patch series.
--from::
Specify the sender of the emails. This will default to
@@ -59,9 +59,11 @@ The --cc option must be repeated for each user you want on the cc list.
Only necessary if --compose is also set. If --compose
is not set, this will be prompted for.
---no-signed-off-by-cc::
- Do not add emails found in Signed-off-by: or Cc: lines to the
- cc list.
+--signed-off-by-cc, --no-signed-off-by-cc::
+ If this is set, add emails found in Signed-off-by: or Cc: lines to the
+ cc list.
+ Default is the value of 'sendemail.signedoffbycc' configuration value;
+ if that is unspecified, default to --signed-off-by-cc.
--quiet::
Make git-send-email less verbose. One line per email should be
@@ -78,13 +80,22 @@ The --cc option must be repeated for each user you want on the cc list.
`localhost` otherwise.
--subject::
- Specify the initial subject of the email thread.
+ Specify the initial subject of the email thread.
Only necessary if --compose is also set. If --compose
is not set, this will be prompted for.
---suppress-from::
- Do not add the From: address to the cc: list, if it shows up in a From:
- line.
+--suppress-from, --no-suppress-from::
+ If this is set, do not add the From: address to the cc: list, if it
+ shows up in a From: line.
+ Default is the value of 'sendemail.suppressfrom' configuration value;
+ if that is unspecified, default to --no-supress-from.
+
+--thread, --no-thread::
+ If this is set, the In-Reply-To header will be set on each email sent.
+ If disabled with "--no-thread", no emails will have the In-Reply-To
+ header set.
+ Default is the value of the 'sendemail.thread' configuration value;
+ if that is unspecified, default to --thread.
--dry-run::
Do everything except actually send the emails.
@@ -137,4 +148,3 @@ Documentation by Ryan Anderson
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-sh-setup.txt b/Documentation/git-sh-setup.txt
index 2b2abeb..1ea1faa 100644
--- a/Documentation/git-sh-setup.txt
+++ b/Documentation/git-sh-setup.txt
@@ -69,4 +69,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-shell.txt b/Documentation/git-shell.txt
index 228b9f1..48f2d57 100644
--- a/Documentation/git-shell.txt
+++ b/Documentation/git-shell.txt
@@ -32,4 +32,3 @@ Documentation by Petr Baudis and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-shortlog.txt b/Documentation/git-shortlog.txt
index 15cc6f7..2220ef6 100644
--- a/Documentation/git-shortlog.txt
+++ b/Documentation/git-shortlog.txt
@@ -56,4 +56,3 @@ Documentation by Junio C Hamano.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-show-index.txt b/Documentation/git-show-index.txt
index be09b62..764d993 100644
--- a/Documentation/git-show-index.txt
+++ b/Documentation/git-show-index.txt
@@ -32,4 +32,3 @@ Documentation by Junio C Hamano
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-show.txt b/Documentation/git-show.txt
index 34c5caf..a42e121 100644
--- a/Documentation/git-show.txt
+++ b/Documentation/git-show.txt
@@ -84,4 +84,3 @@ This manual page is a stub. You can help the git documentation by expanding it.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-ssh-fetch.txt b/Documentation/git-ssh-fetch.txt
index 192b1f1..8d3e2ff 100644
--- a/Documentation/git-ssh-fetch.txt
+++ b/Documentation/git-ssh-fetch.txt
@@ -13,6 +13,8 @@ SYNOPSIS
DESCRIPTION
-----------
+THIS COMMAND IS DEPRECATED.
+
Pulls from a remote repository over ssh connection, invoking
git-ssh-upload on the other end. It functions identically to
git-ssh-upload, aside from which end you run it on.
@@ -48,4 +50,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-ssh-upload.txt b/Documentation/git-ssh-upload.txt
index a9b7e9f..5e2ca8d 100644
--- a/Documentation/git-ssh-upload.txt
+++ b/Documentation/git-ssh-upload.txt
@@ -12,6 +12,8 @@ SYNOPSIS
DESCRIPTION
-----------
+THIS COMMAND IS DEPRECATED.
+
Pushes from a remote repository over ssh connection, invoking
git-ssh-fetch on the other end. It functions identically to
git-ssh-fetch, aside from which end you run it on.
@@ -44,4 +46,3 @@ Documentation by Daniel Barkalow
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt
new file mode 100644
index 0000000..17121ad
--- /dev/null
+++ b/Documentation/git-stash.txt
@@ -0,0 +1,165 @@
+git-stash(1)
+============
+
+NAME
+----
+git-stash - Stash the changes in a dirty working directory away
+
+SYNOPSIS
+--------
+[verse]
+'git-stash' (list | show [<stash>] | apply [<stash>] | clear)
+'git-stash' [save] [message...]
+
+DESCRIPTION
+-----------
+
+Use 'git-stash' when you want to record the current state of the
+working directory and the index, but want to go back to a clean
+working directory. The command saves your local modifications away
+and reverts the working directory to match the `HEAD` commit.
+
+The modifications stashed away by this command can be listed with
+`git-stash list`, inspected with `git-stash show`, and restored
+(potentially on top of a different commit) with `git-stash apply`.
+Calling git-stash without any arguments is equivalent to `git-stash
+save`. A stash is by default listed as "WIP on 'branchname' ...", but
+you can give a more descriptive message on the command line when
+you create one.
+
+The latest stash you created is stored in `$GIT_DIR/refs/stash`; older
+stashes are found in the reflog of this reference and can be named using
+the usual reflog syntax (e.g. `stash@\{1}` is the most recently
+created stash, `stash@\{2}` is the one before it, `stash@\{2.hours.ago}`
+is also possible).
+
+OPTIONS
+-------
+
+save::
+
+ Save your local modifications to a new 'stash', and run `git-reset
+ --hard` to revert them. This is the default action when no
+ subcommand is given.
+
+list::
+
+ List the stashes that you currently have. Each 'stash' is listed
+ with its name (e.g. `stash@\{0}` is the latest stash, `stash@\{1} is
+ the one before, etc.), the name of the branch that was current when the
+ stash was made, and a short description of the commit the stash was
+ based on.
++
+----------------------------------------------------------------
+stash@{0}: WIP on submit: 6ebd0e2... Update git-stash documentation
+stash@{1}: On master: 9cc0589... Add git-stash
+----------------------------------------------------------------
+
+show [<stash>]::
+
+ Show the changes recorded in the stash as a diff between the the
+ stashed state and its original parent. When no `<stash>` is given,
+ shows the latest one. By default, the command shows the diffstat, but
+ it will accept any format known to `git-diff` (e.g., `git-stash show
+ -p stash@\{2}` to view the second most recent stash in patch form).
+
+apply [<stash>]::
+
+ Restore the changes recorded in the stash on top of the current
+ working tree state. When no `<stash>` is given, applies the latest
+ one. The working directory must match the index.
++
+This operation can fail with conflicts; you need to resolve them
+by hand in the working tree.
+
+clear::
+ Remove all the stashed states. Note that those states will then
+ be subject to pruning, and may be difficult or impossible to recover.
+
+
+DISCUSSION
+----------
+
+A stash is represented as a commit whose tree records the state of the
+working directory, and its first parent is the commit at `HEAD` when
+the stash was created. The tree of the second parent records the
+state of the index when the stash is made, and it is made a child of
+the `HEAD` commit. The ancestry graph looks like this:
+
+ .----W
+ / /
+ -----H----I
+
+where `H` is the `HEAD` commit, `I` is a commit that records the state
+of the index, and `W` is a commit that records the state of the working
+tree.
+
+
+EXAMPLES
+--------
+
+Pulling into a dirty tree::
+
+When you are in the middle of something, you learn that there are
+upstream changes that are possibly relevant to what you are
+doing. When your local changes do not conflict with the changes in
+the upstream, a simple `git pull` will let you move forward.
++
+However, there are cases in which your local changes do conflict with
+the upstream changes, and `git pull` refuses to overwrite your
+changes. In such a case, you can stash your changes away,
+perform a pull, and then unstash, like this:
++
+----------------------------------------------------------------
+$ git pull
+...
+file foobar not up to date, cannot merge.
+$ git stash
+$ git pull
+$ git stash apply
+----------------------------------------------------------------
+
+Interrupted workflow::
+
+When you are in the middle of something, your boss comes in and
+demands that you fix something immediately. Traditionally, you would
+make a commit to a temporary branch to store your changes away, and
+return to your original branch to make the emergency fix, like this:
++
+----------------------------------------------------------------
+... hack hack hack ...
+$ git checkout -b my_wip
+$ git commit -a -m "WIP"
+$ git checkout master
+$ edit emergency fix
+$ git commit -a -m "Fix in a hurry"
+$ git checkout my_wip
+$ git reset --soft HEAD^
+... continue hacking ...
+----------------------------------------------------------------
++
+You can use `git-stash` to simplify the above, like this:
++
+----------------------------------------------------------------
+... hack hack hack ...
+$ git stash
+$ edit emergency fix
+$ git commit -a -m "Fix in a hurry"
+$ git stash apply
+... continue hacking ...
+----------------------------------------------------------------
+
+SEE ALSO
+--------
+gitlink:git-checkout[1],
+gitlink:git-commit[1],
+gitlink:git-reflog[1],
+gitlink:git-reset[1]
+
+AUTHOR
+------
+Written by Nanako Shiraishi <nanako3@bluebottle.com>
+
+GIT
+---
+Part of the gitlink:git[7] suite
diff --git a/Documentation/git-status.txt b/Documentation/git-status.txt
index 1fd1af1..6f16eb0 100644
--- a/Documentation/git-status.txt
+++ b/Documentation/git-status.txt
@@ -58,4 +58,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-stripspace.txt b/Documentation/git-stripspace.txt
index 3a03dd0..1306d7b 100644
--- a/Documentation/git-stripspace.txt
+++ b/Documentation/git-stripspace.txt
@@ -30,4 +30,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
new file mode 100644
index 0000000..2c48936
--- /dev/null
+++ b/Documentation/git-submodule.txt
@@ -0,0 +1,77 @@
+git-submodule(1)
+================
+
+NAME
+----
+git-submodule - Initialize, update or inspect submodules
+
+
+SYNOPSIS
+--------
+[verse]
+'git-submodule' [--quiet] [-b branch] add <repository> [<path>]
+'git-submodule' [--quiet] [--cached] [status|init|update] [--] [<path>...]
+
+
+COMMANDS
+--------
+add::
+ Add the given repository as a submodule at the given path
+ to the changeset to be committed next. In particular, the
+ repository is cloned at the specified path, added to the
+ changeset and registered in .gitmodules. If no path is
+ specified, the path is deduced from the repository specification.
+
+status::
+ Show the status of the submodules. This will print the SHA-1 of the
+ currently checked out commit for each submodule, along with the
+ submodule path and the output of gitlink:git-describe[1] for the
+ SHA-1. Each SHA-1 will be prefixed with `-` if the submodule is not
+ initialized and `+` if the currently checked out submodule commit
+ does not match the SHA-1 found in the index of the containing
+ repository. This command is the default command for git-submodule.
+
+init::
+ Initialize the submodules, i.e. register in .git/config each submodule
+ name and url found in .gitmodules. The key used in .git/config is
+ `submodule.$name.url`. This command does not alter existing information
+ in .git/config.
+
+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.
+
+
+OPTIONS
+-------
+-q, --quiet::
+ Only print error messages.
+
+-b, --branch::
+ Branch of repository to add as submodule.
+
+--cached::
+ Display the SHA-1 stored in the index, not the SHA-1 of the currently
+ checked out submodule commit. This option is only valid for the
+ status command.
+
+<path>::
+ Path to submodule(s). When specified this will restrict the command
+ to only operate on the submodules found at the specified paths.
+
+FILES
+-----
+When initializing submodules, a .gitmodules file in the top-level directory
+of the containing repository is used to find the url of each submodule.
+This file should be formatted in the same way as $GIR_DIR/config. The key
+to each submodule url is "submodule.$name.url".
+
+
+AUTHOR
+------
+Written by Lars Hjemli <hjemli@gmail.com>
+
+GIT
+---
+Part of the gitlink:git[7] suite
diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt
index c0d7d95..0a210e4 100644
--- a/Documentation/git-svn.txt
+++ b/Documentation/git-svn.txt
@@ -66,9 +66,10 @@ COMMANDS
to the names of remotes if trunk/branches/tags are
specified. The prefix does not automatically include a
trailing slash, so be sure you include one in the
- argument if that is what you want. This is useful if
- you wish to track multiple projects that share a common
- repository.
+ argument if that is what you want. If --branches/-b is
+ specified, the prefix must include a trailing slash.
+ Setting a prefix is useful if you wish to track multiple
+ projects that share a common repository.
'fetch'::
Fetch unfetched revisions from the Subversion remote we are
diff --git a/Documentation/git-svnimport.txt b/Documentation/git-svnimport.txt
index bdae7d8..e97d15e 100644
--- a/Documentation/git-svnimport.txt
+++ b/Documentation/git-svnimport.txt
@@ -174,4 +174,3 @@ Documentation by Matthias Urlichs <smurf@smurf.noris.de>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt
index 4e3e027..aee2c1b 100644
--- a/Documentation/git-tag.txt
+++ b/Documentation/git-tag.txt
@@ -11,7 +11,7 @@ SYNOPSIS
[verse]
'git-tag' [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] <name> [<head>]
'git-tag' -d <name>...
-'git-tag' -l [<pattern>]
+'git-tag' [-n [<num>]] -l [<pattern>]
'git-tag' -v <name>
DESCRIPTION
@@ -38,8 +38,8 @@ GnuPG key for signing.
`-v <tag>` verifies the gpg signature of the tag.
-`-l <pattern>` lists tags that match the given pattern (or all
-if no pattern is given).
+`-l <pattern>` lists tags with names that match the given pattern
+(or all if no pattern is given).
OPTIONS
-------
@@ -61,8 +61,13 @@ OPTIONS
-v::
Verify the gpg signature of given the tag
+-n <num>::
+ <num> specifies how many lines from the annotation, if any,
+ are printed when using -l.
+ The default is not to print any annotation lines.
+
-l <pattern>::
- List tags that match the given pattern (or all if no pattern is given).
+ List tags with names that match the given pattern (or all if no pattern is given).
-m <msg>::
Use the given tag message (instead of prompting)
diff --git a/Documentation/git-tar-tree.txt b/Documentation/git-tar-tree.txt
index 7bde73b..2d01d96 100644
--- a/Documentation/git-tar-tree.txt
+++ b/Documentation/git-tar-tree.txt
@@ -90,4 +90,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-unpack-file.txt b/Documentation/git-unpack-file.txt
index 213dc81..20bb6a7 100644
--- a/Documentation/git-unpack-file.txt
+++ b/Documentation/git-unpack-file.txt
@@ -33,4 +33,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-unpack-objects.txt b/Documentation/git-unpack-objects.txt
index b1b3ec9..d529a43 100644
--- a/Documentation/git-unpack-objects.txt
+++ b/Documentation/git-unpack-objects.txt
@@ -52,4 +52,3 @@ Documentation by Junio C Hamano
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt
index 6cfbd9a..0a19538 100644
--- a/Documentation/git-update-index.txt
+++ b/Documentation/git-update-index.txt
@@ -56,7 +56,7 @@ OPTIONS
--unmerged::
If --refresh finds unmerged changes in the index, the default
- behavior is to error out. This option makes git-update-index
+ behavior is to error out. This option makes git-update-index
continue anyway.
--ignore-missing::
@@ -64,12 +64,12 @@ OPTIONS
--cacheinfo <mode> <object> <path>::
Directly insert the specified info into the index.
-
+
--index-info::
Read index information from stdin.
--chmod=(+|-)x::
- Set the execute permissions on the updated files.
+ Set the execute permissions on the updated files.
--assume-unchanged, --no-assume-unchanged::
When these flags are specified, the object name recorded
@@ -126,7 +126,7 @@ OPTIONS
<file>::
Files to act on.
Note that files beginning with '.' are discarded. This includes
- `./file` and `dir/./file`. If you don't want this, then use
+ `./file` and `dir/./file`. If you don't want this, then use
cleaner names.
The same applies to directories ending '/' and paths with '//'
@@ -324,4 +324,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-update-ref.txt b/Documentation/git-update-ref.txt
index 9424fea..f222616 100644
--- a/Documentation/git-update-ref.txt
+++ b/Documentation/git-update-ref.txt
@@ -7,7 +7,7 @@ git-update-ref - Update the object name stored in a ref safely
SYNOPSIS
--------
-'git-update-ref' [-m <reason>] (-d <ref> <oldvalue> | <ref> <newvalue> [<oldvalue>])
+'git-update-ref' [-m <reason>] (-d <ref> <oldvalue> | [--no-deref] <ref> <newvalue> [<oldvalue>])
DESCRIPTION
-----------
@@ -36,6 +36,9 @@ them and update them as a regular file (i.e. it will allow the
filesystem to follow them, but will overwrite such a symlink to
somewhere else with a regular filename).
+If --no-deref is given, <ref> itself is overwritten, rather than
+the result of following the symbolic pointers.
+
In general, using
git-update-ref HEAD "$head"
diff --git a/Documentation/git-update-server-info.txt b/Documentation/git-update-server-info.txt
index 88a03c7..e7e82a3 100644
--- a/Documentation/git-update-server-info.txt
+++ b/Documentation/git-update-server-info.txt
@@ -55,4 +55,3 @@ Documentation by Junio C Hamano.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-var.txt b/Documentation/git-var.txt
index 9b0de1c..8139423 100644
--- a/Documentation/git-var.txt
+++ b/Documentation/git-var.txt
@@ -62,4 +62,3 @@ Documentation by Eric Biederman and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-verify-pack.txt b/Documentation/git-verify-pack.txt
index 7a6132b..f4c540f 100644
--- a/Documentation/git-verify-pack.txt
+++ b/Documentation/git-verify-pack.txt
@@ -51,4 +51,3 @@ Documentation by Junio C Hamano
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-verify-tag.txt b/Documentation/git-verify-tag.txt
index 0f9bdb5..48d17fd 100644
--- a/Documentation/git-verify-tag.txt
+++ b/Documentation/git-verify-tag.txt
@@ -29,4 +29,3 @@ Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-whatchanged.txt b/Documentation/git-whatchanged.txt
index 399bff3..607df48 100644
--- a/Documentation/git-whatchanged.txt
+++ b/Documentation/git-whatchanged.txt
@@ -78,4 +78,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-write-tree.txt b/Documentation/git-write-tree.txt
index 96d5e07..cb8d6aa 100644
--- a/Documentation/git-write-tree.txt
+++ b/Documentation/git-write-tree.txt
@@ -47,4 +47,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 98860af..18f8b6a 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -10,7 +10,8 @@ SYNOPSIS
--------
[verse]
'git' [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate]
- [--bare] [--git-dir=GIT_DIR] [--help] COMMAND [ARGS]
+ [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE]
+ [--help] COMMAND [ARGS]
DESCRIPTION
-----------
@@ -41,9 +42,13 @@ unreleased) version of git, that is available from 'master'
branch of the `git.git` repository.
Documentation for older releases are available here:
-* link:v1.5.2/git.html[documentation for release 1.5.2]
+* link:v1.5.2.4/git.html[documentation for release 1.5.2.4]
* release notes for
+ link:RelNotes-1.5.2.4.txt[1.5.2.4],
+ link:RelNotes-1.5.2.3.txt[1.5.2.3],
+ link:RelNotes-1.5.2.2.txt[1.5.2.2],
+ link:RelNotes-1.5.2.1.txt[1.5.2.1],
link:RelNotes-1.5.2.txt[1.5.2].
* link:v1.5.1.6/git.html[documentation for release 1.5.1.6]
@@ -101,6 +106,14 @@ OPTIONS
Set the path to the repository. This can also be controlled by
setting the GIT_DIR environment variable.
+--work-tree=<path>::
+ Set the path to the working tree. The value will not be
+ used in combination with repositories found automatically in
+ a .git directory (i.e. $GIT_DIR is not set).
+ This can also be controlled by setting the GIT_WORK_TREE
+ environment variable and the core.worktree configuration
+ variable.
+
--bare::
Same as --git-dir=`pwd`.
@@ -345,6 +358,13 @@ git so take care if using Cogito etc.
specifies a path to use instead of the default `.git`
for the base of the repository.
+'GIT_WORK_TREE'::
+ Set the path to the working tree. The value will not be
+ used in combination with repositories found automatically in
+ a .git directory (i.e. $GIT_DIR is not set).
+ This can also be controlled by the '--work-tree' command line
+ option and the core.worktree configuration variable.
+
git Commits
~~~~~~~~~~~
'GIT_AUTHOR_NAME'::
@@ -391,8 +411,41 @@ parameter, <path>.
other
~~~~~
+'GIT_MERGE_VERBOSITY'::
+ A number controlling the amount of output shown by
+ the recursive merge strategy. Overrides merge.verbosity.
+ See gitlink:git-merge[1]
+
'GIT_PAGER'::
- This environment variable overrides `$PAGER`.
+ This environment variable overrides `$PAGER`. If it is set
+ to an empty string or to the value "cat", git will not launch
+ a pager.
+
+'GIT_SSH'::
+ If this environment variable is set then gitlink:git-fetch[1]
+ and gitlink:git-push[1] will use this command instead
+ of `ssh` when they need to connect to a remote system.
+ The 'GIT_SSH' command will be given exactly two arguments:
+ the 'username@host' (or just 'host') from the URL and the
+ shell command to execute on that remote system.
++
+To pass options to the program that you want to list in GIT_SSH
+you will need to wrap the program and options into a shell script,
+then set GIT_SSH to refer to the shell script.
++
+Usually it is easier to configure any desired options through your
+personal `.ssh/config` file. Please consult your ssh documentation
+for further details.
+
+'GIT_FLUSH'::
+ If this environment variable is set to "1", then commands such
+ as git-blame (in incremental mode), git-rev-list, git-log,
+ git-whatchanged, etc., will force a flush of the output stream
+ after each commit-oriented record have been flushed. If this
+ variable is set to "0", the output of these commands will be done
+ using completely buffered I/O. If this environment variable is
+ not set, git will choose buffered or record-oriented flushing
+ based on whether stdout appears to be redirected to a file or not.
'GIT_TRACE'::
If this variable is set to "1", "2" or "true" (comparison
@@ -428,4 +481,3 @@ contributors on the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt
index d3ac9c7..8b90a5b 100644
--- a/Documentation/gitattributes.txt
+++ b/Documentation/gitattributes.txt
@@ -72,8 +72,8 @@ EFFECTS
-------
Certain operations by git can be influenced by assigning
-particular attributes to a path. Currently, three operations
-are attributes-aware.
+particular attributes to a path. Currently, the following
+operations are attributes-aware.
Checking-out and checking-in
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -199,7 +199,9 @@ Generating diff text
~~~~~~~~~~~~~~~~~~~~
The attribute `diff` affects if `git diff` generates textual
-patch for the path or just says `Binary files differ`.
+patch for the path or just says `Binary files differ`. It also
+can affect what line is shown on the hunk header `@@ -k,l +n,m @@`
+line.
Set::
@@ -224,7 +226,8 @@ String::
Diff is shown using the specified custom diff driver.
The driver program is given its input using the same
calling convention as used for GIT_EXTERNAL_DIFF
- program.
+ program. This name is also used for custom hunk header
+ selection.
Defining a custom diff driver
@@ -249,6 +252,50 @@ parameters, just like `GIT_EXTERNAL_DIFF` program is called.
See gitlink:git[7] for details.
+Defining a custom hunk-header
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Each group of changes (called "hunk") in the textual diff output
+is prefixed with a line of the form:
+
+ @@ -k,l +n,m @@ TEXT
+
+The text is called 'hunk header', and by default a line that
+begins with an alphabet, an underscore or a dollar sign is used,
+which matches what GNU `diff -p` output uses. This default
+selection however is not suited for some contents, and you can
+use customized pattern to make a selection.
+
+First in .gitattributes, you would assign the `diff` attribute
+for paths.
+
+------------------------
+*.tex diff=tex
+------------------------
+
+Then, you would define "diff.tex.funcname" configuration to
+specify a regular expression that matches a line that you would
+want to appear as the hunk header, like this:
+
+------------------------
+[diff "tex"]
+ funcname = "^\\(\\\\\\(sub\\)*section{.*\\)$"
+------------------------
+
+Note. A single level of backslashes are eaten by the
+configuration file parser, so you would need to double the
+backslashes; the pattern above picks a line that begins with a
+backslash, and zero or more occurences of `sub` followed by
+`section` followed by open brace, to the end of line.
+
+There are a few built-in patterns to make this easier, and `tex`
+is one of them, so you do not have to write the above in your
+configuration file (you still need to enable this with the
+attribute mechanism, via `.gitattributes`). Another built-in
+pattern is defined for `java` that defines a pattern suitable
+for program text in Java language.
+
+
Performing a three-way merge
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -358,7 +405,7 @@ the attributes given to path `t/abc` are computed as follows:
and `bar` attributes should be given to this path, so it
leaves `foo` and `bar` unset. Attribute `baz` is set.
-3. Finally it examines `$GIT_DIR/info/gitattributes`. This file
+3. Finally it examines `$GIT_DIR/info/attributes`. This file
is used to override the in-tree settings. The first line is
a match, and `foo` is set, `bar` is reverted to unspecified
state, and `baz` is unset.
diff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt
index ea79d74..9c83095 100644
--- a/Documentation/gitignore.txt
+++ b/Documentation/gitignore.txt
@@ -18,21 +18,26 @@ pattern.
When deciding whether to ignore a path, git normally checks
`gitignore` patterns from multiple sources, with the following
-order of precedence:
+order of precedence, from highest to lowest (within one level of
+precedence, the last matching pattern decides the outcome):
- * Patterns read from the file specified by the configuration
- variable 'core.excludesfile'.
-
- * Patterns read from `$GIT_DIR/info/exclude`.
+ * Patterns read from the command line for those commands that support
+ them.
* Patterns read from a `.gitignore` file in the same directory
- as the path, or in any parent directory, ordered from the
- deepest such file to a file in the root of the repository.
+ as the path, or in any parent directory, with patterns in the
+ higher level files (up to the root) being overriden by those in
+ lower level files down to the directory containing the file.
These patterns match relative to the location of the
`.gitignore` file. A project normally includes such
`.gitignore` files in its repository, containing patterns for
files generated as part of the project build.
+ * Patterns read from `$GIT_DIR/info/exclude`.
+
+ * Patterns read from the file specified by the configuration
+ variable 'core.excludesfile'.
+
The underlying git plumbing tools, such as
gitlink:git-ls-files[1] and gitlink:git-read-tree[1], read
`gitignore` patterns specified by command-line options, or from
@@ -49,7 +54,8 @@ Patterns have the following format:
- An optional prefix '!' which negates the pattern; any
matching file excluded by a previous pattern will become
- included again.
+ included again. If a negated pattern matches, this will
+ override lower precedence patterns sources.
- If the pattern does not contain a slash '/', git treats it as
a shell glob pattern and checks for a match against the
diff --git a/Documentation/gitk.txt b/Documentation/gitk.txt
index 48c5894..e9f82b9 100644
--- a/Documentation/gitk.txt
+++ b/Documentation/gitk.txt
@@ -99,4 +99,3 @@ Documentation by Junio C Hamano, Jonas Fonseca, and the git-list
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/gitmodules.txt b/Documentation/gitmodules.txt
new file mode 100644
index 0000000..035294e
--- /dev/null
+++ b/Documentation/gitmodules.txt
@@ -0,0 +1,62 @@
+gitmodules(5)
+=============
+
+NAME
+----
+gitmodules - defining submodule properties
+
+SYNOPSIS
+--------
+gitmodules
+
+
+DESCRIPTION
+-----------
+
+The `.gitmodules` file, located in the top-level directory of a git
+working tree, is a text file with a syntax matching the requirements
+of gitlink:git-config[1].
+
+The file contains one subsection per submodule, and the subsection value
+is the name of the submodule. Each submodule section also contains the
+following required keys:
+
+submodule.<name>.path::
+ Defines the path, relative to the top-level directory of the git
+ working tree, where the submodule is expected to be checked out.
+ The path name must not end with a `/`. All submodule paths must
+ be unique within the .gitmodules file.
+
+submodule.<name>.url::
+ Defines an url from where the submodule repository can be cloned.
+
+
+EXAMPLES
+--------
+
+Consider the following .gitmodules file:
+
+ [submodule "libfoo"]
+ path = include/foo
+ url = git://foo.com/git/lib.git
+
+ [submodule "libbar"]
+ path = include/bar
+ url = git://bar.com/git/lib.git
+
+
+This defines two submodules, `libfoo` and `libbar`. These are expected to
+be checked out in the paths 'include/foo' and 'include/bar', and for both
+submodules an url is specified which can be used for cloning the submodules.
+
+SEE ALSO
+--------
+gitlink:git-submodule[1] gitlink:git-config[1]
+
+DOCUMENTATION
+-------------
+Documentation by Lars Hjemli <hjemli@gmail.com>
+
+GIT
+---
+Part of the gitlink:git[7] suite
diff --git a/Documentation/hooks.txt b/Documentation/hooks.txt
index aabb975..6836477 100644
--- a/Documentation/hooks.txt
+++ b/Documentation/hooks.txt
@@ -12,11 +12,10 @@ This document describes the currently defined hooks.
applypatch-msg
--------------
-This hook is invoked by `git-applypatch` script, which is
-typically invoked by `git-applymbox`. It takes a single
+This hook is invoked by `git-am` script. It takes a single
parameter, the name of the file that holds the proposed commit
log message. Exiting with non-zero status causes
-`git-applypatch` to abort before applying the patch.
+`git-am` to abort before applying the patch.
The hook is allowed to edit the message file in place, and can
be used to normalize the message into some project standard
@@ -29,8 +28,7 @@ The default 'applypatch-msg' hook, when enabled, runs the
pre-applypatch
--------------
-This hook is invoked by `git-applypatch` script, which is
-typically invoked by `git-applymbox`. It takes no parameter,
+This hook is invoked by `git-am`. It takes no parameter,
and is invoked after the patch is applied, but before a commit
is made. Exiting with non-zero status causes the working tree
after application of the patch not committed.
@@ -44,12 +42,11 @@ The default 'pre-applypatch' hook, when enabled, runs the
post-applypatch
---------------
-This hook is invoked by `git-applypatch` script, which is
-typically invoked by `git-applymbox`. It takes no parameter,
+This hook is invoked by `git-am`. It takes no parameter,
and is invoked after the patch is applied and a commit is made.
This hook is meant primarily for notification, and cannot affect
-the outcome of `git-applypatch`.
+the outcome of `git-am`.
pre-commit
----------
diff --git a/Documentation/howto/rebase-and-edit.txt b/Documentation/howto/rebase-and-edit.txt
index 646c55c..554909f 100644
--- a/Documentation/howto/rebase-and-edit.txt
+++ b/Documentation/howto/rebase-and-edit.txt
@@ -9,16 +9,16 @@ Abstract: In this article, Linus demonstrates how a broken commit
On Sat, 13 Aug 2005, Linus Torvalds wrote:
-> That's correct. Same things apply: you can move a patch over, and create a
-> new one with a modified comment, but basically the _old_ commit will be
+> That's correct. Same things apply: you can move a patch over, and create a
+> new one with a modified comment, but basically the _old_ commit will be
> immutable.
Let me clarify.
You can entirely _drop_ old branches, so commits may be immutable, but
-nothing forces you to keep them. Of course, when you drop a commit, you'll
-always end up dropping all the commits that depended on it, and if you
-actually got somebody else to pull that commit you can't drop it from
+nothing forces you to keep them. Of course, when you drop a commit, you'll
+always end up dropping all the commits that depended on it, and if you
+actually got somebody else to pull that commit you can't drop it from
_their_ repository, but undoing things is not impossible.
For example, let's say that you've made a mess of things: you've committed
@@ -29,7 +29,7 @@ want to save "b" and "c". What you can do is
# for reference
git branch broken
- # Reset the main branch to three parents back: this
+ # Reset the main branch to three parents back: this
# effectively undoes the three top commits
git reset HEAD^^^
git checkout -f
@@ -59,7 +59,7 @@ Finally, check out the end result again:
to see that everything looks sensible.
-And then, you can just remove the broken branch if you decide you really
+And then, you can just remove the broken branch if you decide you really
don't want it:
# remove 'broken' branch
@@ -68,8 +68,8 @@ don't want it:
# Prune old objects if you're really really sure
git prune
-And yeah, I'm sure there are other ways of doing this. And as usual, the
-above is totally untested, and I just wrote it down in this email, so if
+And yeah, I'm sure there are other ways of doing this. And as usual, the
+above is totally untested, and I just wrote it down in this email, so if
I've done something wrong, you'll have to figure it out on your own ;)
Linus
@@ -77,5 +77,3 @@ I've done something wrong, you'll have to figure it out on your own ;)
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
-
-
diff --git a/Documentation/howto/rebase-from-internal-branch.txt b/Documentation/howto/rebase-from-internal-branch.txt
index 3b3a5c2..7a76045 100644
--- a/Documentation/howto/rebase-from-internal-branch.txt
+++ b/Documentation/howto/rebase-from-internal-branch.txt
@@ -14,10 +14,10 @@ Petr Baudis <pasky@suse.cz> writes:
> Dear diary, on Sun, Aug 14, 2005 at 09:57:13AM CEST, I got a letter
> where Junio C Hamano <junkio@cox.net> told me that...
>> Linus Torvalds <torvalds@osdl.org> writes:
->>
->> > Junio, maybe you want to talk about how you move patches from your "pu"
+>>
+>> > Junio, maybe you want to talk about how you move patches from your "pu"
>> > branch to the real branches.
->>
+>>
> Actually, wouldn't this be also precisely for what StGIT is intended to?
Exactly my feeling. I was sort of waiting for Catalin to speak
@@ -118,7 +118,7 @@ up your changes, along with other changes.
where *your "master" head
upstream --> #1 --> #2 --> #3
- used \
+ used \
to be \--> #A --> #2' --> #3' --> #B --> #C
*upstream head
@@ -133,7 +133,7 @@ You fetch from upstream, but not merge.
$ git fetch upstream
This leaves the updated upstream head in .git/FETCH_HEAD but
-does not touch your .git/HEAD nor .git/refs/heads/master.
+does not touch your .git/HEAD nor .git/refs/heads/master.
You run "git rebase" now.
$ git rebase FETCH_HEAD master
@@ -161,5 +161,3 @@ the #1' commit.
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
-
-
diff --git a/Documentation/howto/rebuild-from-update-hook.txt b/Documentation/howto/rebuild-from-update-hook.txt
index 02621b5..8d55dfb 100644
--- a/Documentation/howto/rebuild-from-update-hook.txt
+++ b/Documentation/howto/rebuild-from-update-hook.txt
@@ -84,4 +84,3 @@ There are four things worth mentioning:
- This is still crude and does not protect against simultaneous
make invocations stomping on each other. I would need to add
some locking mechanism for this.
-
diff --git a/Documentation/howto/revert-branch-rebase.txt b/Documentation/howto/revert-branch-rebase.txt
index d88ec23..865a666 100644
--- a/Documentation/howto/revert-branch-rebase.txt
+++ b/Documentation/howto/revert-branch-rebase.txt
@@ -146,7 +146,7 @@ Everything is in the good order. I do not need the temporary branch
nor tag anymore, so remove them:
------------------------------------------------
-$ rm -f .git/refs/tags/pu-anchor
+$ rm -f .git/refs/tags/pu-anchor
$ git branch -d revert-c99
------------------------------------------------
diff --git a/Documentation/howto/separating-topic-branches.txt b/Documentation/howto/separating-topic-branches.txt
index 090e2c9..0d73b31 100644
--- a/Documentation/howto/separating-topic-branches.txt
+++ b/Documentation/howto/separating-topic-branches.txt
@@ -12,7 +12,7 @@ up with a history like this:
"master"
o---o
- \ "topic"
+ \ "topic"
o---o---o---o---o---o
At this point, "topic" contains something I know I want, but it
@@ -29,11 +29,11 @@ start building on top of "master":
$ git checkout -b topicA master
... pick and apply pieces from P.diff to build
... commits on topicA branch.
-
+
o---o---o
/ "topicA"
o---o"master"
- \ "topic"
+ \ "topic"
o---o---o---o---o---o
Before doing each commit on "topicA" HEAD, I run "diff HEAD"
@@ -59,7 +59,7 @@ other topic:
/o---o---o
|/ "topicA"
o---o"master"
- \ "topic"
+ \ "topic"
o---o---o---o---o---o
After I am done, I'd try a pretend-merge between "topicA" and
@@ -73,7 +73,7 @@ After I am done, I'd try a pretend-merge between "topicA" and
/o---o---o----------'
|/ "topicA"
o---o"master"
- \ "topic"
+ \ "topic"
o---o---o---o---o---o
The last diff better not to show anything other than cleanups
@@ -84,8 +84,7 @@ for crufts. Then I can finally clean things up:
"topicB"
o---o---o---o---o
- /
+ /
/o---o---o
|/ "topicA"
o---o"master"
-
diff --git a/Documentation/howto/use-git-daemon.txt b/Documentation/howto/use-git-daemon.txt
index 1a1eb24..4e2f75c 100644
--- a/Documentation/howto/use-git-daemon.txt
+++ b/Documentation/howto/use-git-daemon.txt
@@ -49,4 +49,3 @@ Now, test your daemon with
$ git ls-remote git://127.0.0.1/rule-the-world.git
If this does not work, find out why, and submit a patch to this document.
-
diff --git a/Documentation/install-doc-quick.sh b/Documentation/install-doc-quick.sh
index a640549..07d227f 100755
--- a/Documentation/install-doc-quick.sh
+++ b/Documentation/install-doc-quick.sh
@@ -7,10 +7,10 @@ mandir="$2"
SUBDIRECTORY_OK=t
USAGE='<refname> <target directory>'
. git-sh-setup
-export GIT_DIR
+cd_to_toplevel
test -z "$mandir" && usage
-if ! git-rev-parse --verify "$head^0" >/dev/null; then
+if ! git rev-parse --verify "$head^0" >/dev/null; then
echo >&2 "head: $head does not exist in the current repository"
usage
fi
@@ -18,12 +18,14 @@ fi
GIT_INDEX_FILE=`pwd`/.quick-doc.index
export GIT_INDEX_FILE
rm -f "$GIT_INDEX_FILE"
-git-read-tree $head
-git-checkout-index -a -f --prefix="$mandir"/
+trap 'rm -f "$GIT_INDEX_FILE"' 0
+
+git read-tree $head
+git checkout-index -a -f --prefix="$mandir"/
if test -n "$GZ"; then
cd "$mandir"
- for i in `git-ls-tree -r --name-only $head`
+ for i in `git ls-tree -r --name-only $head`
do
gzip < $i > $i.gz && rm $i
done
diff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt
index 182cef5..d64c259 100644
--- a/Documentation/merge-options.txt
+++ b/Documentation/merge-options.txt
@@ -1,3 +1,7 @@
+--summary::
+ Show a diffstat at the end of the merge. The diffstat is also
+ controlled by the configuration option merge.diffstat.
+
-n, \--no-summary::
Do not show diffstat at the end of the merge.
@@ -21,4 +25,3 @@
If there is no `-s` option, a built-in list of strategies
is used instead (`git-merge-recursive` when merging a single
head, `git-merge-octopus` otherwise).
-
diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt
index d922e8e..0193c3c 100644
--- a/Documentation/pretty-formats.txt
+++ b/Documentation/pretty-formats.txt
@@ -106,12 +106,14 @@ The placeholders are:
- '%aD': author date, RFC2822 style
- '%ar': author date, relative
- '%at': author date, UNIX timestamp
+- '%ai': author date, ISO 8601 format
- '%cn': committer name
- '%ce': committer email
- '%cd': committer date
- '%cD': committer date, RFC2822 style
- '%cr': committer date, relative
- '%ct': committer date, UNIX timestamp
+- '%ci': committer date, ISO 8601 format
- '%e': encoding
- '%s': subject
- '%b': body
@@ -121,4 +123,3 @@ The placeholders are:
- '%Creset': reset color
- '%m': left, right or boundary mark
- '%n': newline
-
diff --git a/Documentation/pretty-options.txt b/Documentation/pretty-options.txt
index 7d515be..973d8dd 100644
--- a/Documentation/pretty-options.txt
+++ b/Documentation/pretty-options.txt
@@ -1,9 +1,18 @@
--pretty[='<format>']::
- Pretty print the contents of the commit logs in a given format,
+ Pretty-print the contents of the commit logs in a given format,
where '<format>' can be one of 'oneline', 'short', 'medium',
'full', 'fuller', 'email', 'raw' and 'format:<string>'.
- When left out the format default to 'medium'.
+ When omitted, the format defaults to 'medium'.
+
+--abbrev-commit::
+ Instead of showing the full 40-byte hexadecimal commit object
+ name, show only handful hexdigits prefix. Non default number of
+ digits can be specified with "--abbrev=<n>" (which also modifies
+ diff output, if it is displayed).
++
+This should make "--pretty=oneline" a whole lot more readable for
+people using 80-column terminals.
--encoding[=<encoding>]::
The commit objects record the encoding used for the log message
@@ -11,4 +20,3 @@
command to re-code the commit log message in the encoding
preferred by the user. For non plumbing commands this
defaults to UTF-8.
-
diff --git a/Documentation/pull-fetch-param.txt b/Documentation/pull-fetch-param.txt
index 8d4e950..b6eb7fc 100644
--- a/Documentation/pull-fetch-param.txt
+++ b/Documentation/pull-fetch-param.txt
@@ -58,7 +58,7 @@ is often useful.
+
Some short-cut notations are also supported.
+
-* `tag <tag>` means the same as `refs/tags/<tag>:refs/tags/<tag>`;
+* `tag <tag>` means the same as `refs/tags/<tag>:refs/tags/<tag>`;
it requests fetching everything up to the given tag.
* A parameter <ref> without a colon is equivalent to
<ref>: when pulling/fetching, so it merges <ref> into the current
diff --git a/Documentation/repository-layout.txt b/Documentation/repository-layout.txt
index 15221b5..4c92e37 100644
--- a/Documentation/repository-layout.txt
+++ b/Documentation/repository-layout.txt
@@ -177,4 +177,3 @@ shallow::
This is similar to `info/grafts` but is internally used
and maintained by shallow clone mechanism. See `--depth`
option to gitlink:git-clone[1] and gitlink:git-fetch[1].
-
diff --git a/Documentation/technical/pack-format.txt b/Documentation/technical/pack-format.txt
index 9ce3c47..e5b31c8 100644
--- a/Documentation/technical/pack-format.txt
+++ b/Documentation/technical/pack-format.txt
@@ -80,7 +80,7 @@ Pack Idx file:
+--------------------------------+ |
main | offset | |
index | object name 00XXXXXXXXXXXXXXXX | |
-table +--------------------------------+ |
+table +--------------------------------+ |
| offset | |
| object name 00XXXXXXXXXXXXXXXX | |
+--------------------------------+ |
@@ -97,14 +97,14 @@ trailer | | packfile checksum |
| +--------------------------------+
| | idxfile checksum |
| +--------------------------------+
- .-------.
+ .-------.
|
Pack file entry: <+
packed object header:
1-byte size extension bit (MSB)
type (next 3 bit)
- size0 (lower 4-bit)
+ size0 (lower 4-bit)
n-byte sizeN (as long as MSB is set, each 7-bit)
size0..sizeN form 4+7+7+..+7 bit integer, size0
is the least significant part, and sizeN is the
@@ -114,5 +114,5 @@ Pack file entry: <+
is the size before compression).
If it is DELTA, then
20-byte base object name SHA1 (the size above is the
- size of the delta data that follows).
+ size of the delta data that follows).
delta data, deflated.
diff --git a/Documentation/tutorial.txt b/Documentation/tutorial.txt
index 965ec00..bd9fbee 100644
--- a/Documentation/tutorial.txt
+++ b/Documentation/tutorial.txt
@@ -354,7 +354,7 @@ used for pulls:
-------------------------------------
$ git config --get remote.origin.url
-/home/bob/myrepo
+/home/alice/project
-------------------------------------
(The complete configuration created by git-clone is visible using
diff --git a/Documentation/urls-remotes.txt b/Documentation/urls-remotes.txt
new file mode 100644
index 0000000..5dd1f83
--- /dev/null
+++ b/Documentation/urls-remotes.txt
@@ -0,0 +1,55 @@
+include::urls.txt[]
+
+REMOTES
+-------
+
+In addition to the above, as a short-hand, the name of a
+file in `$GIT_DIR/remotes` directory can be given; the
+named file should be in the following format:
+
+------------
+ URL: one of the above URL format
+ Push: <refspec>
+ Pull: <refspec>
+
+------------
+
+Then such a short-hand is specified in place of
+<repository> without <refspec> parameters on the command
+line, <refspec> specified on `Push:` lines or `Pull:`
+lines are used for `git-push` and `git-fetch`/`git-pull`,
+respectively. Multiple `Push:` and `Pull:` lines may
+be specified for additional branch mappings.
+
+Or, equivalently, in the `$GIT_DIR/config` (note the use
+of `fetch` instead of `Pull:`):
+
+------------
+ [remote "<remote>"]
+ url = <url>
+ push = <refspec>
+ fetch = <refspec>
+
+------------
+
+The name of a file in `$GIT_DIR/branches` directory can be
+specified as an older notation short-hand; the named
+file should contain a single line, a URL in one of the
+above formats, optionally followed by a hash `#` and the
+name of remote head (URL fragment notation).
+`$GIT_DIR/branches/<remote>` file that stores a <url>
+without the fragment is equivalent to have this in the
+corresponding file in the `$GIT_DIR/remotes/` directory.
+
+------------
+ URL: <url>
+ Pull: refs/heads/master:<remote>
+
+------------
+
+while having `<url>#<head>` is equivalent to
+
+------------
+ URL: <url>
+ Pull: refs/heads/<head>:<remote>
+------------
diff --git a/Documentation/urls.txt b/Documentation/urls.txt
index 745f967..781df41 100644
--- a/Documentation/urls.txt
+++ b/Documentation/urls.txt
@@ -32,57 +32,3 @@ To sync with a local directory, use:
===============================================================
- /path/to/repo.git/
===============================================================
-
-REMOTES
--------
-
-In addition to the above, as a short-hand, the name of a
-file in `$GIT_DIR/remotes` directory can be given; the
-named file should be in the following format:
-
-------------
- URL: one of the above URL format
- Push: <refspec>
- Pull: <refspec>
-
-------------
-
-Then such a short-hand is specified in place of
-<repository> without <refspec> parameters on the command
-line, <refspec> specified on `Push:` lines or `Pull:`
-lines are used for `git-push` and `git-fetch`/`git-pull`,
-respectively. Multiple `Push:` and `Pull:` lines may
-be specified for additional branch mappings.
-
-Or, equivalently, in the `$GIT_DIR/config` (note the use
-of `fetch` instead of `Pull:`):
-
-------------
- [remote "<remote>"]
- url = <url>
- push = <refspec>
- fetch = <refspec>
-
-------------
-
-The name of a file in `$GIT_DIR/branches` directory can be
-specified as an older notation short-hand; the named
-file should contain a single line, a URL in one of the
-above formats, optionally followed by a hash `#` and the
-name of remote head (URL fragment notation).
-`$GIT_DIR/branches/<remote>` file that stores a <url>
-without the fragment is equivalent to have this in the
-corresponding file in the `$GIT_DIR/remotes/` directory.
-
-------------
- URL: <url>
- Pull: refs/heads/master:<remote>
-
-------------
-
-while having `<url>#<head>` is equivalent to
-
-------------
- URL: <url>
- Pull: refs/heads/<head>:<remote>
-------------
diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt
index d6caff4..f89952a 100644
--- a/Documentation/user-manual.txt
+++ b/Documentation/user-manual.txt
@@ -1,4 +1,4 @@
-Git User's Manual (for version 1.5.1 or newer)
+Git User's Manual (for version 1.5.3 or newer)
______________________________________________
@@ -154,11 +154,11 @@ Author: Jamal Hadi Salim <hadi@cyberus.ca>
Date: Sat Dec 2 22:22:25 2006 -0800
[XFRM]: Fix aevent structuring to be more complete.
-
+
aevents can not uniquely identify an SA. We break the ABI with this
patch, but consensus is that since it is not yet utilized by any
(known) application then it is fine (better do it now than later).
-
+
Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
Signed-off-by: David S. Miller <davem@davemloft.net>
@@ -167,7 +167,7 @@ index 8be626f..d7aac9d 100644
--- a/Documentation/networking/xfrm_sync.txt
+++ b/Documentation/networking/xfrm_sync.txt
@@ -47,10 +47,13 @@ aevent_id structure looks like:
-
+
struct xfrm_aevent_id {
struct xfrm_usersa_id sa_id;
+ xfrm_address_t saddr;
@@ -449,7 +449,7 @@ Exploring git history
Git is best thought of as a tool for storing the history of a
collection of files. It does this by storing compressed snapshots of
-the contents of a file heirarchy, together with "commits" which show
+the contents of a file hierarchy, together with "commits" which show
the relationships between these snapshots.
Git provides extremely flexible and fast tools for exploring the
@@ -1057,7 +1057,7 @@ $ git show
-------------------------------------------------
As a special shortcut,
-
+
-------------------------------------------------
$ git commit -a
-------------------------------------------------
@@ -1070,7 +1070,7 @@ about to commit:
-------------------------------------------------
$ git diff --cached # difference between HEAD and the index; what
- # would be commited if you ran "commit" now.
+ # would be committed if you ran "commit" now.
$ git diff # difference between the index file and your
# working directory; changes that would not
# be included if you ran "commit" now.
@@ -1079,6 +1079,11 @@ $ git diff HEAD # difference between HEAD and working tree; what
$ git status # a brief per-file summary of the above.
-------------------------------------------------
+You can also use gitlink:git-gui[1] to create commits, view changes in
+the index and the working tree files, and individually select diff hunks
+for inclusion in the index (by right-clicking on the diff hunk and
+choosing "Stage Hunk For Commit").
+
[[creating-good-commit-messages]]
Creating good commit messages
-----------------------------
@@ -1257,7 +1262,7 @@ index 802992c,2b60207..0000000
++>>>>>>> 77976da35a11db4580b80ae27e8d65caf5208086:file.txt
-------------------------------------------------
-Recall that the commit which will be commited after we resolve this
+Recall that the commit which will be committed after we resolve this
conflict will have two parents instead of the usual one: one parent
will be HEAD, the tip of the current branch; the other will be the
tip of the other branch, which is stored temporarily in MERGE_HEAD.
@@ -1351,7 +1356,7 @@ away, you can always return to the pre-merge state with
$ git reset --hard HEAD
-------------------------------------------------
-Or, if you've already commited the merge that you want to throw away,
+Or, if you've already committed the merge that you want to throw away,
-------------------------------------------------
$ git reset --hard ORIG_HEAD
@@ -1484,6 +1489,38 @@ $ git show HEAD^:path/to/file
which will display the given version of the file.
+[[interrupted-work]]
+Temporarily setting aside work in progress
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+While you are in the middle of working on something complicated, you
+find an unrelated but obvious and trivial bug. You would like to fix it
+before continuing. You can use gitlink:git-stash[1] to save the current
+state of your work, and after fixing the bug (or, optionally after doing
+so on a different branch and then coming back), unstash the
+work-in-progress changes.
+
+------------------------------------------------
+$ git stash "work in progress for foo feature"
+------------------------------------------------
+
+This command will save your changes away to the `stash`, and
+reset your working tree and the index to match the tip of your
+current branch. Then you can make your fix as usual.
+
+------------------------------------------------
+... edit and test ...
+$ git commit -a -m "blorpl: typofix"
+------------------------------------------------
+
+After that, you can go back to what you were working on with
+`git stash apply`:
+
+------------------------------------------------
+$ git stash apply
+------------------------------------------------
+
+
[[ensuring-good-performance]]
Ensuring good performance
-------------------------
@@ -1555,7 +1592,7 @@ history.
Fortunately, git also keeps a log, called a "reflog", of all the
previous values of each branch. So in this case you can still find the
-old history using, for example,
+old history using, for example,
-------------------------------------------------
$ git log master@{1}
@@ -1631,7 +1668,7 @@ If you decide you want the history back, you can always create a new
reference pointing to it, for example, a new branch:
------------------------------------------------
-$ git branch recovered-branch 7281251ddd
+$ git branch recovered-branch 7281251ddd
------------------------------------------------
Other types of dangling objects (blobs and trees) are also possible, and
@@ -1667,24 +1704,19 @@ one step:
$ git pull origin master
-------------------------------------------------
-In fact, "origin" is normally the default repository to pull from,
-and the default branch is normally the HEAD of the remote repository,
-so often you can accomplish the above with just
+In fact, if you have "master" checked out, then by default "git pull"
+merges from the HEAD branch of the origin repository. So often you can
+accomplish the above with just a simple
-------------------------------------------------
$ git pull
-------------------------------------------------
-See the descriptions of the branch.<name>.remote and branch.<name>.merge
-options in gitlink:git-config[1] to learn how to control these defaults
-depending on the current branch. Also note that the --track option to
-gitlink:git-branch[1] and gitlink:git-checkout[1] can be used to
-automatically set the default remote branch to pull from at the time
-that a branch is created:
-
--------------------------------------------------
-$ git checkout --track -b maint origin/maint
--------------------------------------------------
+More generally, a branch that is created from a remote branch will pull
+by default from that branch. See the descriptions of the
+branch.<name>.remote and branch.<name>.merge options in
+gitlink:git-config[1], and the discussion of the --track option in
+gitlink:git-checkout[1], to learn how to control these defaults.
In addition to saving you keystrokes, "git pull" also helps you by
producing a default commit message documenting the branch and
@@ -1803,7 +1835,7 @@ like this:
you push
your personal repo ------------------> your public repo
- ^ |
+ ^ |
| |
| you pull | they pull
| |
@@ -2377,7 +2409,7 @@ the result would create a new merge commit, like this:
\ \
a--b--c--m <-- mywork
................................................
-
+
However, if you prefer to keep the history in mywork a simple series of
commits without any merges, you may instead choose to use
gitlink:git-rebase[1]:
@@ -2479,8 +2511,10 @@ $ gitk origin..mywork &
And browse through the list of patches in the mywork branch using gitk,
applying them (possibly in a different order) to mywork-new using
-cherry-pick, and possibly modifying them as you go using commit
---amend.
+cherry-pick, and possibly modifying them as you go using commit --amend.
+The git-gui[1] command may also help as it allows you to individually
+select diff hunks for inclusion in the index (by right-clicking on the
+diff hunk and choosing "Stage Hunk for Commit").
Another technique is to use git-format-patch to create a series of
patches, then reset the state to before the patches:
@@ -2753,7 +2787,7 @@ must have at least one root, and while you can tie several different
root objects together into one project by creating a commit object which
has two or more separate roots as its ultimate parents, that's probably
just going to confuse people. So aim for the notion of "one root object
-per project", even if git itself does not enforce that.
+per project", even if git itself does not enforce that.
A <<def_tag_object,"tag" object>> symbolically identifies and can be
used to sign other objects. It contains the identifier and type of
@@ -2972,15 +3006,15 @@ cache, and the normal operation is to re-generate it completely from a
known tree object, or update/compare it with a live tree that is being
developed. If you blow the directory cache away entirely, you generally
haven't lost any information as long as you have the name of the tree
-that it described.
+that it described.
-At the same time, the index is at the same time also the
-staging area for creating new trees, and creating a new tree always
-involves a controlled modification of the index file. In particular,
-the index file can have the representation of an intermediate tree that
-has not yet been instantiated. So the index can be thought of as a
-write-back cache, which can contain dirty information that has not yet
-been written back to the backing store.
+At the same time, the index is also the staging area for creating
+new trees, and creating a new tree always involves a controlled
+modification of the index file. In particular, the index file can
+have the representation of an intermediate tree that has not yet been
+instantiated. So the index can be thought of as a write-back cache,
+which can contain dirty information that has not yet been written back
+to the backing store.
@@ -2992,7 +3026,7 @@ Generally, all "git" operations work on the index file. Some operations
work *purely* on the index file (showing the current state of the
index), but most operations move data to and from the index file. Either
from the database or from the working directory. Thus there are four
-main combinations:
+main combinations:
[[working-directory-to-index]]
working directory -> index
@@ -3455,7 +3489,7 @@ because you interrupted a "git fetch" with ^C or something like that,
leaving _some_ of the new objects in the object database, but just
dangling and useless.
-Anyway, once you are sure that you're not interested in any dangling
+Anyway, once you are sure that you're not interested in any dangling
state, you can just prune all unreachable objects:
------------------------------------------------
@@ -3466,12 +3500,12 @@ and they'll be gone. But you should only run "git prune" on a quiescent
repository - it's kind of like doing a filesystem fsck recovery: you
don't want to do that while the filesystem is mounted.
-(The same is true of "git-fsck" itself, btw - but since
-git-fsck never actually *changes* the repository, it just reports
-on what it found, git-fsck itself is never "dangerous" to run.
-Running it while somebody is actually changing the repository can cause
-confusing and scary messages, but it won't actually do anything bad. In
-contrast, running "git prune" while somebody is actively changing the
+(The same is true of "git-fsck" itself, btw - but since
+git-fsck never actually *changes* the repository, it just reports
+on what it found, git-fsck itself is never "dangerous" to run.
+Running it while somebody is actually changing the repository can cause
+confusing and scary messages, but it won't actually do anything bad. In
+contrast, running "git prune" while somebody is actively changing the
repository is a *BAD* idea).
[[birdview-on-the-source-code]]
diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN
index a318baa..3c0032c 100755
--- a/GIT-VERSION-GEN
+++ b/GIT-VERSION-GEN
@@ -1,7 +1,7 @@
#!/bin/sh
GVF=GIT-VERSION-FILE
-DEF_VER=v1.5.2.4.GIT
+DEF_VER=v1.5.3.GIT
LF='
'
diff --git a/INSTALL b/INSTALL
index 361c65b..c62b12c 100644
--- a/INSTALL
+++ b/INSTALL
@@ -31,7 +31,7 @@ Issues of note:
interactive tools. None of the core git stuff needs the wrapper,
it's just a convenient shorthand and while it is documented in some
places, you can always replace "git commit" with "git-commit"
- instead.
+ instead.
But let's face it, most of us don't have GNU interactive tools, and
even if we had it, we wouldn't know what it does. I don't think it
@@ -56,9 +56,8 @@ Issues of note:
- "zlib", the compression library. Git won't build without it.
- - "openssl". The git-rev-list program uses bignum support from
- openssl, and unless you specify otherwise, you'll also get the
- SHA1 library from here.
+ - "openssl". Unless you specify otherwise, you'll get the SHA1
+ library from here.
If you don't have openssl, you can use one of the SHA1 libraries
that come with git (git includes the one from Mozilla, and has
@@ -73,7 +72,7 @@ Issues of note:
management over DAV. Similar to "curl" above, this is optional.
- "wish", the Tcl/Tk windowing shell is used in gitk to show the
- history graphically
+ history graphically, and in git-gui.
- "ssh" is used to push and pull over the net
@@ -89,10 +88,16 @@ Issues of note:
will include them. Note that config.mak is not distributed;
the name is reserved for local settings.
- - To build and install documentation suite, you need to have the
- asciidoc/xmlto toolchain. Alternatively, pre-formatted
- documentation are available in "html" and "man" branches of the git
- repository itself. For example, you could:
+ - To build and install documentation suite, you need to have
+ the asciidoc/xmlto toolchain. Because not many people are
+ inclined to install the tools, the default build target
+ ("make all") does _not_ build them. The documentation is
+ written for AsciiDoc 7, but "make ASCIIDOC8=YesPlease doc"
+ will let you format with AsciiDoc 8.
+
+ Alternatively, pre-formatted documentation are available in
+ "html" and "man" branches of the git repository itself. For
+ example, you could:
$ mkdir manual && cd manual
$ git init
@@ -112,3 +117,6 @@ Issues of note:
http://www.kernel.org/pub/software/scm/git/docs/
+ 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
+ the patch in contrib/patches/docbook-xsl-manpages-charmap.patch
diff --git a/Makefile b/Makefile
index eb443bd..2f3b9b2 100644
--- a/Makefile
+++ b/Makefile
@@ -112,8 +112,6 @@ all::
# Define NO_PERL_MAKEMAKER if you cannot use Makefiles generated by perl's
# MakeMaker (e.g. using ActiveState under Cygwin).
#
-# Define WITH_P4IMPORT to build and install Python git-p4import script.
-#
# Define NO_TCLTK if you do not want Tcl/Tk GUI.
#
# The TCL_PATH variable governs the location of the Tcl interpreter
@@ -146,13 +144,14 @@ STRIP ?= strip
prefix = $(HOME)
bindir = $(prefix)/bin
gitexecdir = $(bindir)
-sharedir = $(prefix)/share/
-template_dir = $(sharedir)/git-core/templates/
+sharedir = $(prefix)/share
+template_dir = $(sharedir)/git-core/templates
ifeq ($(prefix),/usr)
sysconfdir = /etc
else
sysconfdir = $(prefix)/etc
endif
+lib = lib
ETC_GITCONFIG = $(sysconfdir)/gitconfig
# DESTDIR=
@@ -176,7 +175,9 @@ export prefix bindir gitexecdir sharedir template_dir sysconfdir
CC = gcc
AR = ar
+RM = rm -f
TAR = tar
+FIND = find
INSTALL = install
RPMBUILD = rpmbuild
TCL_PATH = tclsh
@@ -204,14 +205,16 @@ SCRIPT_SH = \
git-fetch.sh \
git-ls-remote.sh \
git-merge-one-file.sh git-mergetool.sh git-parse-remote.sh \
- git-pull.sh git-rebase.sh \
+ git-pull.sh git-rebase.sh git-rebase--interactive.sh \
git-repack.sh git-request-pull.sh git-reset.sh \
git-sh-setup.sh \
git-tag.sh git-verify-tag.sh \
- git-applymbox.sh git-applypatch.sh git-am.sh \
+ git-am.sh \
git-merge.sh git-merge-stupid.sh git-merge-octopus.sh \
git-merge-resolve.sh git-merge-ours.sh \
- git-lost-found.sh git-quiltimport.sh
+ git-lost-found.sh git-quiltimport.sh git-submodule.sh \
+ git-filter-branch.sh \
+ git-stash.sh
SCRIPT_PERL = \
git-add--interactive.perl \
@@ -220,27 +223,15 @@ SCRIPT_PERL = \
git-svnimport.perl git-cvsexportcommit.perl \
git-send-email.perl git-svn.perl
-SCRIPT_PYTHON = \
- git-p4import.py
-
-ifdef WITH_P4IMPORT
-SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \
- $(patsubst %.perl,%,$(SCRIPT_PERL)) \
- $(patsubst %.py,%,$(SCRIPT_PYTHON)) \
- git-status git-instaweb
-else
SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \
$(patsubst %.perl,%,$(SCRIPT_PERL)) \
git-status git-instaweb
-endif
-
# ... and all the rest that could be moved out of bindir to gitexecdir
PROGRAMS = \
git-convert-objects$X git-fetch-pack$X \
git-hash-object$X git-index-pack$X git-local-fetch$X \
git-fast-import$X \
- git-merge-base$X \
git-daemon$X \
git-merge-index$X git-mktag$X git-mktree$X git-patch-id$X \
git-peek-remote$X git-receive-pack$X \
@@ -284,9 +275,6 @@ endif
ifndef PERL_PATH
PERL_PATH = /usr/bin/perl
endif
-ifndef PYTHON_PATH
- PYTHON_PATH = /usr/local/bin/python
-endif
export PERL_PATH
@@ -298,7 +286,8 @@ LIB_H = \
diff.h object.h pack.h pkt-line.h quote.h refs.h list-objects.h sideband.h \
run-command.h strbuf.h tag.h tree.h git-compat-util.h revision.h \
tree-walk.h log-tree.h dir.h path-list.h unpack-trees.h builtin.h \
- utf8.h reflog-walk.h patch-ids.h attr.h decorate.h progress.h mailmap.h
+ utf8.h reflog-walk.h patch-ids.h attr.h decorate.h progress.h \
+ mailmap.h remote.h
DIFF_OBJS = \
diff.o diff-lib.o diffcore-break.o diffcore-order.o \
@@ -320,7 +309,7 @@ LIB_OBJS = \
write_or_die.o trace.o list-objects.o grep.o match-trees.o \
alloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS) \
color.o wt-status.o archive-zip.o archive-tar.o shallow.o utf8.o \
- convert.o attr.o decorate.o progress.o mailmap.o symlinks.o
+ convert.o attr.o decorate.o progress.o mailmap.o symlinks.o remote.o
BUILTIN_OBJS = \
builtin-add.o \
@@ -385,7 +374,7 @@ BUILTIN_OBJS = \
builtin-pack-refs.o
GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
-EXTLIBS = -lz
+EXTLIBS =
#
# Platform specific tweaks
@@ -469,6 +458,10 @@ ifeq ($(uname_S),AIX)
NO_STRLCPY = YesPlease
NEEDS_LIBICONV=YesPlease
endif
+ifeq ($(uname_S),GNU)
+ # GNU/Hurd
+ NO_STRLCPY=YesPlease
+endif
ifeq ($(uname_S),IRIX64)
NO_IPV6=YesPlease
NO_SETENV=YesPlease
@@ -512,9 +505,9 @@ endif
ifndef NO_CURL
ifdef CURLDIR
- # Try "-Wl,-rpath=$(CURLDIR)/lib" in such a case.
+ # Try "-Wl,-rpath=$(CURLDIR)/$(lib)" in such a case.
BASIC_CFLAGS += -I$(CURLDIR)/include
- CURL_LIBCURL = -L$(CURLDIR)/lib $(CC_LD_DYNPATH)$(CURLDIR)/lib -lcurl
+ CURL_LIBCURL = -L$(CURLDIR)/$(lib) $(CC_LD_DYNPATH)$(CURLDIR)/$(lib) -lcurl
else
CURL_LIBCURL = -lcurl
endif
@@ -530,11 +523,17 @@ ifndef NO_CURL
endif
endif
+ifdef ZLIB_PATH
+ BASIC_CFLAGS += -I$(ZLIB_PATH)/include
+ EXTLIBS += -L$(ZLIB_PATH)/$(lib) $(CC_LD_DYNPATH)$(ZLIB_PATH)/$(lib)
+endif
+EXTLIBS += -lz
+
ifndef NO_OPENSSL
OPENSSL_LIBSSL = -lssl
ifdef OPENSSLDIR
BASIC_CFLAGS += -I$(OPENSSLDIR)/include
- OPENSSL_LINK = -L$(OPENSSLDIR)/lib $(CC_LD_DYNPATH)$(OPENSSLDIR)/lib
+ OPENSSL_LINK = -L$(OPENSSLDIR)/$(lib) $(CC_LD_DYNPATH)$(OPENSSLDIR)/$(lib)
else
OPENSSL_LINK =
endif
@@ -551,7 +550,7 @@ endif
ifdef NEEDS_LIBICONV
ifdef ICONVDIR
BASIC_CFLAGS += -I$(ICONVDIR)/include
- ICONV_LINK = -L$(ICONVDIR)/lib $(CC_LD_DYNPATH)$(ICONVDIR)/lib
+ ICONV_LINK = -L$(ICONVDIR)/$(lib) $(CC_LD_DYNPATH)$(ICONVDIR)/$(lib)
else
ICONV_LINK =
endif
@@ -708,7 +707,6 @@ prefix_SQ = $(subst ','\'',$(prefix))
SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH))
-PYTHON_PATH_SQ = $(subst ','\'',$(PYTHON_PATH))
TCLTK_PATH_SQ = $(subst ','\'',$(TCLTK_PATH))
LIBS = $(GITLIBS) $(EXTLIBS)
@@ -727,7 +725,7 @@ export TAR INSTALL DESTDIR SHELL_PATH
all:: $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS)
ifneq (,$X)
- $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), rm -f '$p';)
+ $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), $(RM) '$p';)
endif
all::
@@ -741,29 +739,34 @@ strip: $(PROGRAMS) git$X
$(STRIP) $(STRIP_OPTS) $(PROGRAMS) git$X
gitk-wish: gitk GIT-GUI-VARS
- $(QUIET_GEN)rm -f $@ $@+ && \
+ $(QUIET_GEN)$(RM) $@ $@+ && \
sed -e '1,3s|^exec .* "$$0"|exec $(subst |,'\|',$(TCLTK_PATH_SQ)) "$$0"|' <gitk >$@+ && \
chmod +x $@+ && \
mv -f $@+ $@
-git$X: git.c common-cmds.h $(BUILTIN_OBJS) $(GITLIBS) GIT-CFLAGS
- $(QUIET_LINK)$(CC) -DGIT_VERSION='"$(GIT_VERSION)"' \
- $(ALL_CFLAGS) -o $@ $(filter %.c,$^) \
+git.o: git.c common-cmds.h GIT-CFLAGS
+ $(QUIET_CC)$(CC) -DGIT_VERSION='"$(GIT_VERSION)"' \
+ $(ALL_CFLAGS) -c $(filter %.c,$^)
+
+git$X: git.o $(BUILTIN_OBJS) $(GITLIBS)
+ $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ git.o \
$(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS)
help.o: common-cmds.h
git-merge-subtree$X: git-merge-recursive$X
- $(QUIET_BUILT_IN)rm -f $@ && ln git-merge-recursive$X $@
+ $(QUIET_BUILT_IN)$(RM) $@ && ln git-merge-recursive$X $@
$(BUILT_INS): git$X
- $(QUIET_BUILT_IN)rm -f $@ && ln git$X $@
+ $(QUIET_BUILT_IN)$(RM) $@ && ln git$X $@
+
+common-cmds.h: ./generate-cmdlist.sh
common-cmds.h: $(wildcard Documentation/git-*.txt)
$(QUIET_GEN)./generate-cmdlist.sh > $@+ && mv $@+ $@
$(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
- $(QUIET_GEN)rm -f $@ $@+ && \
+ $(QUIET_GEN)$(RM) $@ $@+ && \
sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
-e 's|@@PERL@@|$(PERL_PATH_SQ)|g' \
-e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
@@ -774,20 +777,11 @@ $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
$(patsubst %.perl,%,$(SCRIPT_PERL)): perl/perl.mak
-$(patsubst %.py,%,$(SCRIPT_PYTHON)) : % : %.py
- rm -f $@ $@+
- sed -e '1s|#!.*/python|#!$(PYTHON_PATH_SQ)|' \
- -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
- -e 's/@@NO_CURL@@/$(NO_CURL)/g' \
- $@.py >$@+
- chmod +x $@+
- mv $@+ $@
-
perl/perl.mak: GIT-CFLAGS
$(QUIET_SUBDIR0)perl $(QUIET_SUBDIR1) PERL_PATH='$(PERL_PATH_SQ)' prefix='$(prefix_SQ)' $(@F)
$(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl
- $(QUIET_GEN)rm -f $@ $@+ && \
+ $(QUIET_GEN)$(RM) $@ $@+ && \
INSTLIBDIR=`$(MAKE) -C perl -s --no-print-directory instlibdir` && \
sed -e '1{' \
-e ' s|#!.*perl|#!$(PERL_PATH_SQ)|' \
@@ -806,7 +800,7 @@ git-status: git-commit
$(QUIET_GEN)cp $< $@+ && mv $@+ $@
gitweb/gitweb.cgi: gitweb/gitweb.perl
- $(QUIET_GEN)rm -f $@ $@+ && \
+ $(QUIET_GEN)$(RM) $@ $@+ && \
sed -e '1s|#!.*perl|#!$(PERL_PATH_SQ)|' \
-e 's|++GIT_VERSION++|$(GIT_VERSION)|g' \
-e 's|++GIT_BINDIR++|$(bindir)|g' \
@@ -829,7 +823,7 @@ gitweb/gitweb.cgi: gitweb/gitweb.perl
mv $@+ $@
git-instaweb: git-instaweb.sh gitweb/gitweb.cgi gitweb/gitweb.css
- $(QUIET_GEN)rm -f $@ $@+ && \
+ $(QUIET_GEN)$(RM) $@ $@+ && \
sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
-e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
-e 's/@@NO_CURL@@/$(NO_CURL)/g' \
@@ -842,20 +836,22 @@ git-instaweb: git-instaweb.sh gitweb/gitweb.cgi gitweb/gitweb.css
mv $@+ $@
configure: configure.ac
- $(QUIET_GEN)rm -f $@ $<+ && \
+ $(QUIET_GEN)$(RM) $@ $<+ && \
sed -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
$< > $<+ && \
autoconf -o $@ $<+ && \
- rm -f $<+
+ $(RM) $<+
# These can record GIT_VERSION
-git$X git.spec \
+git.o git.spec \
$(patsubst %.sh,%,$(SCRIPT_SH)) \
$(patsubst %.perl,%,$(SCRIPT_PERL)) \
: GIT-VERSION-FILE
%.o: %.c GIT-CFLAGS
$(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) $<
+%.s: %.c GIT-CFLAGS
+ $(QUIET_CC)$(CC) -S $(ALL_CFLAGS) $<
%.o: %.S
$(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) $<
@@ -899,7 +895,7 @@ $(patsubst git-%$X,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)
$(DIFF_OBJS): diffcore.h
$(LIB_FILE): $(LIB_OBJS)
- $(QUIET_AR)rm -f $@ && $(AR) rcs $@ $(LIB_OBJS)
+ $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIB_OBJS)
XDIFF_OBJS=xdiff/xdiffi.o xdiff/xprepare.o xdiff/xutils.o xdiff/xemit.o \
xdiff/xmerge.o
@@ -907,7 +903,7 @@ $(XDIFF_OBJS): xdiff/xinclude.h xdiff/xmacros.h xdiff/xdiff.h xdiff/xtypes.h \
xdiff/xutils.h xdiff/xprepare.h xdiff/xdiffi.h xdiff/xemit.h
$(XDIFF_LIB): $(XDIFF_OBJS)
- $(QUIET_AR)rm -f $@ && $(AR) rcs $@ $(XDIFF_OBJS)
+ $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(XDIFF_OBJS)
perl/Makefile: perl/Git.pm perl/Makefile.PL GIT-CFLAGS
@@ -918,12 +914,12 @@ doc:
$(MAKE) -C Documentation all
TAGS:
- rm -f TAGS
- find . -name '*.[hcS]' -print | xargs etags -a
+ $(RM) TAGS
+ $(FIND) . -name '*.[hcS]' -print | xargs etags -a
tags:
- rm -f tags
- find . -name '*.[hcS]' -print | xargs ctags -a
+ $(RM) tags
+ $(FIND) . -name '*.[hcS]' -print | xargs ctags -a
### Detect prefix changes
TRACK_CFLAGS = $(subst ','\'',$(ALL_CFLAGS)):\
@@ -952,7 +948,7 @@ endif
### Testing rules
-TEST_PROGRAMS = test-chmtime$X test-genrandom$X
+TEST_PROGRAMS = test-chmtime$X test-genrandom$X test-date$X test-delta$X test-sha1$X test-match-trees$X test-absolute-path$X
all:: $(TEST_PROGRAMS)
@@ -965,26 +961,12 @@ export NO_SVN_TESTS
test: all
$(MAKE) -C t/ all
-test-date$X: test-date.c date.o ctype.o
- $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) test-date.c date.o ctype.o
+test-date$X: date.o ctype.o
-test-delta$X: test-delta.o diff-delta.o patch-delta.o $(GITLIBS)
- $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
+test-delta$X: diff-delta.o patch-delta.o
-test-dump-cache-tree$X: dump-cache-tree.o $(GITLIBS)
- $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
-
-test-sha1$X: test-sha1.o $(GITLIBS)
- $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
-
-test-match-trees$X: test-match-trees.o $(GITLIBS)
- $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
-
-test-chmtime$X: test-chmtime.c
- $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $<
-
-test-genrandom$X: test-genrandom.c
- $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $<
+test-%$X: test-%.o $(GITLIBS)
+ $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
check-sha1:: test-sha1$X
./test-sha1.sh
@@ -992,7 +974,8 @@ check-sha1:: test-sha1$X
check: common-cmds.h
for i in *.c; do sparse $(ALL_CFLAGS) $(SPARSE_FLAGS) $$i || exit; done
-
+remove-dashes:
+ ./fixup-builtins $(BUILT_INS)
### Installation rules
@@ -1014,9 +997,9 @@ endif
cp '$(DESTDIR_SQ)$(bindir_SQ)/git$X' \
'$(DESTDIR_SQ)$(gitexecdir_SQ)/git$X'; \
fi
- $(foreach p,$(BUILT_INS), rm -f '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' && ln '$(DESTDIR_SQ)$(gitexecdir_SQ)/git$X' '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' ;)
+ $(foreach p,$(BUILT_INS), $(RM) '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' && ln '$(DESTDIR_SQ)$(gitexecdir_SQ)/git$X' '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' ;)
ifneq (,$X)
- $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), rm -f '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p';)
+ $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), $(RM) '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p';)
endif
install-doc:
@@ -1034,18 +1017,19 @@ git.spec: git.spec.in
mv $@+ $@
GIT_TARNAME=git-$(GIT_VERSION)
-dist: git.spec git-archive
+dist: git.spec git-archive configure
./git-archive --format=tar \
--prefix=$(GIT_TARNAME)/ HEAD^{tree} > $(GIT_TARNAME).tar
@mkdir -p $(GIT_TARNAME)
- @cp git.spec $(GIT_TARNAME)
+ @cp git.spec configure $(GIT_TARNAME)
@echo $(GIT_VERSION) > $(GIT_TARNAME)/version
@$(MAKE) -C git-gui TARDIR=../$(GIT_TARNAME)/git-gui dist-version
$(TAR) rf $(GIT_TARNAME).tar \
$(GIT_TARNAME)/git.spec \
+ $(GIT_TARNAME)/configure \
$(GIT_TARNAME)/version \
$(GIT_TARNAME)/git-gui/version
- @rm -rf $(GIT_TARNAME)
+ @$(RM) -r $(GIT_TARNAME)
gzip -f -9 $(GIT_TARNAME).tar
rpm: dist
@@ -1054,13 +1038,13 @@ rpm: dist
htmldocs = git-htmldocs-$(GIT_VERSION)
manpages = git-manpages-$(GIT_VERSION)
dist-doc:
- rm -fr .doc-tmp-dir
+ $(RM) -r .doc-tmp-dir
mkdir .doc-tmp-dir
$(MAKE) -C Documentation WEBDOC_DEST=../.doc-tmp-dir install-webdoc
cd .doc-tmp-dir && $(TAR) cf ../$(htmldocs).tar .
gzip -n -9 -f $(htmldocs).tar
:
- rm -fr .doc-tmp-dir
+ $(RM) -r .doc-tmp-dir
mkdir -p .doc-tmp-dir/man1 .doc-tmp-dir/man5 .doc-tmp-dir/man7
$(MAKE) -C Documentation DESTDIR=./ \
man1dir=../.doc-tmp-dir/man1 \
@@ -1069,30 +1053,31 @@ dist-doc:
install
cd .doc-tmp-dir && $(TAR) cf ../$(manpages).tar .
gzip -n -9 -f $(manpages).tar
- rm -fr .doc-tmp-dir
+ $(RM) -r .doc-tmp-dir
### Cleaning rules
clean:
- rm -f *.o mozilla-sha1/*.o arm/*.o ppc/*.o compat/*.o xdiff/*.o \
- test-chmtime$X test-genrandom$X $(LIB_FILE) $(XDIFF_LIB)
- rm -f $(ALL_PROGRAMS) $(BUILT_INS) git$X
- rm -f *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags
- rm -rf autom4te.cache
- rm -f configure config.log config.mak.autogen config.mak.append config.status config.cache
- rm -rf $(GIT_TARNAME) .doc-tmp-dir
- rm -f $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz
- rm -f $(htmldocs).tar.gz $(manpages).tar.gz
- rm -f gitweb/gitweb.cgi
+ $(RM) *.o mozilla-sha1/*.o arm/*.o ppc/*.o compat/*.o xdiff/*.o \
+ $(LIB_FILE) $(XDIFF_LIB)
+ $(RM) $(ALL_PROGRAMS) $(BUILT_INS) git$X
+ $(RM) $(TEST_PROGRAMS)
+ $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags
+ $(RM) -r autom4te.cache
+ $(RM) configure config.log config.mak.autogen config.mak.append config.status config.cache
+ $(RM) -r $(GIT_TARNAME) .doc-tmp-dir
+ $(RM) $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz
+ $(RM) $(htmldocs).tar.gz $(manpages).tar.gz
+ $(RM) gitweb/gitweb.cgi
$(MAKE) -C Documentation/ clean
$(MAKE) -C perl clean
$(MAKE) -C templates/ clean
$(MAKE) -C t/ clean
ifndef NO_TCLTK
- rm -f gitk-wish
+ $(RM) gitk-wish
$(MAKE) -C git-gui clean
endif
- rm -f GIT-VERSION-FILE GIT-CFLAGS GIT-GUI-VARS
+ $(RM) GIT-VERSION-FILE GIT-CFLAGS GIT-GUI-VARS
.PHONY: all install clean strip
.PHONY: .FORCE-GIT-VERSION-FILE TAGS tags .FORCE-GIT-CFLAGS
diff --git a/RelNotes b/RelNotes
index 1f6c16e..0de5e66 120000
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes-1.5.2.4.txt \ No newline at end of file
+Documentation/RelNotes-1.5.3.txt \ No newline at end of file
diff --git a/archive-tar.c b/archive-tar.c
index 33e7657..66fe3e3 100644
--- a/archive-tar.c
+++ b/archive-tar.c
@@ -167,7 +167,7 @@ static void write_entry(const unsigned char *sha1, struct strbuf *path,
} else {
if (verbose)
fprintf(stderr, "%.*s\n", path->len, path->buf);
- if (S_ISDIR(mode) || S_ISDIRLNK(mode)) {
+ if (S_ISDIR(mode) || S_ISGITLINK(mode)) {
*header.typeflag = TYPEFLAG_DIR;
mode = (mode | 0777) & ~tar_umask;
} else if (S_ISLNK(mode)) {
@@ -280,7 +280,7 @@ static int write_tar_entry(const unsigned char *sha1,
memcpy(path.buf + baselen, filename, filenamelen);
path.len = baselen + filenamelen;
path.buf[path.len] = '\0';
- if (S_ISDIR(mode) || S_ISDIRLNK(mode)) {
+ if (S_ISDIR(mode) || S_ISGITLINK(mode)) {
strbuf_append_string(&path, "/");
buffer = NULL;
size = 0;
diff --git a/archive-zip.c b/archive-zip.c
index 3cbf6bb..444e162 100644
--- a/archive-zip.c
+++ b/archive-zip.c
@@ -182,7 +182,7 @@ static int write_zip_entry(const unsigned char *sha1,
goto out;
}
- if (S_ISDIR(mode) || S_ISDIRLNK(mode)) {
+ if (S_ISDIR(mode) || S_ISGITLINK(mode)) {
method = 0;
attr2 = 16;
result = (S_ISDIR(mode) ? READ_TREE_RECURSIVE : 0);
diff --git a/arm/sha1.c b/arm/sha1.c
index 11b1a04..9e3ae03 100644
--- a/arm/sha1.c
+++ b/arm/sha1.c
@@ -49,7 +49,7 @@ void SHA1_Update(SHA_CTX *c, const void *p, unsigned long n)
void SHA1_Final(unsigned char *hash, SHA_CTX *c)
{
uint64_t bitlen;
- uint32_t bitlen_hi, bitlen_lo;
+ uint32_t bitlen_hi, bitlen_lo;
unsigned int i, offset, padlen;
unsigned char bits[8];
static const unsigned char padding[64] = { 0x80, };
@@ -69,7 +69,7 @@ void SHA1_Final(unsigned char *hash, SHA_CTX *c)
bits[5] = bitlen_lo >> 16;
bits[6] = bitlen_lo >> 8;
bits[7] = bitlen_lo;
- SHA1_Update(c, bits, 8);
+ SHA1_Update(c, bits, 8);
for (i = 0; i < 5; i++) {
uint32_t v = c->hash[i];
diff --git a/arm/sha1_arm.S b/arm/sha1_arm.S
index a328b73..8c1cb99 100644
--- a/arm/sha1_arm.S
+++ b/arm/sha1_arm.S
@@ -181,4 +181,3 @@ sha_transform:
.L_sha_K:
.word 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6
-
diff --git a/builtin-add.c b/builtin-add.c
index 1591171..de5c108 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -40,42 +40,29 @@ static void prune_directory(struct dir_struct *dir, const char **pathspec, int p
dir->nr = dst - dir->entries;
for (i = 0; i < specs; i++) {
- struct stat st;
- const char *match;
- if (seen[i])
- continue;
-
- match = pathspec[i];
- if (!match[0])
- continue;
-
- /* Existing file? We must have ignored it */
- if (!lstat(match, &st)) {
- struct dir_entry *ent;
-
- ent = dir_add_name(dir, match, strlen(match));
- ent->ignored = 1;
- if (S_ISDIR(st.st_mode))
- ent->ignored_dir = 1;
- continue;
- }
- die("pathspec '%s' did not match any files", match);
+ if (!seen[i] && !file_exists(pathspec[i]))
+ die("pathspec '%s' did not match any files",
+ pathspec[i]);
}
}
-static void fill_directory(struct dir_struct *dir, const char **pathspec)
+static void fill_directory(struct dir_struct *dir, const char **pathspec,
+ int ignored_too)
{
const char *path, *base;
int baselen;
/* Set up the default git porcelain excludes */
memset(dir, 0, sizeof(*dir));
- dir->exclude_per_dir = ".gitignore";
- path = git_path("info/exclude");
- if (!access(path, R_OK))
- add_excludes_from_file(dir, path);
- if (!access(excludes_file, R_OK))
- add_excludes_from_file(dir, excludes_file);
+ if (!ignored_too) {
+ dir->collect_ignored = 1;
+ dir->exclude_per_dir = ".gitignore";
+ path = git_path("info/exclude");
+ if (!access(path, R_OK))
+ add_excludes_from_file(dir, path);
+ if (excludes_file != NULL && !access(excludes_file, R_OK))
+ add_excludes_from_file(dir, excludes_file);
+ }
/*
* Calculate common prefix for the pathspec, and
@@ -219,13 +206,11 @@ int cmd_add(int argc, const char **argv, const char *prefix)
}
pathspec = get_pathspec(prefix, argv + i);
- fill_directory(&dir, pathspec);
+ fill_directory(&dir, pathspec, ignored_too);
if (show_only) {
const char *sep = "", *eof = "";
for (i = 0; i < dir.nr; i++) {
- if (!ignored_too && dir.entries[i]->ignored)
- continue;
printf("%s%s", sep, dir.entries[i]->name);
sep = " ";
eof = "\n";
@@ -237,25 +222,13 @@ int cmd_add(int argc, const char **argv, const char *prefix)
if (read_cache() < 0)
die("index file corrupt");
- if (!ignored_too) {
- int has_ignored = 0;
- for (i = 0; i < dir.nr; i++)
- if (dir.entries[i]->ignored)
- has_ignored = 1;
- if (has_ignored) {
- fprintf(stderr, ignore_warning);
- for (i = 0; i < dir.nr; i++) {
- if (!dir.entries[i]->ignored)
- continue;
- fprintf(stderr, "%s", dir.entries[i]->name);
- if (dir.entries[i]->ignored_dir)
- fprintf(stderr, " (directory)");
- fputc('\n', stderr);
- }
- fprintf(stderr,
- "Use -f if you really want to add them.\n");
- exit(1);
+ if (dir.ignored_nr) {
+ fprintf(stderr, ignore_warning);
+ for (i = 0; i < dir.ignored_nr; i++) {
+ fprintf(stderr, "%s\n", dir.ignored[i]->name);
}
+ fprintf(stderr, "Use -f if you really want to add them.\n");
+ exit(1);
}
for (i = 0; i < dir.nr; i++)
diff --git a/builtin-annotate.c b/builtin-annotate.c
index 9db7cfe..fc43eed 100644
--- a/builtin-annotate.c
+++ b/builtin-annotate.c
@@ -22,4 +22,3 @@ int cmd_annotate(int argc, const char **argv, const char *prefix)
return cmd_blame(argc + 1, nargv, prefix);
}
-
diff --git a/builtin-apply.c b/builtin-apply.c
index 9ee9393..da27075 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -55,7 +55,7 @@ static enum whitespace_eol {
} new_whitespace = warn_on_whitespace;
static int whitespace_error;
static int squelch_whitespace_errors = 5;
-static int applied_after_stripping;
+static int applied_after_fixing_ws;
static const char *patch_input_file;
static void parse_whitespace_option(const char *option)
@@ -1661,7 +1661,7 @@ static int apply_line(char *output, const char *patch, int plen)
if (add_nl_to_tail)
output[plen++] = '\n';
if (fixed)
- applied_after_stripping++;
+ applied_after_fixing_ws++;
return output + plen - buf;
}
@@ -1675,6 +1675,7 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i
char *new = xmalloc(size);
const char *oldlines, *newlines;
int oldsize = 0, newsize = 0;
+ int new_blank_lines_at_end = 0;
unsigned long leading, trailing;
int pos, lines;
@@ -1682,6 +1683,7 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i
char first;
int len = linelen(patch, size);
int plen;
+ int added_blank_line = 0;
if (!len)
break;
@@ -1703,6 +1705,7 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i
else if (first == '+')
first = '-';
}
+
switch (first) {
case '\n':
/* Newer GNU diff, empty context line */
@@ -1720,9 +1723,14 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i
break;
/* Fall-through for ' ' */
case '+':
- if (first != '+' || !no_add)
- newsize += apply_line(new + newsize, patch,
- plen);
+ if (first != '+' || !no_add) {
+ int added = apply_line(new + newsize, patch,
+ plen);
+ newsize += added;
+ if (first == '+' &&
+ added == 1 && new[newsize-1] == '\n')
+ added_blank_line = 1;
+ }
break;
case '@': case '\\':
/* Ignore it, we already handled it */
@@ -1732,6 +1740,10 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i
error("invalid start of line: '%c'", first);
return -1;
}
+ if (added_blank_line)
+ new_blank_lines_at_end++;
+ else
+ new_blank_lines_at_end = 0;
patch += len;
size -= len;
}
@@ -1774,9 +1786,16 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i
if (match_beginning && offset)
offset = -1;
if (offset >= 0) {
- int diff = newsize - oldsize;
- unsigned long size = desc->size + diff;
- unsigned long alloc = desc->alloc;
+ int diff;
+ unsigned long size, alloc;
+
+ if (new_whitespace == strip_whitespace &&
+ (desc->size - oldsize - offset == 0)) /* end of file? */
+ newsize -= new_blank_lines_at_end;
+
+ diff = newsize - oldsize;
+ size = desc->size + diff;
+ alloc = desc->alloc;
/* Warn if it was necessary to reduce the number
* of context lines.
@@ -2869,18 +2888,17 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
squelched == 1 ? "" : "s");
}
if (new_whitespace == error_on_whitespace)
- die("%d line%s add%s trailing whitespaces.",
+ die("%d line%s add%s whitespace errors.",
whitespace_error,
whitespace_error == 1 ? "" : "s",
whitespace_error == 1 ? "s" : "");
- if (applied_after_stripping)
+ if (applied_after_fixing_ws)
fprintf(stderr, "warning: %d line%s applied after"
- " stripping trailing whitespaces.\n",
- applied_after_stripping,
- applied_after_stripping == 1 ? "" : "s");
+ " fixing whitespace errors.\n",
+ applied_after_fixing_ws,
+ applied_after_fixing_ws == 1 ? "" : "s");
else if (whitespace_error)
- fprintf(stderr, "warning: %d line%s add%s trailing"
- " whitespaces.\n",
+ fprintf(stderr, "warning: %d line%s add%s whitespace errors.\n",
whitespace_error,
whitespace_error == 1 ? "" : "s",
whitespace_error == 1 ? "s" : "");
diff --git a/builtin-archive.c b/builtin-archive.c
index 7f4e409..187491b 100644
--- a/builtin-archive.c
+++ b/builtin-archive.c
@@ -45,7 +45,7 @@ static int run_remote_archiver(const char *remote, int argc,
}
url = xstrdup(remote);
- pid = git_connect(fd, url, exec);
+ pid = git_connect(fd, url, exec, 0);
if (pid < 0)
return pid;
diff --git a/builtin-blame.c b/builtin-blame.c
index 35471fc..0519339 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -20,7 +20,7 @@
#include "mailmap.h"
static char blame_usage[] =
-"git-blame [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-p] [-L n,m] [-S <revs-file>] [-M] [-C] [-C] [--contents <filename>] [--incremental] [commit] [--] file\n"
+"git-blame [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-p] [-w] [-L n,m] [-S <revs-file>] [-M] [-C] [-C] [--contents <filename>] [--incremental] [commit] [--] file\n"
" -c Use the same output mode as git-annotate (Default: off)\n"
" -b Show blank SHA-1 for boundary commits (Default: off)\n"
" -l Show long commit SHA1 (Default: off)\n"
@@ -30,6 +30,7 @@ static char blame_usage[] =
" -n, --show-number Show original linenumber (Default: off)\n"
" -s Suppress author name and timestamp (Default: off)\n"
" -p, --porcelain Show in a format designed for machine consumption\n"
+" -w Ignore whitespace differences\n"
" -L n,m Process only line range n,m, counting from 1\n"
" -M, -C Find line movements within and across files\n"
" --incremental Show blame entries as we find them, incrementally\n"
@@ -45,6 +46,7 @@ static int show_root;
static int blank_boundary;
static int incremental;
static int cmd_is_annotate;
+static int xdl_opts = XDF_NEED_MINIMAL;
static struct path_list mailmap;
#ifndef DEBUG
@@ -515,9 +517,9 @@ static struct patch *compare_buffer(mmfile_t *file_p, mmfile_t *file_o,
xdemitconf_t xecfg;
xdemitcb_t ecb;
- xpp.flags = XDF_NEED_MINIMAL;
+ xpp.flags = xdl_opts;
+ memset(&xecfg, 0, sizeof(xecfg));
xecfg.ctxlen = context;
- xecfg.flags = 0;
ecb.outf = xdiff_outf;
ecb.priv = &state;
memset(&state, 0, sizeof(state));
@@ -1457,6 +1459,7 @@ static void found_guilty_entry(struct blame_entry *ent)
printf("boundary\n");
}
write_filename_info(suspect->path);
+ maybe_flush_or_die(stdout, "stdout");
}
}
@@ -1744,11 +1747,11 @@ static int read_ancestry(const char *graft_file)
*/
static int lineno_width(int lines)
{
- int i, width;
+ int i, width;
- for (width = 1, i = 10; i <= lines + 1; width++)
- i *= 10;
- return width;
+ for (width = 1, i = 10; i <= lines + 1; width++)
+ i *= 10;
+ return width;
}
/*
@@ -2159,6 +2162,8 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
output_option |= OUTPUT_LONG_OBJECT_NAME;
else if (!strcmp("-s", arg))
output_option |= OUTPUT_NO_AUTHOR;
+ else if (!strcmp("-w", arg))
+ xdl_opts |= XDF_IGNORE_WHITESPACE;
else if (!strcmp("-S", arg) && ++i < argc)
revs_file = argv[i];
else if (!prefixcmp(arg, "-M")) {
diff --git a/builtin-branch.c b/builtin-branch.c
index 94dba6e..5f5c182 100644
--- a/builtin-branch.c
+++ b/builtin-branch.c
@@ -1,7 +1,7 @@
/*
* Builtin "git branch"
*
- * Copyright (c) 2006 Kristian Hgsberg <krh@redhat.com>
+ * Copyright (c) 2006 Kristian Høgsberg <krh@redhat.com>
* Based on git-branch.sh by Junio C Hamano.
*/
@@ -10,6 +10,7 @@
#include "refs.h"
#include "commit.h"
#include "builtin.h"
+#include "remote.h"
static const char builtin_branch_usage[] =
"git-branch [-r] (-d | -D) <branchname> | [--track | --no-track] [-l] [-f] <branchname> [<start-point>] | (-m | -M) [<oldbranch>] <newbranch> | [--color | --no-color] [-r | -a] [-v [--abbrev=<length> | --no-abbrev]]";
@@ -22,7 +23,7 @@ static const char builtin_branch_usage[] =
static const char *head;
static unsigned char head_sha1[20];
-static int branch_track_remotes;
+static int branch_track = 1;
static int branch_use_color;
static char branch_colors[][COLOR_MAXLEN] = {
@@ -55,7 +56,7 @@ static int parse_branch_color_slot(const char *var, int ofs)
die("bad config variable '%s'", var);
}
-int git_branch_config(const char *var, const char *value)
+static int git_branch_config(const char *var, const char *value)
{
if (!strcmp(var, "color.branch")) {
branch_use_color = git_config_colorbool(var, value);
@@ -67,12 +68,12 @@ int git_branch_config(const char *var, const char *value)
return 0;
}
if (!strcmp(var, "branch.autosetupmerge"))
- branch_track_remotes = git_config_bool(var, value);
+ branch_track = git_config_bool(var, value);
return git_default_config(var, value);
}
-const char *branch_get_color(enum color_branch ix)
+static const char *branch_get_color(enum color_branch ix)
{
if (branch_use_color)
return branch_colors[ix];
@@ -85,6 +86,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds)
unsigned char sha1[20];
char *name = NULL;
const char *fmt, *remote;
+ char section[PATH_MAX];
int i;
int ret = 0;
@@ -152,9 +154,13 @@ static int delete_branches(int argc, const char **argv, int force, int kinds)
error("Error deleting %sbranch '%s'", remote,
argv[i]);
ret = 1;
- } else
+ } else {
printf("Deleted %sbranch %s.\n", remote, argv[i]);
-
+ snprintf(section, sizeof(section), "branch.%s",
+ argv[i]);
+ if (git_config_rename_section(section, NULL) < 0)
+ warning("Update of config-file failed");
+ }
}
if (name)
@@ -242,7 +248,6 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
char c;
int color;
struct commit *commit;
- char subject[256];
switch (item->kind) {
case REF_LOCAL_BRANCH:
@@ -263,17 +268,23 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
}
if (verbose) {
+ char *subject = NULL;
+ unsigned long subject_len = 0;
+ const char *sub = " **** invalid ref ****";
+
commit = lookup_commit(item->sha1);
- if (commit && !parse_commit(commit))
+ if (commit && !parse_commit(commit)) {
pretty_print_commit(CMIT_FMT_ONELINE, commit, ~0,
- subject, sizeof(subject), 0,
+ &subject, &subject_len, 0,
NULL, NULL, 0);
- else
- strcpy(subject, " **** invalid ref ****");
+ sub = subject;
+ }
printf("%c %s%-*s%s %s %s\n", c, branch_get_color(color),
maxwidth, item->name,
branch_get_color(COLOR_BRANCH_RESET),
- find_unique_abbrev(item->sha1, abbrev), subject);
+ find_unique_abbrev(item->sha1, abbrev), sub);
+ if (subject)
+ free(subject);
} else {
printf("%c %s%s%s\n", c, branch_get_color(color), item->name,
branch_get_color(COLOR_BRANCH_RESET));
@@ -314,125 +325,70 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev)
free_ref_list(&ref_list);
}
-static char *config_repo;
-static char *config_remote;
-static const char *start_ref;
+struct tracking {
+ struct refspec spec;
+ char *src;
+ const char *remote;
+ int matches;
+};
-static int get_remote_branch_name(const char *value)
+static int find_tracked_branch(struct remote *remote, void *priv)
{
- const char *colon;
- const char *end;
-
- if (*value == '+')
- value++;
-
- colon = strchr(value, ':');
- if (!colon)
- return 0;
-
- end = value + strlen(value);
-
- /*
- * Try an exact match first. I.e. handle the case where the
- * value is "$anything:refs/foo/bar/baz" and start_ref is exactly
- * "refs/foo/bar/baz". Then the name at the remote is $anything.
- */
- if (!strcmp(colon + 1, start_ref)) {
- /* Truncate the value before the colon. */
- nfasprintf(&config_repo, "%.*s", colon - value, value);
- return 1;
+ struct tracking *tracking = priv;
+
+ if (!remote_find_tracking(remote, &tracking->spec)) {
+ if (++tracking->matches == 1) {
+ tracking->src = tracking->spec.src;
+ tracking->remote = remote->name;
+ } else {
+ free(tracking->spec.src);
+ if (tracking->src) {
+ free(tracking->src);
+ tracking->src = NULL;
+ }
+ }
+ tracking->spec.src = NULL;
}
- /*
- * Is this a wildcard match?
- */
- if ((end - 2 <= value) || end[-2] != '/' || end[-1] != '*' ||
- (colon - 2 <= value) || colon[-2] != '/' || colon[-1] != '*')
- return 0;
-
- /*
- * Value is "refs/foo/bar/<asterisk>:refs/baz/boa/<asterisk>"
- * and start_ref begins with "refs/baz/boa/"; the name at the
- * remote is refs/foo/bar/ with the remaining part of the
- * start_ref. The length of the prefix on the RHS is (end -
- * colon - 2), including the slash immediately before the
- * asterisk.
- */
- if ((strlen(start_ref) < end - colon - 2) ||
- memcmp(start_ref, colon + 1, end - colon - 2))
- return 0; /* does not match prefix */
-
- /* Replace the asterisk with the remote branch name. */
- nfasprintf(&config_repo, "%.*s%s",
- (colon - 1) - value, value,
- start_ref + (end - colon - 2));
- return 1;
-}
-
-static int get_remote_config(const char *key, const char *value)
-{
- const char *var;
- if (prefixcmp(key, "remote."))
- return 0;
-
- var = strrchr(key, '.');
- if (var == key + 6 || strcmp(var, ".fetch"))
- return 0;
- /*
- * Ok, we are looking at key == "remote.$foo.fetch";
- */
- if (get_remote_branch_name(value))
- nfasprintf(&config_remote, "%.*s", var - (key + 7), key + 7);
-
return 0;
}
-static void set_branch_merge(const char *name, const char *config_remote,
- const char *config_repo)
+
+/*
+ * This is called when new_ref is branched off of orig_ref, and tries
+ * to infer the settings for branch.<new_ref>.{remote,merge} from the
+ * config.
+ */
+static int setup_tracking(const char *new_ref, const char *orig_ref)
{
char key[1024];
- if (sizeof(key) <=
- snprintf(key, sizeof(key), "branch.%s.remote", name))
- die("what a long branch name you have!");
- git_config_set(key, config_remote);
-
- /*
- * We do not have to check if we have enough space for
- * the 'merge' key, since it's shorter than the
- * previous 'remote' key, which we already checked.
- */
- snprintf(key, sizeof(key), "branch.%s.merge", name);
- git_config_set(key, config_repo);
-}
+ struct tracking tracking;
-static void set_branch_defaults(const char *name, const char *real_ref)
-{
- /*
- * name is the name of new branch under refs/heads;
- * real_ref is typically refs/remotes/$foo/$bar, where
- * $foo is the remote name (there typically are no slashes)
- * and $bar is the branch name we map from the remote
- * (it could have slashes).
- */
- start_ref = real_ref;
- git_config(get_remote_config);
- if (!config_repo && !config_remote &&
- !prefixcmp(real_ref, "refs/heads/")) {
- set_branch_merge(name, ".", real_ref);
- printf("Branch %s set up to track local branch %s.\n",
- name, real_ref);
- }
+ if (strlen(new_ref) > 1024 - 7 - 7 - 1)
+ return error("Tracking not set up: name too long: %s",
+ new_ref);
- if (config_repo && config_remote) {
- set_branch_merge(name, config_remote, config_repo);
+ memset(&tracking, 0, sizeof(tracking));
+ tracking.spec.dst = (char *)orig_ref;
+ if (for_each_remote(find_tracked_branch, &tracking) ||
+ !tracking.matches)
+ return 1;
+
+ if (tracking.matches > 1)
+ return error("Not tracking: ambiguous information for ref %s",
+ orig_ref);
+
+ if (tracking.matches == 1) {
+ sprintf(key, "branch.%s.remote", new_ref);
+ git_config_set(key, tracking.remote ? tracking.remote : ".");
+ sprintf(key, "branch.%s.merge", new_ref);
+ git_config_set(key, tracking.src);
+ free(tracking.src);
printf("Branch %s set up to track remote branch %s.\n",
- name, real_ref);
+ new_ref, orig_ref);
}
- if (config_repo)
- free(config_repo);
- if (config_remote)
- free(config_remote);
+ return 0;
}
static void create_branch(const char *name, const char *start_name,
@@ -477,7 +433,7 @@ static void create_branch(const char *name, const char *start_name,
die("Not a valid branch point: '%s'.", start_name);
hashcpy(sha1, commit->object.sha1);
- lock = lock_any_ref_for_update(ref, NULL);
+ lock = lock_any_ref_for_update(ref, NULL, 0);
if (!lock)
die("Failed to lock ref for update: %s.", strerror(errno));
@@ -495,7 +451,7 @@ static void create_branch(const char *name, const char *start_name,
automatically merges from there. So far, this is only done for
remotes registered via .git/config. */
if (real_ref && track)
- set_branch_defaults(name, real_ref);
+ setup_tracking(name, real_ref);
if (write_ref_sha1(lock, sha1, msg) < 0)
die("Failed to write ref: %s.", strerror(errno));
@@ -554,7 +510,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
int i;
git_config(git_branch_config);
- track = branch_track_remotes;
+ track = branch_track;
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
diff --git a/builtin-bundle.c b/builtin-bundle.c
index 306ad29..6ae5ab0 100644
--- a/builtin-bundle.c
+++ b/builtin-bundle.c
@@ -1,3 +1,4 @@
+#include "builtin.h"
#include "cache.h"
#include "object.h"
#include "commit.h"
diff --git a/builtin-checkout-index.c b/builtin-checkout-index.c
index 8460f97..75377b9 100644
--- a/builtin-checkout-index.c
+++ b/builtin-checkout-index.c
@@ -36,6 +36,7 @@
* of "-a" causing problems (not possible in the above example,
* but get used to it in scripting!).
*/
+#include "builtin.h"
#include "cache.h"
#include "strbuf.h"
#include "quote.h"
diff --git a/builtin-config.c b/builtin-config.c
index dbc2339..0a605e0 100644
--- a/builtin-config.c
+++ b/builtin-config.c
@@ -2,7 +2,7 @@
#include "cache.h"
static const char git_config_set_usage[] =
-"git-config [ --global | --system ] [ --bool | --int ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --remove-section name | --list";
+"git-config [ --global | --system | [ -f | --file ] config-file ] [ --bool | --int ] [ -z | --null ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --remove-section name | --list";
static char *key;
static regex_t *key_regexp;
@@ -12,14 +12,17 @@ static int use_key_regexp;
static int do_all;
static int do_not_match;
static int seen;
+static char delim = '=';
+static char key_delim = ' ';
+static char term = '\n';
static enum { T_RAW, T_INT, T_BOOL } type = T_RAW;
static int show_all_config(const char *key_, const char *value_)
{
if (value_)
- printf("%s=%s\n", key_, value_);
+ printf("%s%c%s%c", key_, delim, value_, term);
else
- printf("%s\n", key_);
+ printf("%s%c", key_, term);
return 0;
}
@@ -40,7 +43,7 @@ static int show_config(const char* key_, const char* value_)
if (show_keys) {
if (value_)
- printf("%s ", key_);
+ printf("%s%c", key_, key_delim);
else
printf("%s", key_);
}
@@ -58,7 +61,7 @@ static int show_config(const char* key_, const char* value_)
key_, vptr);
}
else
- printf("%s\n", vptr);
+ printf("%s%c", vptr, term);
return 0;
}
@@ -135,9 +138,33 @@ free_strings:
return ret;
}
+char *normalize_value(const char *key, const char *value)
+{
+ char *normalized;
+
+ if (!value)
+ return NULL;
+
+ if (type == T_RAW)
+ normalized = xstrdup(value);
+ else {
+ normalized = xmalloc(64);
+ if (type == T_INT) {
+ int v = git_config_int(key, value);
+ sprintf(normalized, "%d", v);
+ }
+ else if (type == T_BOOL)
+ sprintf(normalized, "%s",
+ git_config_bool(key, value) ? "true" : "false");
+ }
+
+ return normalized;
+}
+
int cmd_config(int argc, const char **argv, const char *prefix)
{
int nongit = 0;
+ char* value;
setup_git_directory_gently(&nongit);
while (1 < argc) {
@@ -151,14 +178,26 @@ int cmd_config(int argc, const char **argv, const char *prefix)
char *home = getenv("HOME");
if (home) {
char *user_config = xstrdup(mkpath("%s/.gitconfig", home));
- setenv("GIT_CONFIG", user_config, 1);
+ setenv(CONFIG_ENVIRONMENT, user_config, 1);
free(user_config);
} else {
die("$HOME not set");
}
}
else if (!strcmp(argv[1], "--system"))
- setenv("GIT_CONFIG", ETC_GITCONFIG, 1);
+ setenv(CONFIG_ENVIRONMENT, ETC_GITCONFIG, 1);
+ else if (!strcmp(argv[1], "--file") || !strcmp(argv[1], "-f")) {
+ if (argc < 3)
+ usage(git_config_set_usage);
+ setenv(CONFIG_ENVIRONMENT, argv[2], 1);
+ argc--;
+ argv++;
+ }
+ else if (!strcmp(argv[1], "--null") || !strcmp(argv[1], "-z")) {
+ term = '\0';
+ delim = '\n';
+ key_delim = '\n';
+ }
else if (!strcmp(argv[1], "--rename-section")) {
int ret;
if (argc != 4)
@@ -209,9 +248,10 @@ int cmd_config(int argc, const char **argv, const char *prefix)
use_key_regexp = 1;
do_all = 1;
return get_value(argv[2], NULL);
- } else
-
- return git_config_set(argv[1], argv[2]);
+ } else {
+ value = normalize_value(argv[1], argv[2]);
+ return git_config_set(argv[1], value);
+ }
case 4:
if (!strcmp(argv[1], "--unset"))
return git_config_set_multivar(argv[2], NULL, argv[3], 0);
@@ -227,17 +267,21 @@ int cmd_config(int argc, const char **argv, const char *prefix)
use_key_regexp = 1;
do_all = 1;
return get_value(argv[2], argv[3]);
- } else if (!strcmp(argv[1], "--add"))
- return git_config_set_multivar(argv[2], argv[3], "^$", 0);
- else if (!strcmp(argv[1], "--replace-all"))
-
- return git_config_set_multivar(argv[2], argv[3], NULL, 1);
- else
-
- return git_config_set_multivar(argv[1], argv[2], argv[3], 0);
+ } else if (!strcmp(argv[1], "--add")) {
+ value = normalize_value(argv[2], argv[3]);
+ return git_config_set_multivar(argv[2], value, "^$", 0);
+ } else if (!strcmp(argv[1], "--replace-all")) {
+ value = normalize_value(argv[2], argv[3]);
+ return git_config_set_multivar(argv[2], value, NULL, 1);
+ } else {
+ value = normalize_value(argv[1], argv[2]);
+ return git_config_set_multivar(argv[1], value, argv[3], 0);
+ }
case 5:
- if (!strcmp(argv[1], "--replace-all"))
- return git_config_set_multivar(argv[2], argv[3], argv[4], 1);
+ if (!strcmp(argv[1], "--replace-all")) {
+ value = normalize_value(argv[2], argv[3]);
+ return git_config_set_multivar(argv[2], value, argv[4], 1);
+ }
case 1:
default:
usage(git_config_set_usage);
diff --git a/builtin-count-objects.c b/builtin-count-objects.c
index ff90ebd..4274ec1 100644
--- a/builtin-count-objects.c
+++ b/builtin-count-objects.c
@@ -111,6 +111,8 @@ int cmd_count_objects(int ac, const char **av, const char *prefix)
for (p = packed_git; p; p = p->next) {
if (!p->pack_local)
continue;
+ if (open_pack_index(p))
+ continue;
packed += p->num_objects;
num_pack++;
}
diff --git a/builtin-describe.c b/builtin-describe.c
index 165917e..669110c 100644
--- a/builtin-describe.c
+++ b/builtin-describe.c
@@ -3,6 +3,7 @@
#include "tag.h"
#include "refs.h"
#include "builtin.h"
+#include "exec_cmd.h"
#define SEEN (1u<<0)
#define MAX_TAGS (FLAG_BITS - 1)
@@ -242,12 +243,15 @@ static void describe(const char *arg, int last_one)
int cmd_describe(int argc, const char **argv, const char *prefix)
{
int i;
+ int contains = 0;
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
if (*arg != '-')
break;
+ else if (!strcmp(arg, "--contains"))
+ contains = 1;
else if (!strcmp(arg, "--debug"))
debug = 1;
else if (!strcmp(arg, "--all"))
@@ -272,6 +276,16 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
save_commit_buffer = 0;
+ if (contains) {
+ const char **args = xmalloc((4 + argc - i) * sizeof(char*));
+ args[0] = "name-rev";
+ args[1] = "--name-only";
+ args[2] = "--tags";
+ memcpy(args + 3, argv + i, (argc - i) * sizeof(char*));
+ args[3 + argc - i] = NULL;
+ return cmd_name_rev(3 + argc - i, args, prefix);
+ }
+
if (argc <= i)
describe("HEAD", 1);
else
diff --git a/builtin-diff-index.c b/builtin-diff-index.c
index d90eba9..81e7167 100644
--- a/builtin-diff-index.c
+++ b/builtin-diff-index.c
@@ -23,7 +23,7 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix)
argc = setup_revisions(argc, argv, &rev, NULL);
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
-
+
if (!strcmp(arg, "--cached"))
cached = 1;
else
diff --git a/builtin-diff.c b/builtin-diff.c
index 7f367b6..b48121e 100644
--- a/builtin-diff.c
+++ b/builtin-diff.c
@@ -233,6 +233,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
die("diff_setup_done failed");
}
rev.diffopt.allow_external = 1;
+ rev.diffopt.recursive = 1;
/* Do we have --cached and not have a pending object, then
* default to HEAD by hand. Eek.
diff --git a/builtin-fetch--tool.c b/builtin-fetch--tool.c
index 12adb38..e2f8ede 100644
--- a/builtin-fetch--tool.c
+++ b/builtin-fetch--tool.c
@@ -1,3 +1,4 @@
+#include "builtin.h"
#include "cache.h"
#include "refs.h"
#include "commit.h"
@@ -42,7 +43,7 @@ static int update_ref(const char *action,
if (!rla)
rla = "(reflog update)";
snprintf(msg, sizeof(msg), "%s: %s", rla, action);
- lock = lock_any_ref_for_update(refname, oldval);
+ lock = lock_any_ref_for_update(refname, oldval, 0);
if (!lock)
return 1;
if (write_ref_sha1(lock, sha1, msg) < 0)
diff --git a/builtin-fmt-merge-msg.c b/builtin-fmt-merge-msg.c
index 5c145d2..ae60fcc 100644
--- a/builtin-fmt-merge-msg.c
+++ b/builtin-fmt-merge-msg.c
@@ -357,4 +357,3 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
return 0;
}
-
diff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c
index 2b21842..0afa1c5 100644
--- a/builtin-for-each-ref.c
+++ b/builtin-for-each-ref.c
@@ -1,3 +1,4 @@
+#include "builtin.h"
#include "cache.h"
#include "refs.h"
#include "object.h"
@@ -796,7 +797,7 @@ static struct ref_sort *default_sort(void)
return sort;
}
-int cmd_for_each_ref(int ac, const char **av, char *prefix)
+int cmd_for_each_ref(int ac, const char **av, const char *prefix)
{
int i, num_refs;
const char *format = NULL;
diff --git a/builtin-fsck.c b/builtin-fsck.c
index 44ce629..8d12287 100644
--- a/builtin-fsck.c
+++ b/builtin-fsck.c
@@ -1,3 +1,4 @@
+#include "builtin.h"
#include "cache.h"
#include "commit.h"
#include "tree.h"
@@ -20,6 +21,8 @@ static int check_strict;
static int keep_cache_objects;
static unsigned char head_sha1[20];
static int errors_found;
+static int write_lost_and_found;
+static int verbose;
#define ERROR_OBJECT 01
#define ERROR_REACHABLE 02
@@ -137,6 +140,31 @@ static void check_unreachable_object(struct object *obj)
if (!obj->used) {
printf("dangling %s %s\n", typename(obj->type),
sha1_to_hex(obj->sha1));
+ if (write_lost_and_found) {
+ char *filename = git_path("lost-found/%s/%s",
+ obj->type == OBJ_COMMIT ? "commit" : "other",
+ sha1_to_hex(obj->sha1));
+ FILE *f;
+
+ if (safe_create_leading_directories(filename)) {
+ error("Could not create lost-found");
+ return;
+ }
+ if (!(f = fopen(filename, "w")))
+ die("Could not open %s", filename);
+ if (obj->type == OBJ_BLOB) {
+ enum object_type type;
+ unsigned long size;
+ char *buf = read_sha1_file(obj->sha1,
+ &type, &size);
+ if (buf) {
+ fwrite(buf, size, 1, f);
+ free(buf);
+ }
+ } else
+ fprintf(f, "%s\n", sha1_to_hex(obj->sha1));
+ fclose(f);
+ }
return;
}
@@ -149,6 +177,9 @@ static void check_unreachable_object(struct object *obj)
static void check_object(struct object *obj)
{
+ if (verbose)
+ fprintf(stderr, "Checking %s\n", sha1_to_hex(obj->sha1));
+
if (obj->flags & REACHABLE)
check_reachable_object(obj);
else
@@ -161,6 +192,9 @@ static void check_connectivity(void)
/* Look up all the requirements, warn about missing objects.. */
max = get_max_object_index();
+ if (verbose)
+ fprintf(stderr, "Checking connectivity (%d objects)\n", max);
+
for (i = 0; i < max; i++) {
struct object *obj = get_indexed_object(i);
@@ -229,6 +263,10 @@ static int fsck_tree(struct tree *item)
const char *o_name;
const unsigned char *o_sha1;
+ if (verbose)
+ fprintf(stderr, "Checking tree %s\n",
+ sha1_to_hex(item->object.sha1));
+
init_tree_desc(&desc, item->buffer, item->size);
o_mode = 0;
@@ -256,7 +294,7 @@ static int fsck_tree(struct tree *item)
case S_IFREG | 0644:
case S_IFLNK:
case S_IFDIR:
- case S_IFDIRLNK:
+ case S_IFGITLINK:
break;
/*
* This is nonstandard, but we had a few of these
@@ -317,6 +355,10 @@ static int fsck_commit(struct commit *commit)
char *buffer = commit->buffer;
unsigned char tree_sha1[20], sha1[20];
+ if (verbose)
+ fprintf(stderr, "Checking commit %s\n",
+ sha1_to_hex(commit->object.sha1));
+
if (memcmp(buffer, "tree ", 5))
return objerror(&commit->object, "invalid format - expected 'tree' line");
if (get_sha1_hex(buffer+5, tree_sha1) || buffer[45] != '\n')
@@ -336,7 +378,7 @@ static int fsck_commit(struct commit *commit)
if (!commit->parents && show_root)
printf("root %s\n", sha1_to_hex(commit->object.sha1));
if (!commit->date)
- printf("bad commit date in %s\n",
+ printf("bad commit date in %s\n",
sha1_to_hex(commit->object.sha1));
return 0;
}
@@ -345,6 +387,10 @@ static int fsck_tag(struct tag *tag)
{
struct object *tagged = tag->tagged;
+ if (verbose)
+ fprintf(stderr, "Checking tag %s\n",
+ sha1_to_hex(tag->object.sha1));
+
if (!tagged) {
return objerror(&tag->object, "could not load tagged object");
}
@@ -446,6 +492,9 @@ static void fsck_dir(int i, char *path)
if (!dir)
return;
+ if (verbose)
+ fprintf(stderr, "Checking directory %s\n", path);
+
while ((de = readdir(dir)) != NULL) {
char name[100];
unsigned char sha1[20];
@@ -480,6 +529,10 @@ static int fsck_handle_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
{
struct object *obj;
+ if (verbose)
+ fprintf(stderr, "Checking reflog %s->%s\n",
+ sha1_to_hex(osha1), sha1_to_hex(nsha1));
+
if (!is_null_sha1(osha1)) {
obj = lookup_object(osha1);
if (obj) {
@@ -549,6 +602,10 @@ static void get_default_heads(void)
static void fsck_object_dir(const char *path)
{
int i;
+
+ if (verbose)
+ fprintf(stderr, "Checking object directory\n");
+
for (i = 0; i < 256; i++) {
static char dir[4096];
sprintf(dir, "%s/%02x", path, i);
@@ -564,6 +621,9 @@ static int fsck_head_link(void)
int null_is_error = 0;
const char *head_points_at = resolve_ref("HEAD", sha1, 0, &flag);
+ if (verbose)
+ fprintf(stderr, "Checking HEAD link\n");
+
if (!head_points_at)
return error("Invalid HEAD");
if (!strcmp(head_points_at, "HEAD"))
@@ -586,6 +646,9 @@ static int fsck_cache_tree(struct cache_tree *it)
int i;
int err = 0;
+ if (verbose)
+ fprintf(stderr, "Checking cache tree\n");
+
if (0 <= it->entry_count) {
struct object *obj = parse_object(it->sha1);
if (!obj) {
@@ -605,9 +668,9 @@ static int fsck_cache_tree(struct cache_tree *it)
static const char fsck_usage[] =
"git-fsck [--tags] [--root] [[--unreachable] [--cache] [--full] "
-"[--strict] <head-sha1>*]";
+"[--strict] [--verbose] <head-sha1>*]";
-int cmd_fsck(int argc, char **argv, const char *prefix)
+int cmd_fsck(int argc, const char **argv, const char *prefix)
{
int i, heads;
@@ -645,6 +708,16 @@ int cmd_fsck(int argc, char **argv, const char *prefix)
check_strict = 1;
continue;
}
+ if (!strcmp(arg, "--verbose")) {
+ verbose = 1;
+ continue;
+ }
+ if (!strcmp(arg, "--lost-found")) {
+ check_full = 1;
+ include_reflogs = 0;
+ write_lost_and_found = 1;
+ continue;
+ }
if (*arg == '-')
usage(fsck_usage);
}
@@ -668,7 +741,10 @@ int cmd_fsck(int argc, char **argv, const char *prefix)
verify_pack(p, 0);
for (p = packed_git; p; p = p->next) {
- uint32_t i, num = p->num_objects;
+ uint32_t i, num;
+ if (open_pack_index(p))
+ continue;
+ num = p->num_objects;
for (i = 0; i < num; i++)
fsck_sha1(nth_packed_object_sha1(p, i));
}
@@ -676,7 +752,7 @@ int cmd_fsck(int argc, char **argv, const char *prefix)
heads = 0;
for (i = 1; i < argc; i++) {
- const char *arg = argv[i];
+ const char *arg = argv[i];
if (*arg == '-')
continue;
@@ -715,7 +791,7 @@ int cmd_fsck(int argc, char **argv, const char *prefix)
struct object *obj;
mode = ntohl(active_cache[i]->ce_mode);
- if (S_ISDIRLNK(mode))
+ if (S_ISGITLINK(mode))
continue;
blob = lookup_blob(active_cache[i]->sha1);
if (!blob)
diff --git a/builtin-gc.c b/builtin-gc.c
index 3b1f8c2..9397482 100644
--- a/builtin-gc.c
+++ b/builtin-gc.c
@@ -10,18 +10,21 @@
* Copyright (c) 2006 Shawn O. Pearce
*/
+#include "builtin.h"
#include "cache.h"
#include "run-command.h"
#define FAILED_RUN "failed to run %s"
-static const char builtin_gc_usage[] = "git-gc [--prune]";
+static const char builtin_gc_usage[] = "git-gc [--prune] [--aggressive]";
-static int pack_refs = -1;
+static int pack_refs = 1;
+static int aggressive_window = -1;
-static const char *argv_pack_refs[] = {"pack-refs", "--prune", NULL};
+#define MAX_ADD 10
+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[] = {"repack", "-a", "-d", "-l", NULL};
+static const char *argv_repack[MAX_ADD] = {"repack", "-a", "-d", "-l", NULL};
static const char *argv_prune[] = {"prune", NULL};
static const char *argv_rerere[] = {"rerere", "gc", NULL};
@@ -34,13 +37,31 @@ static int gc_config(const char *var, const char *value)
pack_refs = git_config_bool(var, value);
return 0;
}
+ if (!strcmp(var, "gc.aggressivewindow")) {
+ aggressive_window = git_config_int(var, value);
+ return 0;
+ }
return git_default_config(var, value);
}
+static void append_option(const char **cmd, const char *opt, int max_length)
+{
+ int i;
+
+ for (i = 0; cmd[i]; i++)
+ ;
+
+ if (i + 2 >= max_length)
+ die("Too many options specified");
+ cmd[i++] = opt;
+ cmd[i] = NULL;
+}
+
int cmd_gc(int argc, const char **argv, const char *prefix)
{
int i;
int prune = 0;
+ char buf[80];
git_config(gc_config);
@@ -53,6 +74,14 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
prune = 1;
continue;
}
+ if (!strcmp(arg, "--aggressive")) {
+ append_option(argv_repack, "-f", MAX_ADD);
+ if (aggressive_window > 0) {
+ sprintf(buf, "--window=%d", aggressive_window);
+ append_option(argv_repack, buf, MAX_ADD);
+ }
+ continue;
+ }
/* perhaps other parameters later... */
break;
}
diff --git a/builtin-init-db.c b/builtin-init-db.c
index 4df9fd0..0d9b1e0 100644
--- a/builtin-init-db.c
+++ b/builtin-init-db.c
@@ -7,7 +7,7 @@
#include "builtin.h"
#ifndef DEFAULT_GIT_TEMPLATE_DIR
-#define DEFAULT_GIT_TEMPLATE_DIR "/usr/share/git-core/templates/"
+#define DEFAULT_GIT_TEMPLATE_DIR "/usr/share/git-core/templates"
#endif
#ifdef NO_TRUSTABLE_FILEMODE
@@ -40,7 +40,8 @@ static int copy_file(const char *dst, const char *src, int mode)
return fdo;
}
status = copy_fd(fdi, fdo);
- close(fdo);
+ if (close(fdo) != 0)
+ return error("%s: write error: %s", dst, strerror(errno));
if (!status && adjust_shared_perm(dst))
return -1;
@@ -252,20 +253,22 @@ static int create_default_files(const char *git_dir, const char *template_path)
}
git_config_set("core.filemode", filemode ? "true" : "false");
- if (is_bare_repository()) {
+ if (is_bare_repository())
git_config_set("core.bare", "true");
- }
else {
+ const char *work_tree = get_git_work_tree();
git_config_set("core.bare", "false");
/* allow template config file to override the default */
if (log_all_ref_updates == -1)
git_config_set("core.logallrefupdates", "true");
+ if (work_tree != git_work_tree_cfg)
+ git_config_set("core.worktree", work_tree);
}
return reinit;
}
static const char init_db_usage[] =
-"git-init [--template=<template-directory>] [--shared]";
+"git-init [-q | --quiet] [--template=<template-directory>] [--shared]";
/*
* If you want to, you can share the DB area with any number of branches.
@@ -280,6 +283,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
const char *template_dir = NULL;
char *path;
int len, i, reinit;
+ int quiet = 0;
for (i = 1; i < argc; i++, argv++) {
const char *arg = argv[1];
@@ -289,10 +293,18 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
shared_repository = PERM_GROUP;
else if (!prefixcmp(arg, "--shared="))
shared_repository = git_config_perm("arg", arg+9);
+ else if (!strcmp(arg, "-q") || !strcmp(arg, "--quiet"))
+ quiet = 1;
else
usage(init_db_usage);
}
+ git_work_tree_cfg = xcalloc(PATH_MAX, 1);
+ if (!getcwd(git_work_tree_cfg, PATH_MAX))
+ die ("Cannot access current working directory.");
+ if (access(get_git_work_tree(), X_OK))
+ die ("Cannot access work tree '%s'", get_git_work_tree());
+
/*
* Set up the default .git directory contents
*/
@@ -335,10 +347,11 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
git_config_set("receive.denyNonFastforwards", "true");
}
- printf("%s%s Git repository in %s/\n",
- reinit ? "Reinitialized existing" : "Initialized empty",
- shared_repository ? " shared" : "",
- git_dir);
+ if (!quiet)
+ printf("%s%s Git repository in %s/\n",
+ reinit ? "Reinitialized existing" : "Initialized empty",
+ shared_repository ? " shared" : "",
+ git_dir);
return 0;
}
diff --git a/builtin-log.c b/builtin-log.c
index 3744712..13bae31 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -16,6 +16,7 @@
#include "refs.h"
static int default_show_root = 1;
+static const char *fmt_patch_subject_prefix = "PATCH";
/* this is in builtin-diff.c */
void add_head(struct rev_info *revs);
@@ -55,18 +56,18 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
rev->commit_format = CMIT_FMT_DEFAULT;
rev->verbose_header = 1;
rev->show_root_diff = default_show_root;
+ rev->subject_prefix = fmt_patch_subject_prefix;
argc = setup_revisions(argc, argv, rev, "HEAD");
if (rev->diffopt.pickaxe || rev->diffopt.filter)
rev->always_show_header = 0;
+ if (rev->diffopt.follow_renames) {
+ rev->always_show_header = 0;
+ if (rev->diffopt.nr_paths != 1)
+ usage("git logs can only follow renames on one pathname at a time");
+ }
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
- if (!prefixcmp(arg, "--encoding=")) {
- arg += 11;
- if (strcmp(arg, "none"))
- git_log_output_encoding = xstrdup(arg);
- else
- git_log_output_encoding = "";
- } else if (!strcmp(arg, "--decorate")) {
+ if (!strcmp(arg, "--decorate")) {
if (!decorate)
for_each_ref(add_ref_decoration, NULL);
decorate = 1;
@@ -95,6 +96,12 @@ static int cmd_log_walk(struct rev_info *rev)
static int git_log_config(const char *var, const char *value)
{
+ if (!strcmp(var, "format.subjectprefix")) {
+ if (!value)
+ die("format.subjectprefix without value");
+ fmt_patch_subject_prefix = xstrdup(value);
+ return 0;
+ }
if (!strcmp(var, "log.showroot")) {
default_show_root = git_config_bool(var, value);
return 0;
@@ -291,6 +298,7 @@ static int git_format_config(const char *var, const char *value)
if (!strcmp(var, "diff.color") || !strcmp(var, "color.diff")) {
return 0;
}
+
return git_log_config(var, value);
}
@@ -298,7 +306,8 @@ static int git_format_config(const char *var, const char *value)
static FILE *realstdout = NULL;
static const char *output_directory = NULL;
-static int reopen_stdout(struct commit *commit, int nr, int keep_subject)
+static int reopen_stdout(struct commit *commit, int nr, int keep_subject,
+ int numbered_files)
{
char filename[PATH_MAX];
char *sol;
@@ -315,53 +324,61 @@ static int reopen_stdout(struct commit *commit, int nr, int keep_subject)
filename[len++] = '/';
}
- sprintf(filename + len, "%04d", nr);
- len = strlen(filename);
-
- sol = strstr(commit->buffer, "\n\n");
- if (sol) {
- int j, space = 1;
-
- sol += 2;
- /* strip [PATCH] or [PATCH blabla] */
- if (!keep_subject && !prefixcmp(sol, "[PATCH")) {
- char *eos = strchr(sol + 6, ']');
- if (eos) {
- while (isspace(*eos))
- eos++;
- sol = eos;
- }
- }
+ if (numbered_files) {
+ sprintf(filename + len, "%d", nr);
+ len = strlen(filename);
+
+ } else {
+ sprintf(filename + len, "%04d", nr);
+ len = strlen(filename);
- for (j = 0;
- j < FORMAT_PATCH_NAME_MAX - suffix_len - 5 &&
- len < sizeof(filename) - suffix_len &&
- sol[j] && sol[j] != '\n';
- j++) {
- if (istitlechar(sol[j])) {
- if (space) {
- filename[len++] = '-';
- space = 0;
+ sol = strstr(commit->buffer, "\n\n");
+ if (sol) {
+ int j, space = 1;
+
+ sol += 2;
+ /* strip [PATCH] or [PATCH blabla] */
+ if (!keep_subject && !prefixcmp(sol, "[PATCH")) {
+ char *eos = strchr(sol + 6, ']');
+ if (eos) {
+ while (isspace(*eos))
+ eos++;
+ sol = eos;
}
- filename[len++] = sol[j];
- if (sol[j] == '.')
- while (sol[j + 1] == '.')
- j++;
- } else
- space = 1;
+ }
+
+ for (j = 0;
+ j < FORMAT_PATCH_NAME_MAX - suffix_len - 5 &&
+ len < sizeof(filename) - suffix_len &&
+ sol[j] && sol[j] != '\n';
+ j++) {
+ if (istitlechar(sol[j])) {
+ if (space) {
+ filename[len++] = '-';
+ space = 0;
+ }
+ filename[len++] = sol[j];
+ if (sol[j] == '.')
+ while (sol[j + 1] == '.')
+ j++;
+ } else
+ space = 1;
+ }
+ while (filename[len - 1] == '.'
+ || filename[len - 1] == '-')
+ len--;
+ filename[len] = 0;
}
- while (filename[len - 1] == '.' || filename[len - 1] == '-')
- len--;
- filename[len] = 0;
+ if (len + suffix_len >= sizeof(filename))
+ return error("Patch pathname too long");
+ strcpy(filename + len, fmt_patch_suffix);
}
- if (len + suffix_len >= sizeof(filename))
- return error("Patch pathname too long");
- strcpy(filename + len, fmt_patch_suffix);
+
fprintf(realstdout, "%s\n", filename);
if (freopen(filename, "w", stdout) == NULL)
return error("Cannot open patch file %s",filename);
- return 0;
+ return 0;
}
static void get_patch_ids(struct rev_info *rev, struct patch_ids *ids, const char *prefix)
@@ -431,6 +448,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
int numbered = 0;
int start_number = -1;
int keep_subject = 0;
+ int numbered_files = 0; /* _just_ numbers */
int subject_prefix = 0;
int ignore_if_in_upstream = 0;
int thread = 0;
@@ -450,6 +468,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
rev.diffopt.msg_sep = "";
rev.diffopt.recursive = 1;
+ rev.subject_prefix = fmt_patch_subject_prefix;
rev.extra_headers = extra_headers;
/*
@@ -465,6 +484,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
numbered = 1;
else if (!prefixcmp(argv[i], "--start-number="))
start_number = strtol(argv[i] + 15, NULL, 10);
+ else if (!strcmp(argv[i], "--numbered-files"))
+ numbered_files = 1;
else if (!strcmp(argv[i], "--start-number")) {
i++;
if (i == argc)
@@ -540,6 +561,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
die ("-n and -k are mutually exclusive.");
if (keep_subject && subject_prefix)
die ("--subject-prefix and -k are mutually exclusive.");
+ if (numbered_files && use_stdout)
+ die ("--numbered-files and --stdout are mutually exclusive.");
argc = setup_revisions(argc, argv, &rev, "HEAD");
if (argc > 1)
@@ -576,7 +599,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
get_patch_ids(&rev, &ids, prefix);
if (!use_stdout)
- realstdout = fdopen(dup(1), "w");
+ realstdout = xfdopen(xdup(1), "w");
prepare_revision_walk(&rev);
while ((commit = get_revision(&rev)) != NULL) {
@@ -614,7 +637,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
rev.message_id = message_id;
}
if (!use_stdout)
- if (reopen_stdout(commit, rev.nr, keep_subject))
+ if (reopen_stdout(commit, rev.nr, keep_subject,
+ numbered_files))
die("Failed to create output files");
shown = log_tree_commit(&rev, commit);
free(commit->buffer);
@@ -733,11 +757,13 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
sign = '-';
if (verbose) {
- static char buf[16384];
+ char *buf = NULL;
+ unsigned long buflen = 0;
pretty_print_commit(CMIT_FMT_ONELINE, commit, ~0,
- buf, sizeof(buf), 0, NULL, NULL, 0);
+ &buf, &buflen, 0, NULL, NULL, 0);
printf("%c %s %s\n", sign,
sha1_to_hex(commit->object.sha1), buf);
+ free(buf);
}
else {
printf("%c %s\n", sign,
diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index f7c066b..d36181a 100644
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
@@ -117,7 +117,7 @@ static void show_other_files(struct dir_struct *dir)
if (0 <= pos)
continue; /* exact match */
pos = -pos - 1;
- if (pos < active_nr) {
+ if (pos < active_nr) {
ce = active_cache[pos];
if (ce_namelen(ce) == len &&
!memcmp(ce->name, ent->name, len))
@@ -469,9 +469,11 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
break;
}
- if (require_work_tree &&
- (is_bare_repository() || is_inside_git_dir()))
- die("This operation must be run in a work tree");
+ if (require_work_tree && !is_inside_work_tree()) {
+ const char *work_tree = get_git_work_tree();
+ if (!work_tree || chdir(work_tree))
+ die("This operation must be run in a work tree");
+ }
pathspec = get_pathspec(prefix, argv + i);
diff --git a/builtin-ls-tree.c b/builtin-ls-tree.c
index 1cb4dca..cb4be4f 100644
--- a/builtin-ls-tree.c
+++ b/builtin-ls-tree.c
@@ -15,6 +15,7 @@ static int line_termination = '\n';
#define LS_TREE_ONLY 2
#define LS_SHOW_TREES 4
#define LS_NAME_ONLY 8
+#define LS_SHOW_SIZE 16
static int abbrev;
static int ls_options;
static const char **pathspec;
@@ -22,7 +23,7 @@ static int chomp_prefix;
static const char *ls_tree_prefix;
static const char ls_tree_usage[] =
- "git-ls-tree [-d] [-r] [-t] [-z] [--name-only] [--name-status] [--full-name] [--abbrev[=<n>]] <tree-ish> [path...]";
+ "git-ls-tree [-d] [-r] [-t] [-l] [-z] [--name-only] [--name-status] [--full-name] [--abbrev[=<n>]] <tree-ish> [path...]";
static int show_recursive(const char *base, int baselen, const char *pathname)
{
@@ -59,8 +60,9 @@ static int show_tree(const unsigned char *sha1, const char *base, int baselen,
{
int retval = 0;
const char *type = blob_type;
+ unsigned long size;
- if (S_ISDIRLNK(mode)) {
+ if (S_ISGITLINK(mode)) {
/*
* Maybe we want to have some recursive version here?
*
@@ -92,10 +94,24 @@ static int show_tree(const unsigned char *sha1, const char *base, int baselen,
(baselen < chomp_prefix || memcmp(ls_tree_prefix, base, chomp_prefix)))
return 0;
- if (!(ls_options & LS_NAME_ONLY))
- printf("%06o %s %s\t", mode, type,
- abbrev ? find_unique_abbrev(sha1,abbrev)
- : sha1_to_hex(sha1));
+ if (!(ls_options & LS_NAME_ONLY)) {
+ if (ls_options & LS_SHOW_SIZE) {
+ if (!strcmp(type, blob_type)) {
+ sha1_object_info(sha1, &size);
+ printf("%06o %s %s %7lu\t", mode, type,
+ abbrev ? find_unique_abbrev(sha1, abbrev)
+ : sha1_to_hex(sha1),
+ size);
+ } else
+ printf("%06o %s %s %7c\t", mode, type,
+ abbrev ? find_unique_abbrev(sha1, abbrev)
+ : sha1_to_hex(sha1),
+ '-');
+ } else
+ printf("%06o %s %s\t", mode, type,
+ abbrev ? find_unique_abbrev(sha1, abbrev)
+ : sha1_to_hex(sha1));
+ }
write_name_quoted(base + chomp_prefix, baselen - chomp_prefix,
pathname,
line_termination, stdout);
@@ -126,12 +142,19 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
case 't':
ls_options |= LS_SHOW_TREES;
break;
+ case 'l':
+ ls_options |= LS_SHOW_SIZE;
+ break;
case '-':
if (!strcmp(argv[1]+2, "name-only") ||
!strcmp(argv[1]+2, "name-status")) {
ls_options |= LS_NAME_ONLY;
break;
}
+ if (!strcmp(argv[1]+2, "long")) {
+ ls_options |= LS_SHOW_SIZE;
+ break;
+ }
if (!strcmp(argv[1]+2, "full-name")) {
chomp_prefix = 0;
break;
diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
index c95e477..b558754 100644
--- a/builtin-mailinfo.c
+++ b/builtin-mailinfo.c
@@ -237,8 +237,6 @@ static int eatspace(char *line)
static char *cleanup_subject(char *subject)
{
- if (keep_subject)
- return subject;
for (;;) {
char *p;
int len, remove;
@@ -425,6 +423,7 @@ static int read_one_header_line(char *line, int sz, FILE *in)
if (addlen >= sz - len)
addlen = sz - len - 1;
memcpy(line + len, continuation, addlen);
+ line[len] = '\n';
len += addlen;
}
}
@@ -499,15 +498,42 @@ static int decode_b_segment(char *in, char *ot, char *ep)
return 0;
}
+/*
+ * When there is no known charset, guess.
+ *
+ * Right now we assume that if the target is UTF-8 (the default),
+ * and it already looks like UTF-8 (which includes US-ASCII as its
+ * subset, of course) then that is what it is and there is nothing
+ * to do.
+ *
+ * Otherwise, we default to assuming it is Latin1 for historical
+ * reasons.
+ */
+static const char *guess_charset(const char *line, const char *target_charset)
+{
+ if (is_encoding_utf8(target_charset)) {
+ if (is_utf8(line))
+ return NULL;
+ }
+ return "latin1";
+}
+
static void convert_to_utf8(char *line, const char *charset)
{
- static const char latin_one[] = "latin1";
- const char *input_charset = *charset ? charset : latin_one;
- char *out = reencode_string(line, metainfo_charset, input_charset);
+ char *out;
+
+ if (!charset || !*charset) {
+ charset = guess_charset(line, metainfo_charset);
+ if (!charset)
+ return;
+ }
+ if (!strcmp(metainfo_charset, charset))
+ return;
+ out = reencode_string(line, metainfo_charset, charset);
if (!out)
die("cannot convert from %s to %s\n",
- input_charset, metainfo_charset);
+ charset, metainfo_charset);
strcpy(line, out);
free(out);
}
@@ -819,6 +845,22 @@ static void handle_body(void)
return;
}
+static void output_header_lines(FILE *fout, const char *hdr, char *data)
+{
+ while (1) {
+ char *ep = strchr(data, '\n');
+ int len;
+ if (!ep)
+ len = strlen(data);
+ else
+ len = ep - data;
+ fprintf(fout, "%s: %.*s\n", hdr, len, data);
+ if (!ep)
+ break;
+ data = ep + 1;
+ }
+}
+
static void handle_info(void)
{
char *sub;
@@ -836,9 +878,13 @@ static void handle_info(void)
continue;
if (!memcmp(header[i], "Subject", 7)) {
- sub = cleanup_subject(hdr);
- cleanup_space(sub);
- fprintf(fout, "Subject: %s\n", sub);
+ if (keep_subject)
+ sub = hdr;
+ else {
+ sub = cleanup_subject(hdr);
+ cleanup_space(sub);
+ }
+ output_header_lines(fout, "Subject", sub);
} else if (!memcmp(header[i], "From", 4)) {
handle_from(hdr);
fprintf(fout, "Author: %s\n", name);
@@ -851,8 +897,8 @@ static void handle_info(void)
fprintf(fout, "\n");
}
-int mailinfo(FILE *in, FILE *out, int ks, const char *encoding,
- const char *msg, const char *patch)
+static int mailinfo(FILE *in, FILE *out, int ks, const char *encoding,
+ const char *msg, const char *patch)
{
keep_subject = ks;
metainfo_charset = encoding;
diff --git a/builtin-mailsplit.c b/builtin-mailsplit.c
index 3bca855..43fc373 100644
--- a/builtin-mailsplit.c
+++ b/builtin-mailsplit.c
@@ -6,9 +6,10 @@
*/
#include "cache.h"
#include "builtin.h"
+#include "path-list.h"
static const char git_mailsplit_usage[] =
-"git-mailsplit [-d<prec>] [-f<n>] [-b] -o<directory> <mbox>...";
+"git-mailsplit [-d<prec>] [-f<n>] [-b] -o<directory> <mbox>|<Maildir>...";
static int is_from_line(const char *line, int len)
{
@@ -96,44 +97,107 @@ static int split_one(FILE *mbox, const char *name, int allow_bare)
exit(1);
}
-int split_mbox(const char **mbox, const char *dir, int allow_bare, int nr_prec, int skip)
+static int populate_maildir_list(struct path_list *list, const char *path)
{
- char *name = xmalloc(strlen(dir) + 2 + 3 * sizeof(skip));
+ DIR *dir;
+ struct dirent *dent;
+
+ if ((dir = opendir(path)) == NULL) {
+ error("cannot opendir %s (%s)", path, strerror(errno));
+ return -1;
+ }
+
+ while ((dent = readdir(dir)) != NULL) {
+ if (dent->d_name[0] == '.')
+ continue;
+ path_list_insert(dent->d_name, list);
+ }
+
+ closedir(dir);
+
+ return 0;
+}
+
+static int split_maildir(const char *maildir, const char *dir,
+ int nr_prec, int skip)
+{
+ char file[PATH_MAX];
+ char curdir[PATH_MAX];
+ char name[PATH_MAX];
int ret = -1;
+ int i;
+ struct path_list list = {NULL, 0, 0, 1};
- while (*mbox) {
- const char *file = *mbox++;
- FILE *f = !strcmp(file, "-") ? stdin : fopen(file, "r");
- int file_done = 0;
+ snprintf(curdir, sizeof(curdir), "%s/cur", maildir);
+ if (populate_maildir_list(&list, curdir) < 0)
+ goto out;
- if ( !f ) {
- error("cannot open mbox %s", file);
+ for (i = 0; i < list.nr; i++) {
+ FILE *f;
+ snprintf(file, sizeof(file), "%s/%s", curdir, list.items[i].path);
+ f = fopen(file, "r");
+ if (!f) {
+ error("cannot open mail %s (%s)", file, strerror(errno));
goto out;
}
if (fgets(buf, sizeof(buf), f) == NULL) {
- if (f == stdin)
- break; /* empty stdin is OK */
- error("cannot read mbox %s", file);
+ error("cannot read mail %s (%s)", file, strerror(errno));
goto out;
}
- while (!file_done) {
- sprintf(name, "%s/%0*d", dir, nr_prec, ++skip);
- file_done = split_one(f, name, allow_bare);
+ sprintf(name, "%s/%0*d", dir, nr_prec, ++skip);
+ split_one(f, name, 1);
+
+ fclose(f);
+ }
+
+ path_list_clear(&list, 1);
+
+ ret = skip;
+out:
+ return ret;
+}
+
+static int split_mbox(const char *file, const char *dir, int allow_bare,
+ int nr_prec, int skip)
+{
+ char name[PATH_MAX];
+ int ret = -1;
+
+ FILE *f = !strcmp(file, "-") ? stdin : fopen(file, "r");
+ int file_done = 0;
+
+ if (!f) {
+ error("cannot open mbox %s", file);
+ goto out;
+ }
+
+ if (fgets(buf, sizeof(buf), f) == NULL) {
+ /* empty stdin is OK */
+ if (f != stdin) {
+ error("cannot read mbox %s", file);
+ goto out;
}
+ file_done = 1;
+ }
- if (f != stdin)
- fclose(f);
+ while (!file_done) {
+ sprintf(name, "%s/%0*d", dir, nr_prec, ++skip);
+ file_done = split_one(f, name, allow_bare);
}
+
+ if (f != stdin)
+ fclose(f);
+
ret = skip;
out:
- free(name);
return ret;
}
+
int cmd_mailsplit(int argc, const char **argv, const char *prefix)
{
- int nr = 0, nr_prec = 4, ret;
+ int nr = 0, nr_prec = 4, num = 0;
int allow_bare = 0;
const char *dir = NULL;
const char **argp;
@@ -186,9 +250,41 @@ int cmd_mailsplit(int argc, const char **argv, const char *prefix)
argp = stdin_only;
}
- ret = split_mbox(argp, dir, allow_bare, nr_prec, nr);
- if (ret != -1)
- printf("%d\n", ret);
+ while (*argp) {
+ const char *arg = *argp++;
+ struct stat argstat;
+ int ret = 0;
+
+ if (arg[0] == '-' && arg[1] == 0) {
+ ret = split_mbox(arg, dir, allow_bare, nr_prec, nr);
+ if (ret < 0) {
+ error("cannot split patches from stdin");
+ return 1;
+ }
+ num += (ret - nr);
+ nr = ret;
+ continue;
+ }
+
+ if (stat(arg, &argstat) == -1) {
+ error("cannot stat %s (%s)", arg, strerror(errno));
+ return 1;
+ }
+
+ if (S_ISDIR(argstat.st_mode))
+ ret = split_maildir(arg, dir, nr_prec, nr);
+ else
+ ret = split_mbox(arg, dir, allow_bare, nr_prec, nr);
+
+ if (ret < 0) {
+ error("cannot split patches from %s", arg);
+ return 1;
+ }
+ num += (ret - nr);
+ nr = ret;
+ }
+
+ printf("%d\n", num);
- return ret == -1;
+ return 0;
}
diff --git a/builtin-merge-base.c b/builtin-merge-base.c
index e35d362..0108e22 100644
--- a/builtin-merge-base.c
+++ b/builtin-merge-base.c
@@ -1,3 +1,4 @@
+#include "builtin.h"
#include "cache.h"
#include "commit.h"
diff --git a/builtin-merge-file.c b/builtin-merge-file.c
index 9135773..58deb62 100644
--- a/builtin-merge-file.c
+++ b/builtin-merge-file.c
@@ -1,3 +1,4 @@
+#include "builtin.h"
#include "cache.h"
#include "xdiff/xdiff.h"
#include "xdiff-interface.h"
@@ -5,9 +6,9 @@
static const char merge_file_usage[] =
"git merge-file [-p | --stdout] [-q | --quiet] [-L name1 [-L orig [-L name2]]] file1 orig_file file2";
-int cmd_merge_file(int argc, char **argv, char **envp)
+int cmd_merge_file(int argc, const char **argv, const char *prefix)
{
- char *names[3];
+ const char *names[3];
mmfile_t mmfs[3];
mmbuffer_t result = {NULL, 0};
xpparam_t xpp = {XDF_NEED_MINIMAL};
@@ -36,9 +37,13 @@ int cmd_merge_file(int argc, char **argv, char **envp)
for (; i < 3; i++)
names[i] = argv[i + 1];
- for (i = 0; i < 3; i++)
+ for (i = 0; i < 3; i++) {
if (read_mmfile(mmfs + i, argv[i + 1]))
return -1;
+ if (buffer_is_binary(mmfs[i].ptr, mmfs[i].size))
+ return error("Cannot merge binary files: %s\n",
+ argv[i + 1]);
+ }
ret = xdl_merge(mmfs + 1, mmfs + 0, names[0], mmfs + 2, names[2],
&xpp, XDL_MERGE_ZEALOUS, &result);
@@ -47,7 +52,7 @@ int cmd_merge_file(int argc, char **argv, char **envp)
free(mmfs[i].ptr);
if (ret >= 0) {
- char *filename = argv[1];
+ const char *filename = argv[1];
FILE *f = to_stdout ? stdout : fopen(filename, "wb");
if (!f)
diff --git a/builtin-name-rev.c b/builtin-name-rev.c
index 2d94eaa..61eba34 100644
--- a/builtin-name-rev.c
+++ b/builtin-name-rev.c
@@ -85,6 +85,7 @@ copy_data:
struct name_ref_data {
int tags_only;
+ int name_only;
const char *ref_filter;
};
@@ -112,6 +113,10 @@ static int name_ref(const char *path, const unsigned char *sha1, int flags, void
if (!prefixcmp(path, "refs/heads/"))
path = path + 11;
+ else if (data->tags_only
+ && data->name_only
+ && !prefixcmp(path, "refs/tags/"))
+ path = path + 10;
else if (!prefixcmp(path, "refs/"))
path = path + 5;
@@ -151,7 +156,7 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
{
struct object_array revs = { 0, 0, NULL };
int as_is = 0, all = 0, transform_stdin = 0;
- struct name_ref_data data = { 0, NULL };
+ struct name_ref_data data = { 0, 0, NULL };
git_config(git_default_config);
@@ -167,6 +172,9 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
if (!strcmp(*argv, "--")) {
as_is = 1;
continue;
+ } else if (!strcmp(*argv, "--name-only")) {
+ data.name_only = 1;
+ continue;
} else if (!strcmp(*argv, "--tags")) {
data.tags_only = 1;
continue;
@@ -267,16 +275,18 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
struct object * obj = get_indexed_object(i);
if (!obj)
continue;
- printf("%s %s\n", sha1_to_hex(obj->sha1), get_rev_name(obj));
+ if (!data.name_only)
+ printf("%s ", sha1_to_hex(obj->sha1));
+ printf("%s\n", get_rev_name(obj));
}
} else {
int i;
- for (i = 0; i < revs.nr; i++)
- printf("%s %s\n",
- revs.objects[i].name,
- get_rev_name(revs.objects[i].item));
+ for (i = 0; i < revs.nr; i++) {
+ if (!data.name_only)
+ printf("%s ", revs.objects[i].name);
+ printf("%s\n", get_rev_name(revs.objects[i].item));
+ }
}
return 0;
}
-
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 966f843..5e9d1fd 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -1,5 +1,6 @@
#include "builtin.h"
#include "cache.h"
+#include "attr.h"
#include "object.h"
#include "blob.h"
#include "commit.h"
@@ -16,18 +17,15 @@
static const char pack_usage[] = "\
git-pack-objects [{ -q | --progress | --all-progress }] \n\
- [--local] [--incremental] [--window=N] [--depth=N] \n\
- [--no-reuse-delta] [--delta-base-offset] [--non-empty] \n\
- [--revs [--unpacked | --all]*] [--reflog] [--stdout | base-name] \n\
- [<ref-list | <object-list]";
+ [--max-pack-size=N] [--local] [--incremental] \n\
+ [--window=N] [--window-memory=N] [--depth=N] \n\
+ [--no-reuse-delta] [--no-reuse-object] [--delta-base-offset] \n\
+ [--non-empty] [--revs [--unpacked | --all]*] [--reflog] \n\
+ [--stdout | base-name] [<ref-list | <object-list]";
struct object_entry {
- unsigned char sha1[20];
- uint32_t crc32; /* crc of raw pack data for this object */
- off_t offset; /* offset into the final pack file */
+ struct pack_idx_entry idx;
unsigned long size; /* uncompressed size */
- unsigned int hash; /* name hint hash */
- unsigned int depth; /* delta depth */
struct packed_git *in_pack; /* already in pack */
off_t in_pack_offset;
struct object_entry *delta; /* delta base object */
@@ -35,14 +33,17 @@ struct object_entry {
struct object_entry *delta_sibling; /* other deltified objects who
* uses the same base as me
*/
+ void *delta_data; /* cached delta (uncompressed) */
unsigned long delta_size; /* delta data size (uncompressed) */
+ unsigned int hash; /* name hint hash */
enum object_type type;
enum object_type in_pack_type; /* could be delta */
unsigned char in_pack_header_size;
unsigned char preferred_base; /* we do not pack this, but is available
- * to be used as the base objectto delta
+ * to be used as the base object to delta
* objects against.
*/
+ unsigned char no_try_delta;
};
/*
@@ -52,22 +53,33 @@ struct object_entry {
* nice "minimum seek" order.
*/
static struct object_entry *objects;
-static uint32_t nr_objects, nr_alloc, nr_result;
+static struct object_entry **written_list;
+static uint32_t nr_objects, nr_alloc, nr_result, nr_written;
static int non_empty;
-static int no_reuse_delta;
+static int no_reuse_delta, no_reuse_object;
static int local;
static int incremental;
static int allow_ofs_delta;
static const char *pack_tmp_name, *idx_tmp_name;
static char tmpname[PATH_MAX];
-static unsigned char pack_file_sha1[20];
+static const char *base_name;
static int progress = 1;
static int window = 10;
+static uint32_t pack_size_limit;
static int depth = 50;
static int pack_to_stdout;
static int num_preferred_base;
static struct progress progress_state;
+static int pack_compression_level = Z_DEFAULT_COMPRESSION;
+static int pack_compression_seen;
+
+static unsigned long delta_cache_size = 0;
+static unsigned long max_delta_cache_size = 0;
+static unsigned long cache_max_small_delta_size = 1000;
+
+static unsigned long window_memory_usage = 0;
+static unsigned long window_memory_limit = 0;
/*
* The object names in objects array are hashed with this hashtable,
@@ -234,15 +246,15 @@ static void *delta_against(void *buf, unsigned long size, struct object_entry *e
{
unsigned long othersize, delta_size;
enum object_type type;
- void *otherbuf = read_sha1_file(entry->delta->sha1, &type, &othersize);
+ void *otherbuf = read_sha1_file(entry->delta->idx.sha1, &type, &othersize);
void *delta_buf;
if (!otherbuf)
- die("unable to read %s", sha1_to_hex(entry->delta->sha1));
+ die("unable to read %s", sha1_to_hex(entry->delta->idx.sha1));
delta_buf = diff_delta(otherbuf, othersize,
buf, size, &delta_size, 0);
if (!delta_buf || delta_size != entry->delta_size)
- die("delta size changed");
+ die("delta size changed");
free(buf);
free(otherbuf);
return delta_buf;
@@ -346,76 +358,45 @@ static void copy_pack_data(struct sha1file *f,
}
}
-static int check_loose_inflate(unsigned char *data, unsigned long len, unsigned long expect)
-{
- z_stream stream;
- unsigned char fakebuf[4096];
- int st;
-
- memset(&stream, 0, sizeof(stream));
- stream.next_in = data;
- stream.avail_in = len;
- stream.next_out = fakebuf;
- stream.avail_out = sizeof(fakebuf);
- inflateInit(&stream);
-
- while (1) {
- st = inflate(&stream, Z_FINISH);
- if (st == Z_STREAM_END || st == Z_OK) {
- st = (stream.total_out == expect &&
- stream.total_in == len) ? 0 : -1;
- break;
- }
- if (st != Z_BUF_ERROR) {
- st = -1;
- break;
- }
- stream.next_out = fakebuf;
- stream.avail_out = sizeof(fakebuf);
- }
- inflateEnd(&stream);
- return st;
-}
-
-static int revalidate_loose_object(struct object_entry *entry,
- unsigned char *map,
- unsigned long mapsize)
-{
- /* we already know this is a loose object with new type header. */
- enum object_type type;
- unsigned long size, used;
-
- if (pack_to_stdout)
- return 0;
-
- used = unpack_object_header_gently(map, mapsize, &type, &size);
- if (!used)
- return -1;
- map += used;
- mapsize -= used;
- return check_loose_inflate(map, mapsize, size);
-}
-
static unsigned long write_object(struct sha1file *f,
- struct object_entry *entry)
+ struct object_entry *entry,
+ off_t write_offset)
{
unsigned long size;
enum object_type type;
void *buf;
unsigned char header[10];
+ unsigned char dheader[10];
unsigned hdrlen;
off_t datalen;
enum object_type obj_type;
int to_reuse = 0;
+ /* write limit if limited packsize and not first object */
+ unsigned long limit = pack_size_limit && nr_written ?
+ pack_size_limit - write_offset : 0;
+ /* no if no delta */
+ int usable_delta = !entry->delta ? 0 :
+ /* yes if unlimited packfile */
+ !pack_size_limit ? 1 :
+ /* no if base written to previous pack */
+ entry->delta->idx.offset == (off_t)-1 ? 0 :
+ /* otherwise double-check written to this
+ * pack, like we do below
+ */
+ entry->delta->idx.offset ? 1 : 0;
if (!pack_to_stdout)
crc32_begin(f);
obj_type = entry->type;
- if (! entry->in_pack)
+ if (no_reuse_object)
+ to_reuse = 0; /* explicit */
+ else if (!entry->in_pack)
to_reuse = 0; /* can't reuse what we don't have */
else if (obj_type == OBJ_REF_DELTA || obj_type == OBJ_OFS_DELTA)
- to_reuse = 1; /* check_object() decided it for us */
+ /* check_object() decided it for us ... */
+ to_reuse = usable_delta;
+ /* ... but pack split may override that */
else if (obj_type != entry->in_pack_type)
to_reuse = 0; /* pack has delta which is unusable */
else if (entry->delta)
@@ -425,44 +406,49 @@ static unsigned long write_object(struct sha1file *f,
* and we do not need to deltify it.
*/
- if (!entry->in_pack && !entry->delta) {
- unsigned char *map;
- unsigned long mapsize;
- map = map_sha1_file(entry->sha1, &mapsize);
- if (map && !legacy_loose_object(map)) {
- /* We can copy straight into the pack file */
- if (revalidate_loose_object(entry, map, mapsize))
- die("corrupt loose object %s",
- sha1_to_hex(entry->sha1));
- sha1write(f, map, mapsize);
- munmap(map, mapsize);
- written++;
- reused++;
- return mapsize;
- }
- if (map)
- munmap(map, mapsize);
- }
-
if (!to_reuse) {
- buf = read_sha1_file(entry->sha1, &type, &size);
- if (!buf)
- die("unable to read %s", sha1_to_hex(entry->sha1));
- if (size != entry->size)
- die("object %s size inconsistency (%lu vs %lu)",
- sha1_to_hex(entry->sha1), size, entry->size);
- if (entry->delta) {
+ z_stream stream;
+ unsigned long maxsize;
+ void *out;
+ if (!usable_delta) {
+ buf = read_sha1_file(entry->idx.sha1, &obj_type, &size);
+ if (!buf)
+ die("unable to read %s", sha1_to_hex(entry->idx.sha1));
+ } else if (entry->delta_data) {
+ size = entry->delta_size;
+ buf = entry->delta_data;
+ entry->delta_data = NULL;
+ obj_type = (allow_ofs_delta && entry->delta->idx.offset) ?
+ OBJ_OFS_DELTA : OBJ_REF_DELTA;
+ } else {
+ buf = read_sha1_file(entry->idx.sha1, &type, &size);
+ if (!buf)
+ die("unable to read %s", sha1_to_hex(entry->idx.sha1));
buf = delta_against(buf, size, entry);
size = entry->delta_size;
- obj_type = (allow_ofs_delta && entry->delta->offset) ?
+ obj_type = (allow_ofs_delta && entry->delta->idx.offset) ?
OBJ_OFS_DELTA : OBJ_REF_DELTA;
}
+ /* compress the data to store and put compressed length in datalen */
+ memset(&stream, 0, sizeof(stream));
+ deflateInit(&stream, pack_compression_level);
+ maxsize = deflateBound(&stream, size);
+ out = xmalloc(maxsize);
+ /* Compress it */
+ stream.next_in = buf;
+ stream.avail_in = size;
+ stream.next_out = out;
+ stream.avail_out = maxsize;
+ while (deflate(&stream, Z_FINISH) == Z_OK)
+ /* nothing */;
+ deflateEnd(&stream);
+ datalen = stream.total_out;
+ deflateEnd(&stream);
/*
* The object header is a byte of 'type' followed by zero or
* more bytes of length.
*/
hdrlen = encode_header(obj_type, size, header);
- sha1write(f, header, hdrlen);
if (obj_type == OBJ_OFS_DELTA) {
/*
@@ -470,22 +456,42 @@ static unsigned long write_object(struct sha1file *f,
* encoding of the relative offset for the delta
* base from this object's position in the pack.
*/
- off_t ofs = entry->offset - entry->delta->offset;
- unsigned pos = sizeof(header) - 1;
- header[pos] = ofs & 127;
+ off_t ofs = entry->idx.offset - entry->delta->idx.offset;
+ unsigned pos = sizeof(dheader) - 1;
+ dheader[pos] = ofs & 127;
while (ofs >>= 7)
- header[--pos] = 128 | (--ofs & 127);
- sha1write(f, header + pos, sizeof(header) - pos);
- hdrlen += sizeof(header) - pos;
+ dheader[--pos] = 128 | (--ofs & 127);
+ if (limit && hdrlen + sizeof(dheader) - pos + datalen + 20 >= limit) {
+ free(out);
+ free(buf);
+ return 0;
+ }
+ sha1write(f, header, hdrlen);
+ sha1write(f, dheader + pos, sizeof(dheader) - pos);
+ hdrlen += sizeof(dheader) - pos;
} else if (obj_type == OBJ_REF_DELTA) {
/*
* Deltas with a base reference contain
* an additional 20 bytes for the base sha1.
*/
- sha1write(f, entry->delta->sha1, 20);
+ if (limit && hdrlen + 20 + datalen + 20 >= limit) {
+ free(out);
+ free(buf);
+ return 0;
+ }
+ sha1write(f, header, hdrlen);
+ sha1write(f, entry->delta->idx.sha1, 20);
hdrlen += 20;
+ } else {
+ if (limit && hdrlen + datalen + 20 >= limit) {
+ free(out);
+ free(buf);
+ return 0;
+ }
+ sha1write(f, header, hdrlen);
}
- datalen = sha1write_compressed(f, buf, size);
+ sha1write(f, out, datalen);
+ free(out);
free(buf);
}
else {
@@ -495,45 +501,54 @@ static unsigned long write_object(struct sha1file *f,
off_t offset;
if (entry->delta) {
- obj_type = (allow_ofs_delta && entry->delta->offset) ?
+ obj_type = (allow_ofs_delta && entry->delta->idx.offset) ?
OBJ_OFS_DELTA : OBJ_REF_DELTA;
reused_delta++;
}
hdrlen = encode_header(obj_type, entry->size, header);
- sha1write(f, header, hdrlen);
- if (obj_type == OBJ_OFS_DELTA) {
- off_t ofs = entry->offset - entry->delta->offset;
- unsigned pos = sizeof(header) - 1;
- header[pos] = ofs & 127;
- while (ofs >>= 7)
- header[--pos] = 128 | (--ofs & 127);
- sha1write(f, header + pos, sizeof(header) - pos);
- hdrlen += sizeof(header) - pos;
- } else if (obj_type == OBJ_REF_DELTA) {
- sha1write(f, entry->delta->sha1, 20);
- hdrlen += 20;
- }
-
offset = entry->in_pack_offset;
revidx = find_packed_object(p, offset);
datalen = revidx[1].offset - offset;
if (!pack_to_stdout && p->index_version > 1 &&
check_pack_crc(p, &w_curs, offset, datalen, revidx->nr))
- die("bad packed object CRC for %s", sha1_to_hex(entry->sha1));
+ die("bad packed object CRC for %s", sha1_to_hex(entry->idx.sha1));
offset += entry->in_pack_header_size;
datalen -= entry->in_pack_header_size;
+ if (obj_type == OBJ_OFS_DELTA) {
+ off_t ofs = entry->idx.offset - entry->delta->idx.offset;
+ unsigned pos = sizeof(dheader) - 1;
+ dheader[pos] = ofs & 127;
+ while (ofs >>= 7)
+ dheader[--pos] = 128 | (--ofs & 127);
+ if (limit && hdrlen + sizeof(dheader) - pos + datalen + 20 >= limit)
+ return 0;
+ sha1write(f, header, hdrlen);
+ sha1write(f, dheader + pos, sizeof(dheader) - pos);
+ hdrlen += sizeof(dheader) - pos;
+ } else if (obj_type == OBJ_REF_DELTA) {
+ if (limit && hdrlen + 20 + datalen + 20 >= limit)
+ return 0;
+ sha1write(f, header, hdrlen);
+ sha1write(f, entry->delta->idx.sha1, 20);
+ hdrlen += 20;
+ } else {
+ if (limit && hdrlen + datalen + 20 >= limit)
+ return 0;
+ sha1write(f, header, hdrlen);
+ }
+
if (!pack_to_stdout && p->index_version == 1 &&
check_pack_inflate(p, &w_curs, offset, datalen, entry->size))
- die("corrupt packed object for %s", sha1_to_hex(entry->sha1));
+ die("corrupt packed object for %s", sha1_to_hex(entry->idx.sha1));
copy_pack_data(f, p, &w_curs, offset, datalen);
unuse_pack(&w_curs);
reused++;
}
- if (entry->delta)
+ if (usable_delta)
written_delta++;
written++;
if (!pack_to_stdout)
- entry->crc32 = crc32_end(f);
+ entry->idx.crc32 = crc32_end(f);
return hdrlen + datalen;
}
@@ -544,15 +559,23 @@ static off_t write_one(struct sha1file *f,
unsigned long size;
/* offset is non zero if object is written already. */
- if (e->offset || e->preferred_base)
+ if (e->idx.offset || e->preferred_base)
return offset;
/* if we are deltified, write out base object first. */
- if (e->delta)
+ if (e->delta) {
offset = write_one(f, e->delta, offset);
+ if (!offset)
+ return 0;
+ }
- e->offset = offset;
- size = write_object(f, e);
+ e->idx.offset = offset;
+ size = write_object(f, e, offset);
+ if (!size) {
+ e->idx.offset = 0;
+ return 0;
+ }
+ written_list[nr_written++] = e;
/* make sure off_t is sufficiently large not to wrap */
if (offset > offset + size)
@@ -566,174 +589,114 @@ static int open_object_dir_tmp(const char *path)
return mkstemp(tmpname);
}
-static off_t write_pack_file(void)
+/* forward declaration for write_pack_file */
+static int adjust_perm(const char *path, mode_t mode);
+
+static void write_pack_file(void)
{
- uint32_t i;
+ uint32_t i = 0, j;
struct sha1file *f;
- off_t offset, last_obj_offset = 0;
+ off_t offset, offset_one, last_obj_offset = 0;
struct pack_header hdr;
- int do_progress = progress;
-
- if (pack_to_stdout) {
- f = sha1fd(1, "<stdout>");
- do_progress >>= 1;
- } else {
- int fd = open_object_dir_tmp("tmp_pack_XXXXXX");
- if (fd < 0)
- die("unable to create %s: %s\n", tmpname, strerror(errno));
- pack_tmp_name = xstrdup(tmpname);
- f = sha1fd(fd, pack_tmp_name);
- }
+ int do_progress = progress >> pack_to_stdout;
+ uint32_t nr_remaining = nr_result;
if (do_progress)
start_progress(&progress_state, "Writing %u objects...", "", nr_result);
+ written_list = xmalloc(nr_objects * sizeof(struct object_entry *));
- hdr.hdr_signature = htonl(PACK_SIGNATURE);
- hdr.hdr_version = htonl(PACK_VERSION);
- hdr.hdr_entries = htonl(nr_result);
- sha1write(f, &hdr, sizeof(hdr));
- offset = sizeof(hdr);
- if (!nr_result)
- goto done;
- for (i = 0; i < nr_objects; i++) {
- last_obj_offset = offset;
- offset = write_one(f, objects + i, offset);
- if (do_progress)
- display_progress(&progress_state, written);
- }
- if (do_progress)
- stop_progress(&progress_state);
- done:
- if (written != nr_result)
- die("wrote %u objects while expecting %u", written, nr_result);
- sha1close(f, pack_file_sha1, 1);
-
- return last_obj_offset;
-}
-
-static int sha1_sort(const void *_a, const void *_b)
-{
- const struct object_entry *a = *(struct object_entry **)_a;
- const struct object_entry *b = *(struct object_entry **)_b;
- return hashcmp(a->sha1, b->sha1);
-}
-
-static uint32_t index_default_version = 1;
-static uint32_t index_off32_limit = 0x7fffffff;
-
-static void write_index_file(off_t last_obj_offset, unsigned char *sha1)
-{
- struct sha1file *f;
- struct object_entry **sorted_by_sha, **list, **last;
- uint32_t array[256];
- uint32_t i, index_version;
- SHA_CTX ctx;
-
- int fd = open_object_dir_tmp("tmp_idx_XXXXXX");
- if (fd < 0)
- die("unable to create %s: %s\n", tmpname, strerror(errno));
- idx_tmp_name = xstrdup(tmpname);
- f = sha1fd(fd, idx_tmp_name);
-
- if (nr_result) {
- uint32_t j = 0;
- sorted_by_sha =
- xcalloc(nr_result, sizeof(struct object_entry *));
- for (i = 0; i < nr_objects; i++)
- if (!objects[i].preferred_base)
- sorted_by_sha[j++] = objects + i;
- if (j != nr_result)
- die("listed %u objects while expecting %u", j, nr_result);
- qsort(sorted_by_sha, nr_result, sizeof(*sorted_by_sha), sha1_sort);
- list = sorted_by_sha;
- last = sorted_by_sha + nr_result;
- } else
- sorted_by_sha = list = last = NULL;
-
- /* if last object's offset is >= 2^31 we should use index V2 */
- index_version = (last_obj_offset >> 31) ? 2 : index_default_version;
+ do {
+ unsigned char sha1[20];
+
+ if (pack_to_stdout) {
+ f = sha1fd(1, "<stdout>");
+ } else {
+ int fd = open_object_dir_tmp("tmp_pack_XXXXXX");
+ if (fd < 0)
+ die("unable to create %s: %s\n", tmpname, strerror(errno));
+ pack_tmp_name = xstrdup(tmpname);
+ f = sha1fd(fd, pack_tmp_name);
+ }
- /* index versions 2 and above need a header */
- if (index_version >= 2) {
- struct pack_idx_header hdr;
- hdr.idx_signature = htonl(PACK_IDX_SIGNATURE);
- hdr.idx_version = htonl(index_version);
+ hdr.hdr_signature = htonl(PACK_SIGNATURE);
+ hdr.hdr_version = htonl(PACK_VERSION);
+ hdr.hdr_entries = htonl(nr_remaining);
sha1write(f, &hdr, sizeof(hdr));
- }
-
- /*
- * Write the first-level table (the list is sorted,
- * but we use a 256-entry lookup to be able to avoid
- * having to do eight extra binary search iterations).
- */
- for (i = 0; i < 256; i++) {
- struct object_entry **next = list;
- while (next < last) {
- struct object_entry *entry = *next;
- if (entry->sha1[0] != i)
+ offset = sizeof(hdr);
+ nr_written = 0;
+ for (; i < nr_objects; i++) {
+ last_obj_offset = offset;
+ offset_one = write_one(f, objects + i, offset);
+ if (!offset_one)
break;
- next++;
+ offset = offset_one;
+ if (do_progress)
+ display_progress(&progress_state, written);
}
- array[i] = htonl(next - sorted_by_sha);
- list = next;
- }
- sha1write(f, array, 256 * 4);
-
- /* Compute the SHA1 hash of sorted object names. */
- SHA1_Init(&ctx);
-
- /* Write the actual SHA1 entries. */
- list = sorted_by_sha;
- for (i = 0; i < nr_result; i++) {
- struct object_entry *entry = *list++;
- if (index_version < 2) {
- uint32_t offset = htonl(entry->offset);
- sha1write(f, &offset, 4);
- }
- sha1write(f, entry->sha1, 20);
- SHA1_Update(&ctx, entry->sha1, 20);
- }
- if (index_version >= 2) {
- unsigned int nr_large_offset = 0;
-
- /* write the crc32 table */
- list = sorted_by_sha;
- for (i = 0; i < nr_objects; i++) {
- struct object_entry *entry = *list++;
- uint32_t crc32_val = htonl(entry->crc32);
- sha1write(f, &crc32_val, 4);
+ /*
+ * Did we write the wrong # entries in the header?
+ * If so, rewrite it like in fast-import
+ */
+ if (pack_to_stdout || nr_written == nr_remaining) {
+ sha1close(f, sha1, 1);
+ } else {
+ sha1close(f, sha1, 0);
+ fixup_pack_header_footer(f->fd, sha1, pack_tmp_name, nr_written);
+ close(f->fd);
}
- /* write the 32-bit offset table */
- list = sorted_by_sha;
- for (i = 0; i < nr_objects; i++) {
- struct object_entry *entry = *list++;
- uint32_t offset = (entry->offset <= index_off32_limit) ?
- entry->offset : (0x80000000 | nr_large_offset++);
- offset = htonl(offset);
- sha1write(f, &offset, 4);
+ if (!pack_to_stdout) {
+ mode_t mode = umask(0);
+
+ umask(mode);
+ mode = 0444 & ~mode;
+
+ idx_tmp_name = write_idx_file(NULL,
+ (struct pack_idx_entry **) written_list, nr_written, sha1);
+ snprintf(tmpname, sizeof(tmpname), "%s-%s.pack",
+ base_name, sha1_to_hex(sha1));
+ if (adjust_perm(pack_tmp_name, mode))
+ die("unable to make temporary pack file readable: %s",
+ strerror(errno));
+ if (rename(pack_tmp_name, tmpname))
+ die("unable to rename temporary pack file: %s",
+ strerror(errno));
+ snprintf(tmpname, sizeof(tmpname), "%s-%s.idx",
+ base_name, sha1_to_hex(sha1));
+ if (adjust_perm(idx_tmp_name, mode))
+ die("unable to make temporary index file readable: %s",
+ strerror(errno));
+ if (rename(idx_tmp_name, tmpname))
+ die("unable to rename temporary index file: %s",
+ strerror(errno));
+ puts(sha1_to_hex(sha1));
}
- /* write the large offset table */
- list = sorted_by_sha;
- while (nr_large_offset) {
- struct object_entry *entry = *list++;
- uint64_t offset = entry->offset;
- if (offset > index_off32_limit) {
- uint32_t split[2];
- split[0] = htonl(offset >> 32);
- split[1] = htonl(offset & 0xffffffff);
- sha1write(f, split, 8);
- nr_large_offset--;
- }
+ /* mark written objects as written to previous pack */
+ for (j = 0; j < nr_written; j++) {
+ written_list[j]->idx.offset = (off_t)-1;
}
- }
+ nr_remaining -= nr_written;
+ } while (nr_remaining && i < nr_objects);
- sha1write(f, pack_file_sha1, 20);
- sha1close(f, NULL, 1);
- free(sorted_by_sha);
- SHA1_Final(sha1, &ctx);
+ free(written_list);
+ if (do_progress)
+ stop_progress(&progress_state);
+ if (written != nr_result)
+ die("wrote %u objects while expecting %u", written, nr_result);
+ /*
+ * We have scanned through [0 ... i). Since we have written
+ * the correct number of objects, the remaining [i ... nr_objects)
+ * items must be either already written (due to out-of-order delta base)
+ * or a preferred base. Count those which are neither and complain if any.
+ */
+ for (j = 0; i < nr_objects; i++) {
+ struct object_entry *e = objects + i;
+ j += !e->idx.offset && !e->preferred_base;
+ }
+ if (j)
+ die("wrote %u objects as expected but %u unwritten", written, j);
}
static int locate_object_entry_hash(const unsigned char *sha1)
@@ -743,7 +706,7 @@ static int locate_object_entry_hash(const unsigned char *sha1)
memcpy(&ui, sha1, sizeof(unsigned int));
i = ui % object_ix_hashsz;
while (0 < object_ix[i]) {
- if (!hashcmp(sha1, objects[object_ix[i] - 1].sha1))
+ if (!hashcmp(sha1, objects[object_ix[i] - 1].idx.sha1))
return i;
if (++i == object_ix_hashsz)
i = 0;
@@ -775,7 +738,7 @@ static void rehash_objects(void)
object_ix = xrealloc(object_ix, sizeof(int) * object_ix_hashsz);
memset(object_ix, 0, sizeof(int) * object_ix_hashsz);
for (i = 0, oe = objects; i < nr_objects; i++, oe++) {
- int ix = locate_object_entry_hash(oe->sha1);
+ int ix = locate_object_entry_hash(oe->idx.sha1);
if (0 <= ix)
continue;
ix = -1 - ix;
@@ -788,6 +751,9 @@ static unsigned name_hash(const char *name)
unsigned char c;
unsigned hash = 0;
+ if (!name)
+ return 0;
+
/*
* This effectively just creates a sortable number from the
* last sixteen non-whitespace characters. Last characters
@@ -801,13 +767,36 @@ static unsigned name_hash(const char *name)
return hash;
}
+static void setup_delta_attr_check(struct git_attr_check *check)
+{
+ static struct git_attr *attr_delta;
+
+ if (!attr_delta)
+ attr_delta = git_attr("delta", 5);
+
+ check[0].attr = attr_delta;
+}
+
+static int no_try_delta(const char *path)
+{
+ struct git_attr_check check[1];
+
+ setup_delta_attr_check(check);
+ if (git_checkattr(path, ARRAY_SIZE(check), check))
+ return 0;
+ if (ATTR_FALSE(check->value))
+ return 1;
+ return 0;
+}
+
static int add_object_entry(const unsigned char *sha1, enum object_type type,
- unsigned hash, int exclude)
+ const char *name, int exclude)
{
struct object_entry *entry;
struct packed_git *p, *found_pack = NULL;
off_t found_offset = 0;
int ix;
+ unsigned hash = name_hash(name);
ix = nr_objects ? locate_object_entry_hash(sha1) : -1;
if (ix >= 0) {
@@ -843,7 +832,7 @@ static int add_object_entry(const unsigned char *sha1, enum object_type type,
entry = objects + nr_objects++;
memset(entry, 0, sizeof(*entry));
- hashcpy(entry->sha1, sha1);
+ hashcpy(entry->idx.sha1, sha1);
entry->hash = hash;
if (type)
entry->type = type;
@@ -864,6 +853,9 @@ static int add_object_entry(const unsigned char *sha1, enum object_type type,
if (progress)
display_progress(&progress_state, nr_objects);
+ if (name && no_try_delta(name))
+ entry->no_try_delta = 1;
+
return 1;
}
@@ -996,10 +988,9 @@ static void add_pbase_object(struct tree_desc *tree,
if (cmp < 0)
return;
if (name[cmplen] != '/') {
- unsigned hash = name_hash(fullname);
add_object_entry(entry.sha1,
S_ISDIR(entry.mode) ? OBJ_TREE : OBJ_BLOB,
- hash, 1);
+ fullname, 1);
return;
}
if (S_ISDIR(entry.mode)) {
@@ -1059,10 +1050,11 @@ static int check_pbase_path(unsigned hash)
return 0;
}
-static void add_preferred_base_object(const char *name, unsigned hash)
+static void add_preferred_base_object(const char *name)
{
struct pbase_tree *it;
int cmplen;
+ unsigned hash = name_hash(name);
if (!num_preferred_base || check_pbase_path(hash))
return;
@@ -1070,7 +1062,7 @@ static void add_preferred_base_object(const char *name, unsigned hash)
cmplen = name_cmp_len(name);
for (it = pbase_tree; it; it = it->next) {
if (cmplen == 0) {
- add_object_entry(it->pcache.sha1, OBJ_TREE, 0, 1);
+ add_object_entry(it->pcache.sha1, OBJ_TREE, NULL, 1);
}
else {
struct tree_desc tree;
@@ -1125,8 +1117,8 @@ static void check_object(struct object_entry *entry)
buf = use_pack(p, &w_curs, entry->in_pack_offset, &avail);
/*
- * We want in_pack_type even if we do not reuse delta.
- * There is no point not reusing non-delta representations.
+ * We want in_pack_type even if we do not reuse delta
+ * since non-delta representations could still be reused.
*/
used = unpack_object_header_gently(buf, avail,
&entry->in_pack_type,
@@ -1160,13 +1152,13 @@ static void check_object(struct object_entry *entry)
ofs += 1;
if (!ofs || MSB(ofs, 7))
die("delta base offset overflow in pack for %s",
- sha1_to_hex(entry->sha1));
+ sha1_to_hex(entry->idx.sha1));
c = buf[used_0++];
ofs = (ofs << 7) + (c & 127);
}
if (ofs >= entry->in_pack_offset)
die("delta base offset out of bound for %s",
- sha1_to_hex(entry->sha1));
+ sha1_to_hex(entry->idx.sha1));
ofs = entry->in_pack_offset - ofs;
if (!no_reuse_delta && !entry->preferred_base)
base_ref = find_packed_object_name(p, ofs);
@@ -1213,10 +1205,10 @@ static void check_object(struct object_entry *entry)
unuse_pack(&w_curs);
}
- entry->type = sha1_object_info(entry->sha1, &entry->size);
+ entry->type = sha1_object_info(entry->idx.sha1, &entry->size);
if (entry->type < 0)
die("unable to get type of object %s",
- sha1_to_hex(entry->sha1));
+ sha1_to_hex(entry->idx.sha1));
}
static int pack_offset_sort(const void *_a, const void *_b)
@@ -1226,7 +1218,7 @@ static int pack_offset_sort(const void *_a, const void *_b)
/* avoid filesystem trashing with loose objects */
if (!a->in_pack && !b->in_pack)
- return hashcmp(a->sha1, b->sha1);
+ return hashcmp(a->idx.sha1, b->idx.sha1);
if (a->in_pack < b->in_pack)
return -1;
@@ -1280,8 +1272,26 @@ struct unpacked {
struct object_entry *entry;
void *data;
struct delta_index *index;
+ unsigned depth;
};
+static int delta_cacheable(struct unpacked *trg, struct unpacked *src,
+ unsigned long src_size, unsigned long trg_size,
+ unsigned long delta_size)
+{
+ if (max_delta_cache_size && delta_cache_size + delta_size > max_delta_cache_size)
+ return 0;
+
+ if (delta_size < cache_max_small_delta_size)
+ return 1;
+
+ /* cache delta, if objects are large enough compared to delta size */
+ if ((src_size >> 20) + (trg_size >> 21) > (delta_size >> 10))
+ return 1;
+
+ return 0;
+}
+
/*
* We search for deltas _backwards_ in a list sorted by type and
* by size, so that we see progressively smaller and smaller files.
@@ -1296,6 +1306,7 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
struct object_entry *trg_entry = trg->entry;
struct object_entry *src_entry = src->entry;
unsigned long trg_size, src_size, delta_size, sizediff, max_size, sz;
+ unsigned ref_depth;
enum object_type type;
void *delta_buf;
@@ -1320,49 +1331,79 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
return 0;
/* Let's not bust the allowed depth. */
- if (src_entry->depth >= max_depth)
+ if (src->depth >= max_depth)
return 0;
/* Now some size filtering heuristics. */
trg_size = trg_entry->size;
- max_size = trg_size/2 - 20;
- max_size = max_size * (max_depth - src_entry->depth) / max_depth;
+ if (!trg_entry->delta) {
+ max_size = trg_size/2 - 20;
+ ref_depth = 1;
+ } else {
+ max_size = trg_entry->delta_size;
+ ref_depth = trg->depth;
+ }
+ max_size = max_size * (max_depth - src->depth) /
+ (max_depth - ref_depth + 1);
if (max_size == 0)
return 0;
- if (trg_entry->delta && trg_entry->delta_size <= max_size)
- max_size = trg_entry->delta_size-1;
src_size = src_entry->size;
sizediff = src_size < trg_size ? trg_size - src_size : 0;
if (sizediff >= max_size)
return 0;
+ if (trg_size < src_size / 32)
+ return 0;
/* Load data if not already done */
if (!trg->data) {
- trg->data = read_sha1_file(trg_entry->sha1, &type, &sz);
+ trg->data = read_sha1_file(trg_entry->idx.sha1, &type, &sz);
if (sz != trg_size)
die("object %s inconsistent object length (%lu vs %lu)",
- sha1_to_hex(trg_entry->sha1), sz, trg_size);
+ sha1_to_hex(trg_entry->idx.sha1), sz, trg_size);
+ window_memory_usage += sz;
}
if (!src->data) {
- src->data = read_sha1_file(src_entry->sha1, &type, &sz);
+ src->data = read_sha1_file(src_entry->idx.sha1, &type, &sz);
if (sz != src_size)
die("object %s inconsistent object length (%lu vs %lu)",
- sha1_to_hex(src_entry->sha1), sz, src_size);
+ sha1_to_hex(src_entry->idx.sha1), sz, src_size);
+ window_memory_usage += sz;
}
if (!src->index) {
src->index = create_delta_index(src->data, src_size);
- if (!src->index)
- die("out of memory");
+ if (!src->index) {
+ static int warned = 0;
+ if (!warned++)
+ warning("suboptimal pack - out of memory");
+ return 0;
+ }
+ window_memory_usage += sizeof_delta_index(src->index);
}
delta_buf = create_delta(src->index, trg->data, trg_size, &delta_size, max_size);
if (!delta_buf)
return 0;
+ if (trg_entry->delta_data) {
+ /* Prefer only shallower same-sized deltas. */
+ if (delta_size == trg_entry->delta_size &&
+ src->depth + 1 >= trg->depth) {
+ free(delta_buf);
+ return 0;
+ }
+ delta_cache_size -= trg_entry->delta_size;
+ free(trg_entry->delta_data);
+ trg_entry->delta_data = NULL;
+ }
trg_entry->delta = src_entry;
trg_entry->delta_size = delta_size;
- trg_entry->depth = src_entry->depth + 1;
- free(delta_buf);
+ trg->depth = src->depth + 1;
+
+ if (delta_cacheable(src, trg, src_size, trg_size, delta_size)) {
+ trg_entry->delta_data = xrealloc(delta_buf, delta_size);
+ delta_cache_size += trg_entry->delta_size;
+ } else
+ free(delta_buf);
return 1;
}
@@ -1379,9 +1420,23 @@ static unsigned int check_delta_limit(struct object_entry *me, unsigned int n)
return m;
}
+static void free_unpacked(struct unpacked *n)
+{
+ window_memory_usage -= sizeof_delta_index(n->index);
+ free_delta_index(n->index);
+ n->index = NULL;
+ if (n->data) {
+ free(n->data);
+ n->data = NULL;
+ window_memory_usage -= n->entry->size;
+ }
+ n->entry = NULL;
+ n->depth = 0;
+}
+
static void find_deltas(struct object_entry **list, int window, int depth)
{
- uint32_t i = nr_objects, idx = 0, processed = 0;
+ uint32_t i = nr_objects, idx = 0, count = 0, processed = 0;
unsigned int array_size = window * sizeof(struct unpacked);
struct unpacked *array;
int max_depth;
@@ -1412,12 +1467,21 @@ static void find_deltas(struct object_entry **list, int window, int depth)
if (entry->size < 50)
continue;
- free_delta_index(n->index);
- n->index = NULL;
- free(n->data);
- n->data = NULL;
+
+ if (entry->no_try_delta)
+ continue;
+
+ free_unpacked(n);
n->entry = entry;
+ while (window_memory_limit &&
+ window_memory_usage > window_memory_limit &&
+ count > 1) {
+ uint32_t tail = (idx + window - count) % window;
+ free_unpacked(array + tail);
+ count--;
+ }
+
/*
* If the current object is at pack edge, take the depth the
* objects that depend on the current object into account
@@ -1447,11 +1511,13 @@ static void find_deltas(struct object_entry **list, int window, int depth)
* depth, leaving it in the window is pointless. we
* should evict it first.
*/
- if (entry->delta && depth <= entry->depth)
+ if (entry->delta && depth <= n->depth)
continue;
next:
idx++;
+ if (count + 1 < window)
+ count++;
if (idx >= window)
idx = 0;
} while (i > 0);
@@ -1490,10 +1556,32 @@ static int git_pack_config(const char *k, const char *v)
window = git_config_int(k, v);
return 0;
}
- if(!strcmp(k, "pack.depth")) {
+ if (!strcmp(k, "pack.windowmemory")) {
+ window_memory_limit = git_config_ulong(k, v);
+ return 0;
+ }
+ if (!strcmp(k, "pack.depth")) {
depth = git_config_int(k, v);
return 0;
}
+ if (!strcmp(k, "pack.compression")) {
+ int level = git_config_int(k, v);
+ if (level == -1)
+ level = Z_DEFAULT_COMPRESSION;
+ else if (level < 0 || level > Z_BEST_COMPRESSION)
+ die("bad pack compression level %d", level);
+ pack_compression_level = level;
+ pack_compression_seen = 1;
+ return 0;
+ }
+ if (!strcmp(k, "pack.deltacachesize")) {
+ max_delta_cache_size = git_config_int(k, v);
+ return 0;
+ }
+ if (!strcmp(k, "pack.deltacachelimit")) {
+ cache_max_small_delta_size = git_config_int(k, v);
+ return 0;
+ }
return git_default_config(k, v);
}
@@ -1501,7 +1589,6 @@ static void read_object_list_from_stdin(void)
{
char line[40 + 1 + PATH_MAX + 2];
unsigned char sha1[20];
- unsigned hash;
for (;;) {
if (!fgets(line, sizeof(line), stdin)) {
@@ -1524,22 +1611,20 @@ static void read_object_list_from_stdin(void)
if (get_sha1_hex(line, sha1))
die("expected sha1, got garbage:\n %s", line);
- hash = name_hash(line+41);
- add_preferred_base_object(line+41, hash);
- add_object_entry(sha1, 0, hash, 0);
+ add_preferred_base_object(line+41);
+ add_object_entry(sha1, 0, line+41, 0);
}
}
static void show_commit(struct commit *commit)
{
- add_object_entry(commit->object.sha1, OBJ_COMMIT, 0, 0);
+ add_object_entry(commit->object.sha1, OBJ_COMMIT, NULL, 0);
}
static void show_object(struct object_array_entry *p)
{
- unsigned hash = name_hash(p->name);
- add_preferred_base_object(p->name, hash);
- add_object_entry(p->item->sha1, p->item->type, hash, 0);
+ add_preferred_base_object(p->name);
+ add_object_entry(p->item->sha1, p->item->type, p->name, 0);
}
static void show_edge(struct commit *commit)
@@ -1592,8 +1677,6 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
int use_internal_rev_list = 0;
int thin = 0;
uint32_t i;
- off_t last_obj_offset;
- const char *base_name = NULL;
const char **rp_av;
int rp_ac_alloc = 64;
int rp_ac;
@@ -1605,6 +1688,8 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
rp_ac = 2;
git_config(git_pack_config);
+ if (!pack_compression_seen && core_compression_seen)
+ pack_compression_level = core_compression_level;
progress = isatty(2);
for (i = 1; i < argc; i++) {
@@ -1625,6 +1710,25 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
incremental = 1;
continue;
}
+ if (!prefixcmp(arg, "--compression=")) {
+ char *end;
+ int level = strtoul(arg+14, &end, 0);
+ if (!arg[14] || *end)
+ usage(pack_usage);
+ if (level == -1)
+ level = Z_DEFAULT_COMPRESSION;
+ else if (level < 0 || level > Z_BEST_COMPRESSION)
+ die("bad pack compression level %d", level);
+ pack_compression_level = level;
+ continue;
+ }
+ if (!prefixcmp(arg, "--max-pack-size=")) {
+ char *end;
+ pack_size_limit = strtoul(arg+16, &end, 0) * 1024 * 1024;
+ if (!arg[16] || *end)
+ usage(pack_usage);
+ continue;
+ }
if (!prefixcmp(arg, "--window=")) {
char *end;
window = strtoul(arg+9, &end, 0);
@@ -1632,6 +1736,11 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
usage(pack_usage);
continue;
}
+ if (!prefixcmp(arg, "--window-memory=")) {
+ if (!git_parse_ulong(arg+16, &window_memory_limit))
+ usage(pack_usage);
+ continue;
+ }
if (!prefixcmp(arg, "--depth=")) {
char *end;
depth = strtoul(arg+8, &end, 0);
@@ -1655,6 +1764,10 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
no_reuse_delta = 1;
continue;
}
+ if (!strcmp("--no-reuse-object", arg)) {
+ no_reuse_object = no_reuse_delta = 1;
+ continue;
+ }
if (!strcmp("--delta-base-offset", arg)) {
allow_ofs_delta = 1;
continue;
@@ -1688,12 +1801,12 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
}
if (!prefixcmp(arg, "--index-version=")) {
char *c;
- index_default_version = strtoul(arg + 16, &c, 10);
- if (index_default_version > 2)
+ pack_idx_default_version = strtoul(arg + 16, &c, 10);
+ if (pack_idx_default_version > 2)
die("bad %s", arg);
if (*c == ',')
- index_off32_limit = strtoul(c+1, &c, 0);
- if (*c || index_off32_limit & 0x80000000)
+ pack_idx_off32_limit = strtoul(c+1, &c, 0);
+ if (*c || pack_idx_off32_limit & 0x80000000)
die("bad %s", arg);
continue;
}
@@ -1719,6 +1832,9 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
if (pack_to_stdout != !base_name)
usage(pack_usage);
+ if (pack_to_stdout && pack_size_limit)
+ die("--max-pack-size cannot be used to build a pack for transfer.");
+
if (!pack_to_stdout && thin)
die("--thin cannot be used to build an indexable pack.");
@@ -1744,33 +1860,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
fprintf(stderr, "Result has %u objects.\n", nr_result);
if (nr_result)
prepare_pack(window, depth);
- last_obj_offset = write_pack_file();
- if (!pack_to_stdout) {
- unsigned char object_list_sha1[20];
- mode_t mode = umask(0);
-
- umask(mode);
- mode = 0444 & ~mode;
-
- write_index_file(last_obj_offset, object_list_sha1);
- snprintf(tmpname, sizeof(tmpname), "%s-%s.pack",
- base_name, sha1_to_hex(object_list_sha1));
- if (adjust_perm(pack_tmp_name, mode))
- die("unable to make temporary pack file readable: %s",
- strerror(errno));
- if (rename(pack_tmp_name, tmpname))
- die("unable to rename temporary pack file: %s",
- strerror(errno));
- snprintf(tmpname, sizeof(tmpname), "%s-%s.idx",
- base_name, sha1_to_hex(object_list_sha1));
- if (adjust_perm(idx_tmp_name, mode))
- die("unable to make temporary index file readable: %s",
- strerror(errno));
- if (rename(idx_tmp_name, tmpname))
- die("unable to rename temporary index file: %s",
- strerror(errno));
- puts(sha1_to_hex(object_list_sha1));
- }
+ write_pack_file();
if (progress)
fprintf(stderr, "Total %u (delta %u), reused %u (delta %u)\n",
written, written_delta, reused, reused_delta);
diff --git a/builtin-pack-refs.c b/builtin-pack-refs.c
index d080e30..09df4e1 100644
--- a/builtin-pack-refs.c
+++ b/builtin-pack-refs.c
@@ -1,3 +1,4 @@
+#include "builtin.h"
#include "cache.h"
#include "refs.h"
#include "object.h"
@@ -12,9 +13,11 @@ struct ref_to_prune {
char name[FLEX_ARRAY];
};
+#define PACK_REFS_PRUNE 0x0001
+#define PACK_REFS_ALL 0x0002
+
struct pack_refs_cb_data {
- int prune;
- int all;
+ unsigned int flags;
struct ref_to_prune *ref_to_prune;
FILE *refs_file;
};
@@ -39,7 +42,7 @@ static int handle_one_ref(const char *path, const unsigned char *sha1,
is_tag_ref = !prefixcmp(path, "refs/tags/");
/* ALWAYS pack refs that were already packed or are tags */
- if (!cb->all && !is_tag_ref && !(flags & REF_ISPACKED))
+ if (!(cb->flags & PACK_REFS_ALL) && !is_tag_ref && !(flags & REF_ISPACKED))
return 0;
fprintf(cb->refs_file, "%s %s\n", sha1_to_hex(sha1), path);
@@ -53,7 +56,7 @@ static int handle_one_ref(const char *path, const unsigned char *sha1,
}
}
- if (cb->prune && !do_not_prune(flags)) {
+ if ((cb->flags & PACK_REFS_PRUNE) && !do_not_prune(flags)) {
int namelen = strlen(path) + 1;
struct ref_to_prune *n = xcalloc(1, sizeof(*n) + namelen);
hashcpy(n->sha1, sha1);
@@ -85,26 +88,53 @@ static void prune_refs(struct ref_to_prune *r)
static struct lock_file packed;
-int cmd_pack_refs(int argc, const char **argv, const char *prefix)
+static int pack_refs(unsigned int flags)
{
- int fd, i;
+ int fd;
struct pack_refs_cb_data cbdata;
memset(&cbdata, 0, sizeof(cbdata));
+ cbdata.flags = flags;
+
+ fd = hold_lock_file_for_update(&packed, git_path("packed-refs"), 1);
+ cbdata.refs_file = fdopen(fd, "w");
+ if (!cbdata.refs_file)
+ die("unable to create ref-pack file structure (%s)",
+ strerror(errno));
+
+ /* perhaps other traits later as well */
+ fprintf(cbdata.refs_file, "# pack-refs with: peeled \n");
+
+ for_each_ref(handle_one_ref, &cbdata);
+ if (ferror(cbdata.refs_file))
+ die("failed to write ref-pack file");
+ if (fflush(cbdata.refs_file) || fsync(fd) || fclose(cbdata.refs_file))
+ die("failed to write ref-pack file (%s)", strerror(errno));
+ if (commit_lock_file(&packed) < 0)
+ die("unable to overwrite old ref-pack file (%s)", strerror(errno));
+ if (cbdata.flags & PACK_REFS_PRUNE)
+ prune_refs(cbdata.ref_to_prune);
+ return 0;
+}
- cbdata.prune = 1;
+int cmd_pack_refs(int argc, const char **argv, const char *prefix)
+{
+ int i;
+ unsigned int flags;
+
+ flags = PACK_REFS_PRUNE;
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
if (!strcmp(arg, "--prune")) {
- cbdata.prune = 1; /* now the default */
+ flags |= PACK_REFS_PRUNE; /* now the default */
continue;
}
if (!strcmp(arg, "--no-prune")) {
- cbdata.prune = 0;
+ flags &= ~PACK_REFS_PRUNE;
continue;
}
if (!strcmp(arg, "--all")) {
- cbdata.all = 1;
+ flags |= PACK_REFS_ALL;
continue;
}
/* perhaps other parameters later... */
@@ -113,22 +143,5 @@ int cmd_pack_refs(int argc, const char **argv, const char *prefix)
if (i != argc)
usage(builtin_pack_refs_usage);
- fd = hold_lock_file_for_update(&packed, git_path("packed-refs"), 1);
- cbdata.refs_file = fdopen(fd, "w");
- if (!cbdata.refs_file)
- die("unable to create ref-pack file structure (%s)",
- strerror(errno));
-
- /* perhaps other traits later as well */
- fprintf(cbdata.refs_file, "# pack-refs with: peeled \n");
-
- for_each_ref(handle_one_ref, &cbdata);
- fflush(cbdata.refs_file);
- fsync(fd);
- fclose(cbdata.refs_file);
- if (commit_lock_file(&packed) < 0)
- die("unable to overwrite old ref-pack file (%s)", strerror(errno));
- if (cbdata.prune)
- prune_refs(cbdata.ref_to_prune);
- return 0;
+ return pack_refs(flags);
}
diff --git a/builtin-push.c b/builtin-push.c
index cb78401..2612f07 100644
--- a/builtin-push.c
+++ b/builtin-push.c
@@ -5,17 +5,13 @@
#include "refs.h"
#include "run-command.h"
#include "builtin.h"
-
-#define MAX_URI (16)
+#include "remote.h"
static const char push_usage[] = "git-push [--all] [--tags] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]";
-static int all, tags, force, thin = 1, verbose;
+static int all, force, thin = 1, verbose;
static const char *receivepack;
-#define BUF_SIZE (2084)
-static char buffer[BUF_SIZE];
-
static const char **refspec;
static int refspec_nr;
@@ -27,285 +23,47 @@ static void add_refspec(const char *ref)
refspec_nr = nr;
}
-static int expand_one_ref(const char *ref, const unsigned char *sha1, int flag, void *cb_data)
-{
- /* Ignore the "refs/" at the beginning of the refname */
- ref += 5;
-
- if (!prefixcmp(ref, "tags/"))
- add_refspec(xstrdup(ref));
- return 0;
-}
-
-static void expand_refspecs(void)
-{
- if (all) {
- if (refspec_nr)
- die("cannot mix '--all' and a refspec");
-
- /*
- * No need to expand "--all" - we'll just use
- * the "--all" flag to send-pack
- */
- return;
- }
- if (!tags)
- return;
- for_each_ref(expand_one_ref, NULL);
-}
-
-struct wildcard_cb {
- const char *from_prefix;
- int from_prefix_len;
- const char *to_prefix;
- int to_prefix_len;
- int force;
-};
-
-static int expand_wildcard_ref(const char *ref, const unsigned char *sha1, int flag, void *cb_data)
-{
- struct wildcard_cb *cb = cb_data;
- int len = strlen(ref);
- char *expanded, *newref;
-
- if (len < cb->from_prefix_len ||
- memcmp(cb->from_prefix, ref, cb->from_prefix_len))
- return 0;
- expanded = xmalloc(len * 2 + cb->force +
- (cb->to_prefix_len - cb->from_prefix_len) + 2);
- newref = expanded + cb->force;
- if (cb->force)
- expanded[0] = '+';
- memcpy(newref, ref, len);
- newref[len] = ':';
- memcpy(newref + len + 1, cb->to_prefix, cb->to_prefix_len);
- strcpy(newref + len + 1 + cb->to_prefix_len,
- ref + cb->from_prefix_len);
- add_refspec(expanded);
- return 0;
-}
-
-static int wildcard_ref(const char *ref)
-{
- int len;
- const char *colon;
- struct wildcard_cb cb;
-
- memset(&cb, 0, sizeof(cb));
- if (ref[0] == '+') {
- cb.force = 1;
- ref++;
- }
- len = strlen(ref);
- colon = strchr(ref, ':');
- if (! (colon && ref < colon &&
- colon[-2] == '/' && colon[-1] == '*' &&
- /* "<mine>/<asterisk>:<yours>/<asterisk>" is at least 7 bytes */
- 7 <= len &&
- ref[len-2] == '/' && ref[len-1] == '*') )
- return 0 ;
- cb.from_prefix = ref;
- cb.from_prefix_len = colon - ref - 1;
- cb.to_prefix = colon + 1;
- cb.to_prefix_len = len - (colon - ref) - 2;
- for_each_ref(expand_wildcard_ref, &cb);
- return 1;
-}
-
static void set_refspecs(const char **refs, int nr)
{
- if (nr) {
- int i;
- for (i = 0; i < nr; i++) {
- const char *ref = refs[i];
- if (!strcmp("tag", ref)) {
- char *tag;
- int len;
- if (nr <= ++i)
- die("tag shorthand without <tag>");
- len = strlen(refs[i]) + 11;
- tag = xmalloc(len);
- strcpy(tag, "refs/tags/");
- strcat(tag, refs[i]);
- ref = tag;
- }
- else if (wildcard_ref(ref))
- continue;
- add_refspec(ref);
- }
- }
- expand_refspecs();
-}
-
-static int get_remotes_uri(const char *repo, const char *uri[MAX_URI])
-{
- int n = 0;
- FILE *f = fopen(git_path("remotes/%s", repo), "r");
- int has_explicit_refspec = refspec_nr || all || tags;
-
- if (!f)
- return -1;
- while (fgets(buffer, BUF_SIZE, f)) {
- int is_refspec;
- char *s, *p;
-
- if (!prefixcmp(buffer, "URL:")) {
- is_refspec = 0;
- s = buffer + 4;
- } else if (!prefixcmp(buffer, "Push:")) {
- is_refspec = 1;
- s = buffer + 5;
- } else
- continue;
-
- /* Remove whitespace at the head.. */
- while (isspace(*s))
- s++;
- if (!*s)
- continue;
-
- /* ..and at the end */
- p = s + strlen(s);
- while (isspace(p[-1]))
- *--p = 0;
-
- if (!is_refspec) {
- if (n < MAX_URI)
- uri[n++] = xstrdup(s);
- else
- error("more than %d URL's specified, ignoring the rest", MAX_URI);
- }
- else if (is_refspec && !has_explicit_refspec) {
- if (!wildcard_ref(s))
- add_refspec(xstrdup(s));
- }
- }
- fclose(f);
- if (!n)
- die("remote '%s' has no URL", repo);
- return n;
-}
-
-static const char **config_uri;
-static const char *config_repo;
-static int config_repo_len;
-static int config_current_uri;
-static int config_get_refspecs;
-static int config_get_receivepack;
-
-static int get_remote_config(const char* key, const char* value)
-{
- if (!prefixcmp(key, "remote.") &&
- !strncmp(key + 7, config_repo, config_repo_len)) {
- if (!strcmp(key + 7 + config_repo_len, ".url")) {
- if (config_current_uri < MAX_URI)
- config_uri[config_current_uri++] = xstrdup(value);
- else
- error("more than %d URL's specified, ignoring the rest", MAX_URI);
- }
- else if (config_get_refspecs &&
- !strcmp(key + 7 + config_repo_len, ".push")) {
- if (!wildcard_ref(value))
- add_refspec(xstrdup(value));
- }
- else if (config_get_receivepack &&
- !strcmp(key + 7 + config_repo_len, ".receivepack")) {
- if (!receivepack) {
- char *rp = xmalloc(strlen(value) + 16);
- sprintf(rp, "--receive-pack=%s", value);
- receivepack = rp;
- } else
- error("more than one receivepack given, using the first");
- }
- }
- return 0;
-}
-
-static int get_config_remotes_uri(const char *repo, const char *uri[MAX_URI])
-{
- config_repo_len = strlen(repo);
- config_repo = repo;
- config_current_uri = 0;
- config_uri = uri;
- config_get_refspecs = !(refspec_nr || all || tags);
- config_get_receivepack = (receivepack == NULL);
-
- git_config(get_remote_config);
- return config_current_uri;
-}
-
-static int get_branches_uri(const char *repo, const char *uri[MAX_URI])
-{
- const char *slash = strchr(repo, '/');
- int n = slash ? slash - repo : 1000;
- FILE *f = fopen(git_path("branches/%.*s", n, repo), "r");
- char *s, *p;
- int len;
-
- if (!f)
- return 0;
- s = fgets(buffer, BUF_SIZE, f);
- fclose(f);
- if (!s)
- return 0;
- while (isspace(*s))
- s++;
- if (!*s)
- return 0;
- p = s + strlen(s);
- while (isspace(p[-1]))
- *--p = 0;
- len = p - s;
- if (slash)
- len += strlen(slash);
- p = xmalloc(len + 1);
- strcpy(p, s);
- if (slash)
- strcat(p, slash);
- uri[0] = p;
- return 1;
-}
-
-/*
- * Read remotes and branches file, fill the push target URI
- * list. If there is no command line refspecs, read Push: lines
- * to set up the *refspec list as well.
- * return the number of push target URIs
- */
-static int read_config(const char *repo, const char *uri[MAX_URI])
-{
- int n;
-
- if (*repo != '/') {
- n = get_remotes_uri(repo, uri);
- if (n > 0)
- return n;
-
- n = get_config_remotes_uri(repo, uri);
- if (n > 0)
- return n;
-
- n = get_branches_uri(repo, uri);
- if (n > 0)
- return n;
+ int i;
+ for (i = 0; i < nr; i++) {
+ const char *ref = refs[i];
+ if (!strcmp("tag", ref)) {
+ char *tag;
+ int len;
+ if (nr <= ++i)
+ die("tag shorthand without <tag>");
+ len = strlen(refs[i]) + 11;
+ tag = xmalloc(len);
+ strcpy(tag, "refs/tags/");
+ strcat(tag, refs[i]);
+ ref = tag;
+ }
+ add_refspec(ref);
}
-
- uri[0] = repo;
- return 1;
}
static int do_push(const char *repo)
{
- const char *uri[MAX_URI];
- int i, n, errs;
+ int i, errs;
int common_argc;
const char **argv;
int argc;
+ struct remote *remote = remote_get(repo);
- n = read_config(repo, uri);
- if (n <= 0)
+ if (!remote)
die("bad repository '%s'", repo);
+ if (remote->receivepack) {
+ char *rp = xmalloc(strlen(remote->receivepack) + 16);
+ sprintf(rp, "--receive-pack=%s", remote->receivepack);
+ receivepack = rp;
+ }
+ if (!refspec && !all && remote->push_refspec_nr) {
+ refspec = remote->push_refspec;
+ refspec_nr = remote->push_refspec_nr;
+ }
+
argv = xmalloc((refspec_nr + 10) * sizeof(char *));
argv[0] = "dummy-send-pack";
argc = 1;
@@ -318,18 +76,23 @@ static int do_push(const char *repo)
common_argc = argc;
errs = 0;
- for (i = 0; i < n; i++) {
+ for (i = 0; i < remote->uri_nr; i++) {
int err;
int dest_argc = common_argc;
int dest_refspec_nr = refspec_nr;
const char **dest_refspec = refspec;
- const char *dest = uri[i];
+ const char *dest = remote->uri[i];
const char *sender = "send-pack";
if (!prefixcmp(dest, "http://") ||
!prefixcmp(dest, "https://"))
sender = "http-push";
- else if (thin)
- argv[dest_argc++] = "--thin";
+ else {
+ char *rem = xmalloc(strlen(remote->name) + 10);
+ sprintf(rem, "--remote=%s", remote->name);
+ argv[dest_argc++] = rem;
+ if (thin)
+ argv[dest_argc++] = "--thin";
+ }
argv[0] = sender;
argv[dest_argc++] = dest;
while (dest_refspec_nr--)
@@ -341,7 +104,7 @@ static int do_push(const char *repo)
if (!err)
continue;
- error("failed to push to '%s'", uri[i]);
+ error("failed to push to '%s'", remote->uri[i]);
switch (err) {
case -ERR_RUN_COMMAND_FORK:
error("unable to fork for %s", sender);
@@ -362,7 +125,7 @@ static int do_push(const char *repo)
int cmd_push(int argc, const char **argv, const char *prefix)
{
int i;
- const char *repo = "origin"; /* default repository */
+ const char *repo = NULL; /* default repository */
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
@@ -385,7 +148,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
continue;
}
if (!strcmp(arg, "--tags")) {
- tags = 1;
+ add_refspec("refs/tags/*");
continue;
}
if (!strcmp(arg, "--force") || !strcmp(arg, "-f")) {
@@ -411,5 +174,8 @@ int cmd_push(int argc, const char **argv, const char *prefix)
usage(push_usage);
}
set_refspecs(argv + i, argc - i);
+ if (all && refspec)
+ usage(push_usage);
+
return do_push(repo);
}
diff --git a/builtin-read-tree.c b/builtin-read-tree.c
index 316fb0f..a3b17a3 100644
--- a/builtin-read-tree.c
+++ b/builtin-read-tree.c
@@ -84,7 +84,7 @@ static void prime_cache_tree(void)
}
-static const char read_tree_usage[] = "git-read-tree (<sha> | [[-m [--aggressive] | --reset | --prefix=<prefix>] [-u | -i]] [--exclude-per-directory=<gitignore>] [--index-output=<file>] <sha1> [<sha2> [<sha3>]])";
+static const char read_tree_usage[] = "git-read-tree (<sha> | [[-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>] [-u | -i]] [--exclude-per-directory=<gitignore>] [--index-output=<file>] <sha1> [<sha2> [<sha3>]])";
static struct lock_file lock_file;
@@ -97,7 +97,6 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
memset(&opts, 0, sizeof(opts));
opts.head_idx = -1;
- setup_git_directory();
git_config(git_default_config);
newfd = hold_locked_index(&lock_file, 1);
diff --git a/builtin-reflog.c b/builtin-reflog.c
index 4c39f1d..ce093ca 100644
--- a/builtin-reflog.c
+++ b/builtin-reflog.c
@@ -249,7 +249,7 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused,
/* we take the lock for the ref itself to prevent it from
* getting updated.
*/
- lock = lock_any_ref_for_update(ref, sha1);
+ lock = lock_any_ref_for_update(ref, sha1, 0);
if (!lock)
return error("cannot lock ref '%s'", ref);
log_file = xstrdup(git_path("logs/%s", ref));
diff --git a/builtin-rerere.c b/builtin-rerere.c
index 8c2c8bd..29d057c 100644
--- a/builtin-rerere.c
+++ b/builtin-rerere.c
@@ -1,3 +1,4 @@
+#include "builtin.h"
#include "cache.h"
#include "path-list.h"
#include "xdiff/xdiff.h"
@@ -12,6 +13,9 @@ static const char git_rerere_usage[] =
static int cutoff_noresolve = 15;
static int cutoff_resolve = 60;
+/* if rerere_enabled == -1, fall back to detection of .git/rr-cache */
+static int rerere_enabled = -1;
+
static char *merge_rr_path;
static const char *rr_path(const char *name, const char *file)
@@ -57,7 +61,8 @@ static int write_rr(struct path_list *rr, int out_fd)
write_in_full(out_fd, path, length) != length)
die("unable to write rerere record");
}
- close(out_fd);
+ if (close(out_fd) != 0)
+ die("unable to write rerere record");
return commit_lock_file(&write_lock);
}
@@ -164,19 +169,16 @@ static int find_conflict(struct path_list *conflict)
int i;
if (read_cache() < 0)
return error("Could not read index");
- for (i = 0; i + 2 < active_nr; i++) {
- struct cache_entry *e1 = active_cache[i];
- struct cache_entry *e2 = active_cache[i+1];
- struct cache_entry *e3 = active_cache[i+2];
- if (ce_stage(e1) == 1 &&
- ce_stage(e2) == 2 &&
+ for (i = 0; i+1 < active_nr; i++) {
+ struct cache_entry *e2 = active_cache[i];
+ struct cache_entry *e3 = active_cache[i+1];
+ if (ce_stage(e2) == 2 &&
ce_stage(e3) == 3 &&
- ce_same_name(e1, e2) && ce_same_name(e1, e3) &&
- S_ISREG(ntohl(e1->ce_mode)) &&
+ ce_same_name(e2, e3) &&
S_ISREG(ntohl(e2->ce_mode)) &&
S_ISREG(ntohl(e3->ce_mode))) {
- path_list_insert((const char *)e1->name, conflict);
- i += 2;
+ path_list_insert((const char *)e2->name, conflict);
+ i++; /* skip over both #2 and #3 */
}
}
return 0;
@@ -281,8 +283,8 @@ static int diff_two(const char *file1, const char *label1,
printf("--- a/%s\n+++ b/%s\n", label1, label2);
fflush(stdout);
xpp.flags = XDF_NEED_MINIMAL;
+ memset(&xecfg, 0, sizeof(xecfg));
xecfg.ctxlen = 3;
- xecfg.flags = 0;
ecb.outf = outf;
xdl_diff(&minus, &plus, &xpp, &xecfg, &ecb);
@@ -386,21 +388,41 @@ static int git_rerere_config(const char *var, const char *value)
cutoff_resolve = git_config_int(var, value);
else if (!strcmp(var, "gc.rerereunresolved"))
cutoff_noresolve = git_config_int(var, value);
+ else if (!strcmp(var, "rerere.enabled"))
+ rerere_enabled = git_config_bool(var, value);
else
return git_default_config(var, value);
return 0;
}
-int cmd_rerere(int argc, const char **argv, const char *prefix)
+static int is_rerere_enabled(void)
{
- struct path_list merge_rr = { NULL, 0, 0, 1 };
- int i, fd = -1;
struct stat st;
+ const char *rr_cache;
+ int rr_cache_exists;
- if (stat(git_path("rr-cache"), &st) || !S_ISDIR(st.st_mode))
+ if (!rerere_enabled)
return 0;
+ rr_cache = git_path("rr-cache");
+ rr_cache_exists = !stat(rr_cache, &st) && S_ISDIR(st.st_mode);
+ if (rerere_enabled < 0)
+ return rr_cache_exists;
+
+ if (!rr_cache_exists &&
+ (mkdir(rr_cache, 0777) || adjust_shared_perm(rr_cache)))
+ die("Could not create directory %s", rr_cache);
+ return 1;
+}
+
+int cmd_rerere(int argc, const char **argv, const char *prefix)
+{
+ struct path_list merge_rr = { NULL, 0, 0, 1 };
+ int i, fd = -1;
+
git_config(git_rerere_config);
+ if (!is_rerere_enabled())
+ return 0;
merge_rr_path = xstrdup(git_path("rr-cache/MERGE_RR"));
fd = hold_lock_file_for_update(&write_lock, merge_rr_path, 1);
@@ -410,6 +432,7 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
return do_plain_rerere(&merge_rr, fd);
else if (!strcmp(argv[1], "clear")) {
for (i = 0; i < merge_rr.nr; i++) {
+ struct stat st;
const char *name = (const char *)merge_rr.items[i].util;
if (!stat(git_path("rr-cache/%s", name), &st) &&
S_ISDIR(st.st_mode) &&
@@ -434,4 +457,3 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
path_list_clear(&merge_rr, 1);
return 0;
}
-
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 2eb919f..ac551d5 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -70,21 +70,9 @@ static void show_commit(struct commit *commit)
if (revs.parents) {
struct commit_list *parents = commit->parents;
while (parents) {
- struct object *o = &(parents->item->object);
+ printf(" %s", sha1_to_hex(parents->item->object.sha1));
parents = parents->next;
- if (o->flags & TMP_MARK)
- continue;
- printf(" %s", sha1_to_hex(o->sha1));
- o->flags |= TMP_MARK;
}
- /* TMP_MARK is a general purpose flag that can
- * be used locally, but the user should clean
- * things up after it is done with them.
- */
- for (parents = commit->parents;
- parents;
- parents = parents->next)
- parents->item->object.flags &= ~TMP_MARK;
}
if (revs.commit_format == CMIT_FMT_ONELINE)
putchar(' ');
@@ -92,13 +80,15 @@ static void show_commit(struct commit *commit)
putchar('\n');
if (revs.verbose_header) {
- static char pretty_header[16384];
+ char *buf = NULL;
+ unsigned long buflen = 0;
pretty_print_commit(revs.commit_format, commit, ~0,
- pretty_header, sizeof(pretty_header),
+ &buf, &buflen,
revs.abbrev, NULL, NULL, revs.date_mode);
- printf("%s%c", pretty_header, hdr_termination);
+ printf("%s%c", buf, hdr_termination);
+ free(buf);
}
- fflush(stdout);
+ maybe_flush_or_die(stdout, "stdout");
if (commit->parents) {
free_commit_list(commit->parents);
commit->parents = NULL;
diff --git a/builtin-rev-parse.c b/builtin-rev-parse.c
index 37addb2..8d78b69 100644
--- a/builtin-rev-parse.c
+++ b/builtin-rev-parse.c
@@ -321,6 +321,13 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
}
if (!strcmp(arg, "--show-cdup")) {
const char *pfx = prefix;
+ if (!is_inside_work_tree()) {
+ const char *work_tree =
+ get_git_work_tree();
+ if (work_tree)
+ printf("%s\n", work_tree);
+ continue;
+ }
while (pfx) {
pfx = strchr(pfx, '/');
if (pfx) {
@@ -352,6 +359,16 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
: "false");
continue;
}
+ if (!strcmp(arg, "--is-inside-work-tree")) {
+ printf("%s\n", is_inside_work_tree() ? "true"
+ : "false");
+ continue;
+ }
+ if (!strcmp(arg, "--is-bare-repository")) {
+ printf("%s\n", is_bare_repository() ? "true"
+ : "false");
+ continue;
+ }
if (!prefixcmp(arg, "--since=")) {
show_datestring("--max-age=", arg+8);
continue;
diff --git a/builtin-revert.c b/builtin-revert.c
index ea2f15b..499bbe7 100644
--- a/builtin-revert.c
+++ b/builtin-revert.c
@@ -25,7 +25,7 @@ static const char *cherry_pick_usage = "git-cherry-pick [--edit] [-n] [-r] [-x]
static int edit;
static int replay;
-enum { REVERT, CHERRY_PICK } action;
+static enum { REVERT, CHERRY_PICK } action;
static int no_commit;
static struct commit *commit;
static int needed_deref;
@@ -45,8 +45,10 @@ static void parse_options(int argc, const char **argv)
if (argc < 2)
usage(usage_str);
- for (i = 1; i < argc - 1; i++) {
+ for (i = 1; i < argc; i++) {
arg = argv[i];
+ if (arg[0] != '-')
+ break;
if (!strcmp(arg, "-n") || !strcmp(arg, "--no-commit"))
no_commit = 1;
else if (!strcmp(arg, "-e") || !strcmp(arg, "--edit"))
@@ -59,7 +61,8 @@ static void parse_options(int argc, const char **argv)
else if (strcmp(arg, "-r"))
usage(usage_str);
}
-
+ if (i != argc - 1)
+ usage(usage_str);
arg = argv[argc - 1];
if (get_sha1(arg, sha1))
die ("Cannot find '%s'", arg);
@@ -104,7 +107,7 @@ static char *get_oneline(const char *message)
return result;
}
-char *get_encoding(const char *message)
+static char *get_encoding(const char *message)
{
const char *p = message, *eol;
@@ -126,7 +129,7 @@ char *get_encoding(const char *message)
return NULL;
}
-struct lock_file msg_file;
+static struct lock_file msg_file;
static int msg_fd;
static void add_to_msg(const char *string)
diff --git a/builtin-rm.c b/builtin-rm.c
index 4a0bd93..9a808c1 100644
--- a/builtin-rm.c
+++ b/builtin-rm.c
@@ -46,7 +46,7 @@ static int remove_file(const char *name)
return ret;
}
-static int check_local_mod(unsigned char *head)
+static int check_local_mod(unsigned char *head, int index_only)
{
/* items in list are already sorted in the cache order,
* so we could do this a lot more efficiently by using
@@ -65,6 +65,8 @@ static int check_local_mod(unsigned char *head)
const char *name = list.name[i];
unsigned char sha1[20];
unsigned mode;
+ int local_changes = 0;
+ int staged_changes = 0;
pos = cache_name_pos(name, strlen(name));
if (pos < 0)
@@ -87,14 +89,32 @@ static int check_local_mod(unsigned char *head)
continue;
}
if (ce_match_stat(ce, &st, 0))
- errs = error("'%s' has local modifications "
- "(hint: try -f)", ce->name);
+ local_changes = 1;
if (no_head
|| get_tree_entry(head, name, sha1, &mode)
|| ce->ce_mode != create_ce_mode(mode)
|| hashcmp(ce->sha1, sha1))
- errs = error("'%s' has changes staged in the index "
- "(hint: try -f)", name);
+ staged_changes = 1;
+
+ if (local_changes && staged_changes)
+ errs = error("'%s' has staged content different "
+ "from both the file and the HEAD\n"
+ "(use -f to force removal)", name);
+ else if (!index_only) {
+ /* It's not dangerous to git-rm --cached a
+ * file if the index matches the file or the
+ * HEAD, since it means the deleted content is
+ * still available somewhere.
+ */
+ if (staged_changes)
+ errs = error("'%s' has changes staged in the index\n"
+ "(use --cached to keep the file, "
+ "or -f to force removal)", name);
+ if (local_changes)
+ errs = error("'%s' has local modifications\n"
+ "(use --cached to keep the file, "
+ "or -f to force removal)", name);
+ }
}
return errs;
}
@@ -192,7 +212,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
unsigned char sha1[20];
if (get_sha1("HEAD", sha1))
hashclr(sha1);
- if (check_local_mod(sha1))
+ if (check_local_mod(sha1, index_only))
exit(1);
}
diff --git a/builtin-runstatus.c b/builtin-runstatus.c
index 4b489b1..2db25c8 100644
--- a/builtin-runstatus.c
+++ b/builtin-runstatus.c
@@ -1,3 +1,4 @@
+#include "builtin.h"
#include "cache.h"
#include "wt-status.h"
diff --git a/builtin-shortlog.c b/builtin-shortlog.c
index 8d3f742..16af619 100644
--- a/builtin-shortlog.c
+++ b/builtin-shortlog.c
@@ -331,4 +331,3 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix)
return 0;
}
-
diff --git a/builtin-show-branch.c b/builtin-show-branch.c
index c892f1f..4fa87f6 100644
--- a/builtin-show-branch.c
+++ b/builtin-show-branch.c
@@ -259,17 +259,19 @@ static void join_revs(struct commit_list **list_p,
static void show_one_commit(struct commit *commit, int no_name)
{
- char pretty[256], *cp;
+ char *pretty = NULL;
+ const char *pretty_str = "(unavailable)";
+ unsigned long pretty_len = 0;
struct commit_name *name = commit->util;
- if (commit->object.parsed)
+
+ if (commit->object.parsed) {
pretty_print_commit(CMIT_FMT_ONELINE, commit, ~0,
- pretty, sizeof(pretty), 0, NULL, NULL, 0);
- else
- strcpy(pretty, "(unavailable)");
- if (!prefixcmp(pretty, "[PATCH] "))
- cp = pretty + 8;
- else
- cp = pretty;
+ &pretty, &pretty_len,
+ 0, NULL, NULL, 0);
+ pretty_str = pretty;
+ }
+ if (!prefixcmp(pretty_str, "[PATCH] "))
+ pretty_str += 8;
if (!no_name) {
if (name && name->head_name) {
@@ -286,7 +288,8 @@ static void show_one_commit(struct commit *commit, int no_name)
printf("[%s] ",
find_unique_abbrev(commit->object.sha1, 7));
}
- puts(cp);
+ puts(pretty_str);
+ free(pretty);
}
static char *ref_name[MAX_REVS + 1];
diff --git a/builtin-show-ref.c b/builtin-show-ref.c
index 9463ff0..65051d1 100644
--- a/builtin-show-ref.c
+++ b/builtin-show-ref.c
@@ -1,3 +1,4 @@
+#include "builtin.h"
#include "cache.h"
#include "refs.h"
#include "object.h"
diff --git a/builtin-stripspace.c b/builtin-stripspace.c
index f0d4d9e..5571687 100644
--- a/builtin-stripspace.c
+++ b/builtin-stripspace.c
@@ -1,58 +1,94 @@
#include "builtin.h"
+#include "cache.h"
/*
- * Remove empty lines from the beginning and end.
+ * Returns the length of a line, without trailing spaces.
*
- * Turn multiple consecutive empty lines into just one
- * empty line. Return true if it is an incomplete line.
+ * If the line ends with newline, it will be removed too.
*/
-static int cleanup(char *line)
+static size_t cleanup(char *line, size_t len)
{
- int len = strlen(line);
+ if (len) {
+ if (line[len - 1] == '\n')
+ len--;
- if (len && line[len-1] == '\n') {
- if (len == 1)
- return 0;
- do {
- unsigned char c = line[len-2];
+ while (len) {
+ unsigned char c = line[len - 1];
if (!isspace(c))
break;
- line[len-2] = '\n';
len--;
- line[len] = 0;
- } while (len > 1);
- return 0;
+ }
}
- return 1;
+ return len;
}
-void stripspace(FILE *in, FILE *out)
+/*
+ * Remove empty lines from the beginning and end
+ * and also trailing spaces from every line.
+ *
+ * Note that the buffer will not be NUL-terminated.
+ *
+ * Turn multiple consecutive empty lines between paragraphs
+ * into just one empty line.
+ *
+ * If the input has only empty lines and spaces,
+ * no output will be produced.
+ *
+ * If last line has a newline at the end, it will be removed.
+ *
+ * Enable skip_comments to skip every line starting with "#".
+ */
+size_t stripspace(char *buffer, size_t length, int skip_comments)
{
int empties = -1;
- int incomplete = 0;
- char line[1024];
+ size_t i, j, len, newlen;
+ char *eol;
- while (fgets(line, sizeof(line), in)) {
- incomplete = cleanup(line);
+ for (i = j = 0; i < length; i += len, j += newlen) {
+ eol = memchr(buffer + i, '\n', length - i);
+ len = eol ? eol - (buffer + i) + 1 : length - i;
+
+ if (skip_comments && len && buffer[i] == '#') {
+ newlen = 0;
+ continue;
+ }
+ newlen = cleanup(buffer + i, len);
/* Not just an empty line? */
- if (line[0] != '\n') {
+ if (newlen) {
+ if (empties != -1)
+ buffer[j++] = '\n';
if (empties > 0)
- fputc('\n', out);
+ buffer[j++] = '\n';
empties = 0;
- fputs(line, out);
+ memmove(buffer + j, buffer + i, newlen);
continue;
}
if (empties < 0)
continue;
empties++;
}
- if (incomplete)
- fputc('\n', out);
+
+ return j;
}
int cmd_stripspace(int argc, const char **argv, const char *prefix)
{
- stripspace(stdin, stdout);
+ char *buffer;
+ unsigned long size;
+
+ size = 1024;
+ buffer = xmalloc(size);
+ if (read_fd(0, &buffer, &size)) {
+ free(buffer);
+ die("could not read the input");
+ }
+
+ size = stripspace(buffer, size, 0);
+ write_or_die(1, buffer, size);
+ if (size)
+ putc('\n', stdout);
+
+ free(buffer);
return 0;
}
diff --git a/builtin-symbolic-ref.c b/builtin-symbolic-ref.c
index d41b406..9eb95e5 100644
--- a/builtin-symbolic-ref.c
+++ b/builtin-symbolic-ref.c
@@ -43,8 +43,6 @@ int cmd_symbolic_ref(int argc, const char **argv, const char *prefix)
msg = argv[1];
if (!*msg)
die("Refusing to perform update with empty message");
- if (strchr(msg, '\n'))
- die("Refusing to perform update with \\n in message");
}
else if (!strcmp("--", arg)) {
argc--;
diff --git a/builtin-update-index.c b/builtin-update-index.c
index 8f98991..509369e 100644
--- a/builtin-update-index.c
+++ b/builtin-update-index.c
@@ -134,7 +134,7 @@ static int process_directory(const char *path, int len, struct stat *st)
/* Exact match: file or existing gitlink */
if (pos >= 0) {
struct cache_entry *ce = active_cache[pos];
- if (S_ISDIRLNK(ntohl(ce->ce_mode))) {
+ if (S_ISGITLINK(ntohl(ce->ce_mode))) {
/* Do nothing to the index if there is no HEAD! */
if (resolve_gitlink_ref(path, "HEAD", sha1) < 0)
@@ -178,7 +178,7 @@ static int process_file(const char *path, int len, struct stat *st)
int pos = cache_name_pos(path, len);
struct cache_entry *ce = pos < 0 ? NULL : active_cache[pos];
- if (ce && S_ISDIRLNK(ntohl(ce->ce_mode)))
+ if (ce && S_ISGITLINK(ntohl(ce->ce_mode)))
return error("%s is already a gitlink, not replacing", path);
return add_one_path(ce, path, len, st);
diff --git a/builtin-update-ref.c b/builtin-update-ref.c
index 5ee960b..8339cf1 100644
--- a/builtin-update-ref.c
+++ b/builtin-update-ref.c
@@ -3,16 +3,17 @@
#include "builtin.h"
static const char git_update_ref_usage[] =
-"git-update-ref [-m <reason>] (-d <refname> <value> | <refname> <value> [<oldval>])";
+"git-update-ref [-m <reason>] (-d <refname> <value> | [--no-deref] <refname> <value> [<oldval>])";
int cmd_update_ref(int argc, const char **argv, const char *prefix)
{
const char *refname=NULL, *value=NULL, *oldval=NULL, *msg=NULL;
struct ref_lock *lock;
unsigned char sha1[20], oldsha1[20];
- int i, delete;
+ int i, delete, ref_flags;
delete = 0;
+ ref_flags = 0;
git_config(git_default_config);
for (i = 1; i < argc; i++) {
@@ -22,14 +23,16 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
msg = argv[++i];
if (!*msg)
die("Refusing to perform update with empty message.");
- if (strchr(msg, '\n'))
- die("Refusing to perform update with \\n in message.");
continue;
}
if (!strcmp("-d", argv[i])) {
delete = 1;
continue;
}
+ if (!strcmp("--no-deref", argv[i])) {
+ ref_flags |= REF_NODEREF;
+ continue;
+ }
if (!refname) {
refname = argv[i];
continue;
@@ -59,7 +62,7 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
if (oldval && *oldval && get_sha1(oldval, oldsha1))
die("%s: not a valid old SHA1", oldval);
- lock = lock_any_ref_for_update(refname, oldval ? oldsha1 : NULL);
+ lock = lock_any_ref_for_update(refname, oldval ? oldsha1 : NULL, ref_flags);
if (!lock)
die("%s: cannot lock the ref", refname);
if (write_ref_sha1(lock, sha1, msg) < 0)
diff --git a/builtin-write-tree.c b/builtin-write-tree.c
index 391de53..88f34ba 100644
--- a/builtin-write-tree.c
+++ b/builtin-write-tree.c
@@ -52,6 +52,8 @@ int write_tree(unsigned char *sha1, int missing_ok, const char *prefix)
if (prefix) {
struct cache_tree *subtree =
cache_tree_find(active_cache_tree, prefix);
+ if (!subtree)
+ die("git-write-tree: prefix %s not found", prefix);
hashcpy(sha1, subtree->sha1);
}
else
diff --git a/builtin.h b/builtin.h
index d3f3a74..4cc228d 100644
--- a/builtin.h
+++ b/builtin.h
@@ -7,9 +7,7 @@ extern const char git_version_string[];
extern const char git_usage_string[];
extern void help_unknown_cmd(const char *cmd);
-extern int mailinfo(FILE *in, FILE *out, int ks, const char *encoding, const char *msg, const char *patch);
-extern int split_mbox(const char **mbox, const char *dir, int allow_bare, int nr_prec, int skip);
-extern void stripspace(FILE *in, FILE *out);
+extern size_t stripspace(char *buffer, size_t length, int skip_comments);
extern int write_tree(unsigned char *sha1, int missing_ok, const char *prefix);
extern void prune_packed_objects(int);
diff --git a/cache-tree.c b/cache-tree.c
index 6369cc7..077f034 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -326,7 +326,7 @@ static int update_one(struct cache_tree *it,
mode = ntohl(ce->ce_mode);
entlen = pathlen - baselen;
}
- if (mode != S_IFDIRLNK && !missing_ok && !has_sha1_file(sha1))
+ if (mode != S_IFGITLINK && !missing_ok && !has_sha1_file(sha1))
return error("invalid object %s", sha1_to_hex(sha1));
if (!ce->ce_mode)
@@ -478,7 +478,7 @@ static struct cache_tree *read_one(const char **buffer, unsigned long *size_p)
if (0 <= it->entry_count) {
if (size < 20)
goto free_return;
- hashcpy(it->sha1, (unsigned char*)buf);
+ hashcpy(it->sha1, (const unsigned char*)buf);
buf += 20;
size -= 20;
}
diff --git a/cache.h b/cache.h
index 5dff2f1..e97af18 100644
--- a/cache.h
+++ b/cache.h
@@ -40,8 +40,8 @@
* happens that everybody shares the same bit representation
* in the UNIX world (and apparently wider too..)
*/
-#define S_IFDIRLNK 0160000
-#define S_ISDIRLNK(m) (((m) & S_IFMT) == S_IFDIRLNK)
+#define S_IFGITLINK 0160000
+#define S_ISGITLINK(m) (((m) & S_IFMT) == S_IFGITLINK)
/*
* Intensive research over the course of many years has shown that
@@ -123,8 +123,8 @@ static inline unsigned int create_ce_mode(unsigned int mode)
{
if (S_ISLNK(mode))
return htonl(S_IFLNK);
- if (S_ISDIR(mode) || S_ISDIRLNK(mode))
- return htonl(S_IFDIRLNK);
+ if (S_ISDIR(mode) || S_ISGITLINK(mode))
+ return htonl(S_IFGITLINK);
return htonl(S_IFREG | ce_permissions(mode));
}
static inline unsigned int ce_mode_from_stat(struct cache_entry *ce, unsigned int mode)
@@ -142,7 +142,7 @@ static inline unsigned int ce_mode_from_stat(struct cache_entry *ce, unsigned in
}
#define canon_mode(mode) \
(S_ISREG(mode) ? (S_IFREG | ce_permissions(mode)) : \
- S_ISLNK(mode) ? S_IFLNK : S_ISDIR(mode) ? S_IFDIR : S_IFDIRLNK)
+ S_ISLNK(mode) ? S_IFLNK : S_ISDIR(mode) ? S_IFDIR : S_IFGITLINK)
#define cache_entry_size(len) ((offsetof(struct cache_entry,name) + (len) + 8) & ~7)
@@ -192,6 +192,7 @@ enum object_type {
};
#define GIT_DIR_ENVIRONMENT "GIT_DIR"
+#define GIT_WORK_TREE_ENVIRONMENT "GIT_WORK_TREE"
#define DEFAULT_GIT_DIR_ENVIRONMENT ".git"
#define DB_ENVIRONMENT "GIT_OBJECT_DIRECTORY"
#define INDEX_ENVIRONMENT "GIT_INDEX_FILE"
@@ -207,11 +208,15 @@ enum object_type {
extern int is_bare_repository_cfg;
extern int is_bare_repository(void);
extern int is_inside_git_dir(void);
+extern char *git_work_tree_cfg;
+extern int is_inside_work_tree(void);
extern const char *get_git_dir(void);
extern char *get_object_directory(void);
extern char *get_refs_directory(void);
extern char *get_index_file(void);
extern char *get_graft_file(void);
+extern int set_git_dir(const char *path);
+extern const char *get_git_work_tree(void);
#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
@@ -225,6 +230,24 @@ extern void verify_non_filename(const char *prefix, const char *name);
#define alloc_nr(x) (((x)+16)*3/2)
+/*
+ * Realloc the buffer pointed at by variable 'x' so that it can hold
+ * at least 'nr' entries; the number of entries currently allocated
+ * is 'alloc', using the standard growing factor alloc_nr() macro.
+ *
+ * DO NOT USE any expression with side-effect for 'x' or 'alloc'.
+ */
+#define ALLOC_GROW(x, nr, alloc) \
+ do { \
+ if ((nr) > alloc) { \
+ if (alloc_nr(alloc) < (nr)) \
+ alloc = (nr); \
+ else \
+ alloc = alloc_nr(alloc); \
+ x = xrealloc((x), alloc * sizeof(*(x))); \
+ } \
+ } while(0)
+
/* Initialize and use the cache information */
extern int read_index(struct index_state *);
extern int read_index_from(struct index_state *, const char *path);
@@ -245,7 +268,7 @@ extern int ie_match_stat(struct index_state *, struct cache_entry *, struct stat
extern int ie_modified(struct index_state *, struct cache_entry *, struct stat *, int);
extern int ce_path_match(const struct cache_entry *ce, const char **pathspec);
extern int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, enum object_type type, const char *path);
-extern int read_pipe(int fd, char** return_buf, unsigned long* return_size);
+extern int read_fd(int fd, char **return_buf, unsigned long *return_size);
extern int index_pipe(unsigned char *sha1, int fd, const char *type, int write_object);
extern int index_path(unsigned char *sha1, const char *path, struct stat *st, int write_object);
extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st);
@@ -273,8 +296,8 @@ extern void rollback_lock_file(struct lock_file *);
extern int delete_ref(const char *, const unsigned char *sha1);
/* Environment bits from configuration mechanism */
-extern int use_legacy_headers;
extern int trust_executable_bit;
+extern int quote_path_fully;
extern int has_symlinks;
extern int assume_unchanged;
extern int prefer_symlink_refs;
@@ -283,6 +306,8 @@ extern int warn_ambiguous_refs;
extern int shared_repository;
extern const char *apply_default_whitespace;
extern int zlib_compression_level;
+extern int core_compression_level;
+extern int core_compression_seen;
extern size_t packed_git_window_size;
extern size_t packed_git_limit;
extern size_t delta_base_cache_limit;
@@ -336,6 +361,11 @@ int git_config_perm(const char *var, const char *value);
int adjust_shared_perm(const char *path);
int safe_create_leading_directories(char *path);
char *enter_repo(char *path, int strict);
+static inline int is_absolute_path(const char *path)
+{
+ return path[0] == '/';
+}
+const char *make_absolute_path(const char *path);
/* Read and unpack a sha1 file into memory, write memory to a sha1 file */
extern int sha1_object_info(const unsigned char *, unsigned long *);
@@ -353,8 +383,6 @@ extern int move_temp_to_file(const char *tmpfile, const char *filename);
extern int has_sha1_pack(const unsigned char *sha1, const char **ignore);
extern int has_sha1_file(const unsigned char *sha1);
-extern void *map_sha1_file(const unsigned char *sha1, unsigned long *);
-extern int legacy_loose_object(unsigned char *);
extern int has_pack_file(const unsigned char *sha1);
extern int has_pack_index(const unsigned char *sha1);
@@ -389,9 +417,16 @@ extern void *read_object_with_reference(const unsigned char *sha1,
unsigned long *size,
unsigned char *sha1_ret);
-enum date_mode { DATE_NORMAL = 0, DATE_RELATIVE, DATE_SHORT, DATE_LOCAL };
+enum date_mode {
+ DATE_NORMAL = 0,
+ DATE_RELATIVE,
+ DATE_SHORT,
+ DATE_LOCAL,
+ DATE_ISO8601,
+ DATE_RFC2822
+};
+
const char *show_date(unsigned long time, int timezone, enum date_mode mode);
-const char *show_rfc2822_date(unsigned long time, int timezone);
int parse_date(const char *date, char *buf, int bufsize);
void datestamp(char *buf, int bufsize);
unsigned long approxidate(const char *);
@@ -463,11 +498,10 @@ struct ref {
#define REF_HEADS (1u << 1)
#define REF_TAGS (1u << 2)
-extern pid_t git_connect(int fd[2], char *url, const char *prog);
+#define CONNECT_VERBOSE (1u << 0)
+extern pid_t git_connect(int fd[2], char *url, const char *prog, int flags);
extern int finish_connect(pid_t pid);
extern int path_match(const char *path, int nr, char **match);
-extern int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
- int nr_refspec, char **refspec, int all);
extern int get_ack(int fd, unsigned char *result_sha1);
extern struct ref **get_remote_heads(int in, struct ref **list, int nr_match, char **match, unsigned int flags);
extern int server_supports(const char *feature);
@@ -480,14 +514,15 @@ extern void prepare_packed_git(void);
extern void reprepare_packed_git(void);
extern void install_packed_git(struct packed_git *pack);
-extern struct packed_git *find_sha1_pack(const unsigned char *sha1,
+extern struct packed_git *find_sha1_pack(const unsigned char *sha1,
struct packed_git *packs);
extern void pack_report(void);
+extern int open_pack_index(struct packed_git *);
extern unsigned char* use_pack(struct packed_git *, struct pack_window **, off_t, unsigned int *);
extern void unuse_pack(struct pack_window **);
extern struct packed_git *add_packed_git(const char *, int, int);
-extern const unsigned char *nth_packed_object_sha1(const struct packed_git *, uint32_t);
+extern const unsigned char *nth_packed_object_sha1(struct packed_git *, uint32_t);
extern off_t find_pack_entry_one(const unsigned char *, struct packed_git *);
extern void *unpack_entry(struct packed_git *, off_t, enum object_type *, unsigned long *);
extern unsigned long unpack_object_header_gently(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep);
@@ -501,7 +536,10 @@ typedef int (*config_fn_t)(const char *, const char *);
extern int git_default_config(const char *, const char *);
extern int git_config_from_file(config_fn_t fn, const char *);
extern int git_config(config_fn_t fn);
+extern int git_parse_long(const char *, long *);
+extern int git_parse_ulong(const char *, unsigned long *);
extern int git_config_int(const char *, const char *);
+extern unsigned long git_config_ulong(const char *, const char *);
extern int git_config_bool(const char *, const char *);
extern int git_config_set(const char *, const char *);
extern int git_config_set_multivar(const char *, const char *, const char *, int);
@@ -515,6 +553,8 @@ extern char git_default_name[MAX_GITNAME];
extern const char *git_commit_encoding;
extern const char *git_log_output_encoding;
+/* IO helper functions */
+extern void maybe_flush_or_die(FILE *, const char *);
extern int copy_fd(int ifd, int ofd);
extern int read_in_full(int fd, void *buf, size_t count);
extern int write_in_full(int fd, const void *buf, size_t count);
@@ -524,6 +564,7 @@ extern int write_or_whine_pipe(int fd, const void *buf, size_t count, const char
/* pager.c */
extern void setup_pager(void);
+extern char *pager_program;
extern int pager_in_use;
extern int pager_use_color;
diff --git a/combine-diff.c b/combine-diff.c
index ea3ca5f..ef62234 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -215,8 +215,7 @@ static void combine_diff(const unsigned char *parent, mmfile_t *result_file,
parent_file.ptr = grab_blob(parent, &sz);
parent_file.size = sz;
xpp.flags = XDF_NEED_MINIMAL;
- xecfg.ctxlen = 0;
- xecfg.flags = 0;
+ memset(&xecfg, 0, sizeof(xecfg));
ecb.outf = xdiff_outf;
ecb.priv = &state;
memset(&state, 0, sizeof(state));
diff --git a/commit.c b/commit.c
index 5632e32..dc5a064 100644
--- a/commit.c
+++ b/commit.c
@@ -27,7 +27,7 @@ struct sort_node
const char *commit_type = "commit";
-struct cmt_fmt_map {
+static struct cmt_fmt_map {
const char *n;
size_t cmp_len;
enum cmit_fmt v;
@@ -148,7 +148,7 @@ static int commit_graft_pos(const unsigned char *sha1)
int register_commit_graft(struct commit_graft *graft, int ignore_dups)
{
int pos = commit_graft_pos(graft->sha1);
-
+
if (0 <= pos) {
if (ignore_dups)
free(graft);
@@ -406,7 +406,7 @@ struct commit_list * insert_by_date(struct commit *item, struct commit_list **li
return commit_list_insert(item, pp);
}
-
+
void sort_by_date(struct commit_list **list)
{
struct commit_list *ret = NULL;
@@ -529,6 +529,14 @@ static int add_rfc2047(char *buf, const char *line, int len,
return bp - buf;
}
+static unsigned long bound_rfc2047(unsigned long len, const char *encoding)
+{
+ /* upper bound of q encoded string of length 'len' */
+ unsigned long elen = strlen(encoding);
+
+ return len * 3 + elen + 100;
+}
+
static int add_user_info(const char *what, enum cmit_fmt fmt, char *buf,
const char *line, enum date_mode dmode,
const char *encoding)
@@ -577,7 +585,7 @@ static int add_user_info(const char *what, enum cmit_fmt fmt, char *buf,
break;
case CMIT_FMT_EMAIL:
ret += sprintf(buf + ret, "Date: %s\n",
- show_rfc2822_date(time, tz));
+ show_date(time, tz, DATE_RFC2822));
break;
case CMIT_FMT_FULLER:
ret += sprintf(buf + ret, "%sDate: %s\n", what,
@@ -713,7 +721,10 @@ static char *logmsg_reencode(const struct commit *commit,
encoding = get_header(commit, "encoding");
use_encoding = encoding ? encoding : utf8;
if (!strcmp(use_encoding, output_encoding))
- out = xstrdup(commit->buffer);
+ if (encoding) /* we'll strip encoding header later */
+ out = xstrdup(commit->buffer);
+ else
+ return NULL; /* nothing to do */
else
out = reencode_string(commit->buffer,
output_encoding, use_encoding);
@@ -770,13 +781,14 @@ static void fill_person(struct interp *table, const char *msg, int len)
tz = -tz;
}
- interp_set_entry(table, 2, show_date(date, tz, 0));
- interp_set_entry(table, 3, show_rfc2822_date(date, tz));
- interp_set_entry(table, 4, show_date(date, tz, 1));
+ interp_set_entry(table, 2, show_date(date, tz, DATE_NORMAL));
+ interp_set_entry(table, 3, show_date(date, tz, DATE_RFC2822));
+ interp_set_entry(table, 4, show_date(date, tz, DATE_RELATIVE));
+ interp_set_entry(table, 6, show_date(date, tz, DATE_ISO8601));
}
static long format_commit_message(const struct commit *commit,
- const char *msg, char *buf, unsigned long space)
+ const char *msg, char **buf_p, unsigned long *space_p)
{
struct interp table[] = {
{ "%H" }, /* commit hash */
@@ -791,12 +803,14 @@ static long format_commit_message(const struct commit *commit,
{ "%aD" }, /* author date, RFC2822 style */
{ "%ar" }, /* author date, relative */
{ "%at" }, /* author date, UNIX timestamp */
+ { "%ai" }, /* author date, ISO 8601 */
{ "%cn" }, /* committer name */
{ "%ce" }, /* committer email */
{ "%cd" }, /* committer date */
{ "%cD" }, /* committer date, RFC2822 style */
{ "%cr" }, /* committer date, relative */
{ "%ct" }, /* committer date, UNIX timestamp */
+ { "%ci" }, /* committer date, ISO 8601 */
{ "%e" }, /* encoding */
{ "%s" }, /* subject */
{ "%b" }, /* body */
@@ -813,10 +827,11 @@ static long format_commit_message(const struct commit *commit,
IPARENTS, IPARENTS_ABBREV,
IAUTHOR_NAME, IAUTHOR_EMAIL,
IAUTHOR_DATE, IAUTHOR_DATE_RFC2822, IAUTHOR_DATE_RELATIVE,
- IAUTHOR_TIMESTAMP,
+ IAUTHOR_TIMESTAMP, IAUTHOR_ISO8601,
ICOMMITTER_NAME, ICOMMITTER_EMAIL,
ICOMMITTER_DATE, ICOMMITTER_DATE_RFC2822,
ICOMMITTER_DATE_RELATIVE, ICOMMITTER_TIMESTAMP,
+ ICOMMITTER_ISO8601,
IENCODING,
ISUBJECT,
IBODY,
@@ -905,31 +920,252 @@ static long format_commit_message(const struct commit *commit,
if (!table[i].value)
interp_set_entry(table, i, "<unknown>");
- interpolate(buf, space, user_format, table, ARRAY_SIZE(table));
+ do {
+ char *buf = *buf_p;
+ unsigned long space = *space_p;
+
+ space = interpolate(buf, space, user_format,
+ table, ARRAY_SIZE(table));
+ if (!space)
+ break;
+ buf = xrealloc(buf, space);
+ *buf_p = buf;
+ *space_p = space;
+ } while (1);
interp_clear_table(table, ARRAY_SIZE(table));
- return strlen(buf);
+ return strlen(*buf_p);
+}
+
+static void pp_header(enum cmit_fmt fmt,
+ int abbrev,
+ enum date_mode dmode,
+ const char *encoding,
+ const struct commit *commit,
+ const char **msg_p,
+ unsigned long *len_p,
+ unsigned long *ofs_p,
+ char **buf_p,
+ unsigned long *space_p)
+{
+ int parents_shown = 0;
+
+ for (;;) {
+ const char *line = *msg_p;
+ char *dst;
+ int linelen = get_one_line(*msg_p, *len_p);
+ unsigned long len;
+
+ if (!linelen)
+ return;
+ *msg_p += linelen;
+ *len_p -= linelen;
+
+ if (linelen == 1)
+ /* End of header */
+ return;
+
+ ALLOC_GROW(*buf_p, linelen + *ofs_p + 20, *space_p);
+ dst = *buf_p + *ofs_p;
+
+ if (fmt == CMIT_FMT_RAW) {
+ memcpy(dst, line, linelen);
+ *ofs_p += linelen;
+ continue;
+ }
+
+ if (!memcmp(line, "parent ", 7)) {
+ if (linelen != 48)
+ die("bad parent line in commit");
+ continue;
+ }
+
+ if (!parents_shown) {
+ struct commit_list *parent;
+ int num;
+ for (parent = commit->parents, num = 0;
+ parent;
+ parent = parent->next, num++)
+ ;
+ /* with enough slop */
+ num = *ofs_p + num * 50 + 20;
+ ALLOC_GROW(*buf_p, num, *space_p);
+ dst = *buf_p + *ofs_p;
+ *ofs_p += add_merge_info(fmt, dst, commit, abbrev);
+ parents_shown = 1;
+ }
+
+ /*
+ * MEDIUM == DEFAULT shows only author with dates.
+ * FULL shows both authors but not dates.
+ * FULLER shows both authors and dates.
+ */
+ if (!memcmp(line, "author ", 7)) {
+ len = linelen;
+ if (fmt == CMIT_FMT_EMAIL)
+ len = bound_rfc2047(linelen, encoding);
+ ALLOC_GROW(*buf_p, *ofs_p + len + 80, *space_p);
+ dst = *buf_p + *ofs_p;
+ *ofs_p += add_user_info("Author", fmt, dst,
+ line + 7, dmode, encoding);
+ }
+
+ if (!memcmp(line, "committer ", 10) &&
+ (fmt == CMIT_FMT_FULL || fmt == CMIT_FMT_FULLER)) {
+ len = linelen;
+ if (fmt == CMIT_FMT_EMAIL)
+ len = bound_rfc2047(linelen, encoding);
+ ALLOC_GROW(*buf_p, *ofs_p + len + 80, *space_p);
+ dst = *buf_p + *ofs_p;
+ *ofs_p += add_user_info("Commit", fmt, dst,
+ line + 10, dmode, encoding);
+ }
+ }
+}
+
+static void pp_title_line(enum cmit_fmt fmt,
+ const char **msg_p,
+ unsigned long *len_p,
+ unsigned long *ofs_p,
+ char **buf_p,
+ unsigned long *space_p,
+ int indent,
+ const char *subject,
+ const char *after_subject,
+ const char *encoding,
+ int plain_non_ascii)
+{
+ char *title;
+ unsigned long title_alloc, title_len;
+ unsigned long len;
+
+ title_len = 0;
+ title_alloc = 80;
+ title = xmalloc(title_alloc);
+ for (;;) {
+ const char *line = *msg_p;
+ int linelen = get_one_line(line, *len_p);
+ *msg_p += linelen;
+ *len_p -= linelen;
+
+ if (!linelen || is_empty_line(line, &linelen))
+ break;
+
+ if (title_alloc <= title_len + linelen + 2) {
+ title_alloc = title_len + linelen + 80;
+ title = xrealloc(title, title_alloc);
+ }
+ len = 0;
+ if (title_len) {
+ if (fmt == CMIT_FMT_EMAIL) {
+ len++;
+ title[title_len++] = '\n';
+ }
+ len++;
+ title[title_len++] = ' ';
+ }
+ memcpy(title + title_len, line, linelen);
+ title_len += linelen;
+ }
+
+ /* Enough slop for the MIME header and rfc2047 */
+ len = bound_rfc2047(title_len, encoding)+ 1000;
+ if (subject)
+ len += strlen(subject);
+ if (after_subject)
+ len += strlen(after_subject);
+ if (encoding)
+ len += strlen(encoding);
+ ALLOC_GROW(*buf_p, title_len + *ofs_p + len, *space_p);
+
+ if (subject) {
+ len = strlen(subject);
+ memcpy(*buf_p + *ofs_p, subject, len);
+ *ofs_p += len;
+ *ofs_p += add_rfc2047(*buf_p + *ofs_p,
+ title, title_len, encoding);
+ } else {
+ memcpy(*buf_p + *ofs_p, title, title_len);
+ *ofs_p += title_len;
+ }
+ (*buf_p)[(*ofs_p)++] = '\n';
+ if (plain_non_ascii) {
+ const char *header_fmt =
+ "MIME-Version: 1.0\n"
+ "Content-Type: text/plain; charset=%s\n"
+ "Content-Transfer-Encoding: 8bit\n";
+ *ofs_p += snprintf(*buf_p + *ofs_p,
+ *space_p - *ofs_p,
+ header_fmt, encoding);
+ }
+ if (after_subject) {
+ len = strlen(after_subject);
+ memcpy(*buf_p + *ofs_p, after_subject, len);
+ *ofs_p += len;
+ }
+ free(title);
+ if (fmt == CMIT_FMT_EMAIL) {
+ ALLOC_GROW(*buf_p, *ofs_p + 20, *space_p);
+ (*buf_p)[(*ofs_p)++] = '\n';
+ }
+}
+
+static void pp_remainder(enum cmit_fmt fmt,
+ const char **msg_p,
+ unsigned long *len_p,
+ unsigned long *ofs_p,
+ char **buf_p,
+ unsigned long *space_p,
+ int indent)
+{
+ int first = 1;
+ for (;;) {
+ const char *line = *msg_p;
+ int linelen = get_one_line(line, *len_p);
+ *msg_p += linelen;
+ *len_p -= linelen;
+
+ if (!linelen)
+ break;
+
+ if (is_empty_line(line, &linelen)) {
+ if (first)
+ continue;
+ if (fmt == CMIT_FMT_SHORT)
+ break;
+ }
+ first = 0;
+
+ ALLOC_GROW(*buf_p, *ofs_p + linelen + indent + 20, *space_p);
+ if (indent) {
+ memset(*buf_p + *ofs_p, ' ', indent);
+ *ofs_p += indent;
+ }
+ memcpy(*buf_p + *ofs_p, line, linelen);
+ *ofs_p += linelen;
+ (*buf_p)[(*ofs_p)++] = '\n';
+ }
}
unsigned long pretty_print_commit(enum cmit_fmt fmt,
const struct commit *commit,
unsigned long len,
- char *buf, unsigned long space,
+ char **buf_p, unsigned long *space_p,
int abbrev, const char *subject,
const char *after_subject,
enum date_mode dmode)
{
- int hdr = 1, body = 0, seen_title = 0;
unsigned long offset = 0;
+ unsigned long beginning_of_body;
int indent = 4;
- int parents_shown = 0;
const char *msg = commit->buffer;
int plain_non_ascii = 0;
char *reencoded;
const char *encoding;
+ char *buf;
if (fmt == CMIT_FMT_USERFORMAT)
- return format_commit_message(commit, msg, buf, space);
+ return format_commit_message(commit, msg, buf_p, space_p);
encoding = (git_log_output_encoding
? git_log_output_encoding
@@ -937,8 +1173,10 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt,
if (!encoding)
encoding = "utf-8";
reencoded = logmsg_reencode(commit, encoding);
- if (reencoded)
+ if (reencoded) {
msg = reencoded;
+ len = strlen(reencoded);
+ }
if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL)
indent = 0;
@@ -969,137 +1207,57 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt,
}
}
+ pp_header(fmt, abbrev, dmode, encoding,
+ commit, &msg, &len,
+ &offset, buf_p, space_p);
+ if (fmt != CMIT_FMT_ONELINE && !subject) {
+ ALLOC_GROW(*buf_p, offset + 20, *space_p);
+ (*buf_p)[offset++] = '\n';
+ }
+
+ /* Skip excess blank lines at the beginning of body, if any... */
for (;;) {
- const char *line = msg;
int linelen = get_one_line(msg, len);
-
+ int ll = linelen;
if (!linelen)
break;
-
- /*
- * We want some slop for indentation and a possible
- * final "...". Thus the "+ 20".
- */
- if (offset + linelen + 20 > space) {
- memcpy(buf + offset, " ...\n", 8);
- offset += 8;
+ if (!is_empty_line(msg, &ll))
break;
- }
-
msg += linelen;
len -= linelen;
- if (hdr) {
- if (linelen == 1) {
- hdr = 0;
- if ((fmt != CMIT_FMT_ONELINE) && !subject)
- buf[offset++] = '\n';
- continue;
- }
- if (fmt == CMIT_FMT_RAW) {
- memcpy(buf + offset, line, linelen);
- offset += linelen;
- continue;
- }
- if (!memcmp(line, "parent ", 7)) {
- if (linelen != 48)
- die("bad parent line in commit");
- continue;
- }
-
- if (!parents_shown) {
- offset += add_merge_info(fmt, buf + offset,
- commit, abbrev);
- parents_shown = 1;
- continue;
- }
- /*
- * MEDIUM == DEFAULT shows only author with dates.
- * FULL shows both authors but not dates.
- * FULLER shows both authors and dates.
- */
- if (!memcmp(line, "author ", 7))
- offset += add_user_info("Author", fmt,
- buf + offset,
- line + 7,
- dmode,
- encoding);
- if (!memcmp(line, "committer ", 10) &&
- (fmt == CMIT_FMT_FULL || fmt == CMIT_FMT_FULLER))
- offset += add_user_info("Commit", fmt,
- buf + offset,
- line + 10,
- dmode,
- encoding);
- continue;
- }
+ }
- if (!subject)
- body = 1;
+ /* These formats treat the title line specially. */
+ if (fmt == CMIT_FMT_ONELINE
+ || fmt == CMIT_FMT_EMAIL)
+ pp_title_line(fmt, &msg, &len, &offset,
+ buf_p, space_p, indent,
+ subject, after_subject, encoding,
+ plain_non_ascii);
- if (is_empty_line(line, &linelen)) {
- if (!seen_title)
- continue;
- if (!body)
- continue;
- if (subject)
- continue;
- if (fmt == CMIT_FMT_SHORT)
- break;
- }
+ beginning_of_body = offset;
+ if (fmt != CMIT_FMT_ONELINE)
+ pp_remainder(fmt, &msg, &len, &offset,
+ buf_p, space_p, indent);
- seen_title = 1;
- if (subject) {
- int slen = strlen(subject);
- memcpy(buf + offset, subject, slen);
- offset += slen;
- offset += add_rfc2047(buf + offset, line, linelen,
- encoding);
- }
- else {
- memset(buf + offset, ' ', indent);
- memcpy(buf + offset + indent, line, linelen);
- offset += linelen + indent;
- }
- buf[offset++] = '\n';
- if (fmt == CMIT_FMT_ONELINE)
- break;
- if (subject && plain_non_ascii) {
- int sz;
- char header[512];
- const char *header_fmt =
- "MIME-Version: 1.0\n"
- "Content-Type: text/plain; charset=%s\n"
- "Content-Transfer-Encoding: 8bit\n";
- sz = snprintf(header, sizeof(header), header_fmt,
- encoding);
- if (sizeof(header) < sz)
- die("Encoding name %s too long", encoding);
- memcpy(buf + offset, header, sz);
- offset += sz;
- }
- if (after_subject) {
- int slen = strlen(after_subject);
- if (slen > space - offset - 1)
- slen = space - offset - 1;
- memcpy(buf + offset, after_subject, slen);
- offset += slen;
- after_subject = NULL;
- }
- subject = NULL;
- }
- while (offset && isspace(buf[offset-1]))
+ while (offset && isspace((*buf_p)[offset-1]))
offset--;
+
+ ALLOC_GROW(*buf_p, offset + 20, *space_p);
+ buf = *buf_p;
+
/* Make sure there is an EOLN for the non-oneline case */
if (fmt != CMIT_FMT_ONELINE)
buf[offset++] = '\n';
+
/*
- * make sure there is another EOLN to separate the headers from whatever
- * body the caller appends if we haven't already written a body
+ * The caller may append additional body text in e-mail
+ * format. Make sure we did not strip the blank line
+ * between the header and the body.
*/
- if (fmt == CMIT_FMT_EMAIL && !body)
+ if (fmt == CMIT_FMT_EMAIL && offset <= beginning_of_body)
buf[offset++] = '\n';
buf[offset] = '\0';
-
free(reencoded);
return offset;
}
@@ -1116,15 +1274,6 @@ struct commit *pop_commit(struct commit_list **stack)
return item;
}
-int count_parents(struct commit * commit)
-{
- int count;
- struct commit_list * parents = commit->parents;
- for (count = 0; parents; parents = parents->next,count++)
- ;
- return count;
-}
-
void topo_sort_default_setter(struct commit *c, void *data)
{
c->util = data;
@@ -1160,7 +1309,7 @@ void sort_in_topological_order_fn(struct commit_list ** list, int lifo,
next = next->next;
count++;
}
-
+
if (!count)
return;
/* allocate an array to help sort the list */
@@ -1188,11 +1337,11 @@ void sort_in_topological_order_fn(struct commit_list ** list, int lifo,
}
next=next->next;
}
- /*
+ /*
* find the tips
*
- * tips are nodes not reachable from any other node in the list
- *
+ * tips are nodes not reachable from any other node in the list
+ *
* the tips serve as a starting set for the work queue.
*/
next=*list;
@@ -1220,7 +1369,7 @@ void sort_in_topological_order_fn(struct commit_list ** list, int lifo,
if (pn) {
/*
- * parents are only enqueued for emission
+ * parents are only enqueued for emission
* when all their children have been emitted thereby
* guaranteeing topological order.
*/
diff --git a/commit.h b/commit.h
index 86e8dca..467872e 100644
--- a/commit.h
+++ b/commit.h
@@ -61,20 +61,18 @@ enum cmit_fmt {
};
extern enum cmit_fmt get_commit_format(const char *arg);
-extern unsigned long pretty_print_commit(enum cmit_fmt fmt, const struct commit *, unsigned long len, char *buf, unsigned long space, int abbrev, const char *subject, const char *after_subject, enum date_mode dmode);
+extern unsigned long pretty_print_commit(enum cmit_fmt fmt, const struct commit *, unsigned long len, char **buf_p, unsigned long *space_p, int abbrev, const char *subject, const char *after_subject, enum date_mode dmode);
/** Removes the first commit from a list sorted by date, and adds all
* of its parents.
**/
-struct commit *pop_most_recent_commit(struct commit_list **list,
+struct commit *pop_most_recent_commit(struct commit_list **list,
unsigned int mark);
struct commit *pop_commit(struct commit_list **stack);
void clear_commit_marks(struct commit *commit, unsigned int mark);
-int count_parents(struct commit * commit);
-
/*
* Performs an in-place topological sort of list supplied.
*
diff --git a/compat/mmap.c b/compat/mmap.c
index 4cfaee3..c9d46d1 100644
--- a/compat/mmap.c
+++ b/compat/mmap.c
@@ -40,4 +40,3 @@ int git_munmap(void *start, size_t length)
free(start);
return 0;
}
-
diff --git a/config.c b/config.c
index 7b655fd..dd2de6e 100644
--- a/config.c
+++ b/config.c
@@ -12,6 +12,8 @@
static FILE *config_file;
static const char *config_file_name;
static int config_linenr;
+static int zlib_compression_seen;
+
static int get_next_char(void)
{
int c;
@@ -231,21 +233,55 @@ static int git_parse_file(config_fn_t fn)
die("bad config file line %d in %s", config_linenr, config_file_name);
}
-int git_config_int(const char *name, const char *value)
+static unsigned long get_unit_factor(const char *end)
+{
+ if (!*end)
+ return 1;
+ else if (!strcasecmp(end, "k"))
+ return 1024;
+ else if (!strcasecmp(end, "m"))
+ return 1024 * 1024;
+ else if (!strcasecmp(end, "g"))
+ return 1024 * 1024 * 1024;
+ die("unknown unit: '%s'", end);
+}
+
+int git_parse_long(const char *value, long *ret)
+{
+ if (value && *value) {
+ char *end;
+ long val = strtol(value, &end, 0);
+ *ret = val * get_unit_factor(end);
+ return 1;
+ }
+ return 0;
+}
+
+int git_parse_ulong(const char *value, unsigned long *ret)
{
if (value && *value) {
char *end;
- int val = strtol(value, &end, 0);
- if (!*end)
- return val;
- if (!strcasecmp(end, "k"))
- return val * 1024;
- if (!strcasecmp(end, "m"))
- return val * 1024 * 1024;
- if (!strcasecmp(end, "g"))
- return val * 1024 * 1024 * 1024;
- }
- die("bad config value for '%s' in %s", name, config_file_name);
+ unsigned long val = strtoul(value, &end, 0);
+ *ret = val * get_unit_factor(end);
+ return 1;
+ }
+ return 0;
+}
+
+int git_config_int(const char *name, const char *value)
+{
+ long ret;
+ if (!git_parse_long(value, &ret))
+ die("bad config value for '%s' in %s", name, config_file_name);
+ return ret;
+}
+
+unsigned long git_config_ulong(const char *name, const char *value)
+{
+ unsigned long ret;
+ if (!git_parse_ulong(value, &ret))
+ die("bad config value for '%s' in %s", name, config_file_name);
+ return ret;
}
int git_config_bool(const char *name, const char *value)
@@ -269,6 +305,11 @@ int git_default_config(const char *var, const char *value)
return 0;
}
+ if (!strcmp(var, "core.quotepath")) {
+ quote_path_fully = git_config_bool(var, value);
+ return 0;
+ }
+
if (!strcmp(var, "core.symlinks")) {
has_symlinks = git_config_bool(var, value);
return 0;
@@ -299,8 +340,14 @@ int git_default_config(const char *var, const char *value)
return 0;
}
- if (!strcmp(var, "core.legacyheaders")) {
- use_legacy_headers = git_config_bool(var, value);
+ if (!strcmp(var, "core.loosecompression")) {
+ int level = git_config_int(var, value);
+ if (level == -1)
+ level = Z_DEFAULT_COMPRESSION;
+ else if (level < 0 || level > Z_BEST_COMPRESSION)
+ die("bad zlib compression level %d", level);
+ zlib_compression_level = level;
+ zlib_compression_seen = 1;
return 0;
}
@@ -310,7 +357,10 @@ int git_default_config(const char *var, const char *value)
level = Z_DEFAULT_COMPRESSION;
else if (level < 0 || level > Z_BEST_COMPRESSION)
die("bad zlib compression level %d", level);
- zlib_compression_level = level;
+ core_compression_level = level;
+ core_compression_seen = 1;
+ if (!zlib_compression_seen)
+ zlib_compression_level = level;
return 0;
}
@@ -371,6 +421,11 @@ int git_default_config(const char *var, const char *value)
return 0;
}
+ if (!strcmp(var, "core.pager")) {
+ pager_program = xstrdup(value);
+ return 0;
+ }
+
/* Add other config variables here and to Documentation/config.txt. */
return 0;
}
@@ -512,7 +567,7 @@ static int store_aux(const char* key, const char* value)
return 0;
}
-static int write_error()
+static int write_error(void)
{
fprintf(stderr, "Failed to write new configuration file\n");
@@ -610,7 +665,7 @@ static ssize_t find_beginning_of_line(const char* contents, size_t size,
size_t equal_offset = size, bracket_offset = size;
ssize_t offset;
- for (offset = offset_-2; offset > 0
+ for (offset = offset_-2; offset > 0
&& contents[offset] != '\n'; offset--)
switch (contents[offset]) {
case '=': equal_offset = offset; break;
@@ -660,7 +715,7 @@ int git_config_set_multivar(const char* key, const char* value,
int fd = -1, in_fd;
int ret;
char* config_filename;
- char* lock_file;
+ struct lock_file *lock = NULL;
const char* last_dot = strrchr(key, '.');
config_filename = getenv(CONFIG_ENVIRONMENT);
@@ -670,7 +725,6 @@ int git_config_set_multivar(const char* key, const char* value,
config_filename = git_path("config");
}
config_filename = xstrdup(config_filename);
- lock_file = xstrdup(mkpath("%s.lock", config_filename));
/*
* Since "key" actually contains the section name and the real
@@ -715,11 +769,12 @@ int git_config_set_multivar(const char* key, const char* value,
store.key[i] = 0;
/*
- * The lock_file serves a purpose in addition to locking: the new
+ * The lock serves a purpose in addition to locking: the new
* contents of .git/config will be written into it.
*/
- fd = open(lock_file, O_WRONLY | O_CREAT | O_EXCL, 0666);
- if (fd < 0 || adjust_shared_perm(lock_file)) {
+ lock = xcalloc(sizeof(struct lock_file), 1);
+ fd = hold_lock_file_for_update(lock, config_filename, 0);
+ if (fd < 0) {
fprintf(stderr, "could not lock config file\n");
free(store.key);
ret = -1;
@@ -859,25 +914,31 @@ int git_config_set_multivar(const char* key, const char* value,
goto write_err_out;
munmap(contents, contents_sz);
- unlink(config_filename);
}
- if (rename(lock_file, config_filename) < 0) {
- fprintf(stderr, "Could not rename the lock file?\n");
+ if (close(fd) || commit_lock_file(lock) < 0) {
+ fprintf(stderr, "Cannot commit config file!\n");
ret = 4;
goto out_free;
}
+ /* fd is closed, so don't try to close it below. */
+ fd = -1;
+ /*
+ * lock is committed, so don't try to roll it back below.
+ * NOTE: Since lockfile.c keeps a linked list of all created
+ * lock_file structures, it isn't safe to free(lock). It's
+ * better to just leave it hanging around.
+ */
+ lock = NULL;
ret = 0;
out_free:
if (0 <= fd)
close(fd);
+ if (lock)
+ rollback_lock_file(lock);
free(config_filename);
- if (lock_file) {
- unlink(lock_file);
- free(lock_file);
- }
return ret;
write_err_out:
@@ -978,4 +1039,3 @@ int git_config_rename_section(const char *old_name, const char *new_name)
free(config_filename);
return ret;
}
-
diff --git a/config.mak.in b/config.mak.in
index eb9d7a5..a3032e3 100644
--- a/config.mak.in
+++ b/config.mak.in
@@ -38,4 +38,3 @@ NO_STRCASESTR=@NO_STRCASESTR@
NO_STRLCPY=@NO_STRLCPY@
NO_SETENV=@NO_SETENV@
NO_ICONV=@NO_ICONV@
-
diff --git a/configure.ac b/configure.ac
index 50d2b85..84fd7f1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -69,12 +69,26 @@ fi \
## Site configuration related to programs (before tests)
## --with-PACKAGE[=ARG] and --without-PACKAGE
#
+# Set lib to alternative name of lib directory (e.g. lib64)
+AC_ARG_WITH([lib],
+ [AS_HELP_STRING([--with-lib=ARG],
+ [ARG specifies alternative name for lib directory])],
+ [if test "$withval" = "no" -o "$withval" = "yes"; then \
+ AC_MSG_WARN([You should provide name for --with-lib=ARG]); \
+else \
+ GIT_CONF_APPEND_LINE(lib=$withval); \
+fi; \
+],[])
+#
# Define SHELL_PATH to provide path to shell.
GIT_ARG_SET_PATH(shell)
#
# Define PERL_PATH to provide path to Perl.
GIT_ARG_SET_PATH(perl)
#
+# Define ZLIB_PATH to provide path to zlib.
+GIT_ARG_SET_PATH(zlib)
+#
# Declare the with-tcltk/without-tcltk options.
AC_ARG_WITH(tcltk,
AS_HELP_STRING([--with-tcltk],[use Tcl/Tk GUI (default is YES)])
diff --git a/connect.c b/connect.c
index da89c9c..715cdc0 100644
--- a/connect.c
+++ b/connect.c
@@ -4,6 +4,7 @@
#include "quote.h"
#include "refs.h"
#include "run-command.h"
+#include "remote.h"
static char *server_capabilities;
@@ -71,7 +72,7 @@ struct ref **get_remote_heads(int in, struct ref **list,
continue;
if (nr_match && !path_match(name, nr_match, match))
continue;
- ref = xcalloc(1, sizeof(*ref) + len - 40);
+ ref = alloc_ref(len - 40);
hashcpy(ref->old_sha1, old_sha1);
memcpy(ref->name, buffer + 41, len - 40);
*list = ref;
@@ -128,245 +129,6 @@ int path_match(const char *path, int nr, char **match)
return 0;
}
-struct refspec {
- char *src;
- char *dst;
- char force;
-};
-
-/*
- * A:B means fast forward remote B with local A.
- * +A:B means overwrite remote B with local A.
- * +A is a shorthand for +A:A.
- * A is a shorthand for A:A.
- * :B means delete remote B.
- */
-static struct refspec *parse_ref_spec(int nr_refspec, char **refspec)
-{
- int i;
- struct refspec *rs = xcalloc(sizeof(*rs), (nr_refspec + 1));
- for (i = 0; i < nr_refspec; i++) {
- char *sp, *dp, *ep;
- sp = refspec[i];
- if (*sp == '+') {
- rs[i].force = 1;
- sp++;
- }
- ep = strchr(sp, ':');
- if (ep) {
- dp = ep + 1;
- *ep = 0;
- }
- else
- dp = sp;
- rs[i].src = sp;
- rs[i].dst = dp;
- }
- rs[nr_refspec].src = rs[nr_refspec].dst = NULL;
- return rs;
-}
-
-static int count_refspec_match(const char *pattern,
- struct ref *refs,
- struct ref **matched_ref)
-{
- int patlen = strlen(pattern);
- struct ref *matched_weak = NULL;
- struct ref *matched = NULL;
- int weak_match = 0;
- int match = 0;
-
- for (weak_match = match = 0; refs; refs = refs->next) {
- char *name = refs->name;
- int namelen = strlen(name);
- int weak_match;
-
- if (namelen < patlen ||
- memcmp(name + namelen - patlen, pattern, patlen))
- continue;
- if (namelen != patlen && name[namelen - patlen - 1] != '/')
- continue;
-
- /* A match is "weak" if it is with refs outside
- * heads or tags, and did not specify the pattern
- * in full (e.g. "refs/remotes/origin/master") or at
- * least from the toplevel (e.g. "remotes/origin/master");
- * otherwise "git push $URL master" would result in
- * ambiguity between remotes/origin/master and heads/master
- * at the remote site.
- */
- if (namelen != patlen &&
- patlen != namelen - 5 &&
- prefixcmp(name, "refs/heads/") &&
- prefixcmp(name, "refs/tags/")) {
- /* We want to catch the case where only weak
- * matches are found and there are multiple
- * matches, and where more than one strong
- * matches are found, as ambiguous. One
- * strong match with zero or more weak matches
- * are acceptable as a unique match.
- */
- matched_weak = refs;
- weak_match++;
- }
- else {
- matched = refs;
- match++;
- }
- }
- if (!matched) {
- *matched_ref = matched_weak;
- return weak_match;
- }
- else {
- *matched_ref = matched;
- return match;
- }
-}
-
-static void link_dst_tail(struct ref *ref, struct ref ***tail)
-{
- **tail = ref;
- *tail = &ref->next;
- **tail = NULL;
-}
-
-static struct ref *try_explicit_object_name(const char *name)
-{
- unsigned char sha1[20];
- struct ref *ref;
- int len;
-
- if (!*name) {
- ref = xcalloc(1, sizeof(*ref) + 20);
- strcpy(ref->name, "(delete)");
- hashclr(ref->new_sha1);
- return ref;
- }
- if (get_sha1(name, sha1))
- return NULL;
- len = strlen(name) + 1;
- ref = xcalloc(1, sizeof(*ref) + len);
- memcpy(ref->name, name, len);
- hashcpy(ref->new_sha1, sha1);
- return ref;
-}
-
-static int match_explicit_refs(struct ref *src, struct ref *dst,
- struct ref ***dst_tail, struct refspec *rs)
-{
- int i, errs;
- for (i = errs = 0; rs[i].src; i++) {
- struct ref *matched_src, *matched_dst;
-
- matched_src = matched_dst = NULL;
- switch (count_refspec_match(rs[i].src, src, &matched_src)) {
- case 1:
- break;
- case 0:
- /* The source could be in the get_sha1() format
- * not a reference name. :refs/other is a
- * way to delete 'other' ref at the remote end.
- */
- matched_src = try_explicit_object_name(rs[i].src);
- if (matched_src)
- break;
- errs = 1;
- error("src refspec %s does not match any.",
- rs[i].src);
- break;
- default:
- errs = 1;
- error("src refspec %s matches more than one.",
- rs[i].src);
- break;
- }
- switch (count_refspec_match(rs[i].dst, dst, &matched_dst)) {
- case 1:
- break;
- case 0:
- if (!memcmp(rs[i].dst, "refs/", 5)) {
- int len = strlen(rs[i].dst) + 1;
- matched_dst = xcalloc(1, sizeof(*dst) + len);
- memcpy(matched_dst->name, rs[i].dst, len);
- link_dst_tail(matched_dst, dst_tail);
- }
- else if (!strcmp(rs[i].src, rs[i].dst) &&
- matched_src) {
- /* pushing "master:master" when
- * remote does not have master yet.
- */
- int len = strlen(matched_src->name) + 1;
- matched_dst = xcalloc(1, sizeof(*dst) + len);
- memcpy(matched_dst->name, matched_src->name,
- len);
- link_dst_tail(matched_dst, dst_tail);
- }
- else {
- errs = 1;
- error("dst refspec %s does not match any "
- "existing ref on the remote and does "
- "not start with refs/.", rs[i].dst);
- }
- break;
- default:
- errs = 1;
- error("dst refspec %s matches more than one.",
- rs[i].dst);
- break;
- }
- if (errs)
- continue;
- if (matched_dst->peer_ref) {
- errs = 1;
- error("dst ref %s receives from more than one src.",
- matched_dst->name);
- }
- else {
- matched_dst->peer_ref = matched_src;
- matched_dst->force = rs[i].force;
- }
- }
- return -errs;
-}
-
-static struct ref *find_ref_by_name(struct ref *list, const char *name)
-{
- for ( ; list; list = list->next)
- if (!strcmp(list->name, name))
- return list;
- return NULL;
-}
-
-int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
- int nr_refspec, char **refspec, int all)
-{
- struct refspec *rs = parse_ref_spec(nr_refspec, refspec);
-
- if (nr_refspec)
- return match_explicit_refs(src, dst, dst_tail, rs);
-
- /* pick the remainder */
- for ( ; src; src = src->next) {
- struct ref *dst_peer;
- if (src->peer_ref)
- continue;
- dst_peer = find_ref_by_name(dst, src->name);
- if ((dst_peer && dst_peer->peer_ref) || (!dst_peer && !all))
- continue;
- if (!dst_peer) {
- /* Create a new one and link it */
- int len = strlen(src->name) + 1;
- dst_peer = xcalloc(1, sizeof(*dst_peer) + len);
- memcpy(dst_peer->name, src->name, len);
- hashcpy(dst_peer->new_sha1, src->new_sha1);
- link_dst_tail(dst_peer, dst_tail);
- }
- dst_peer->peer_ref = src;
- }
- return 0;
-}
-