summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--.mailmap9
-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.txt109
-rw-r--r--Documentation/SubmittingPatches22
-rw-r--r--Documentation/asciidoc.conf2
-rwxr-xr-xDocumentation/cmd-list.perl3
-rw-r--r--Documentation/config.txt46
-rw-r--r--Documentation/core-tutorial.txt46
-rw-r--r--Documentation/diff-format.txt21
-rw-r--r--Documentation/diff-options.txt4
-rw-r--r--Documentation/diffcore.txt3
-rw-r--r--Documentation/docbook-xsl.css572
-rw-r--r--Documentation/fetch-options.txt1
-rw-r--r--Documentation/git-add.txt1
-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-branch.txt1
-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.txt1
-rw-r--r--Documentation/git-cherry-pick.txt1
-rw-r--r--Documentation/git-cherry.txt1
-rw-r--r--Documentation/git-clone.txt1
-rw-r--r--Documentation/git-commit-tree.txt3
-rw-r--r--Documentation/git-config.txt1
-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.txt13
-rw-r--r--Documentation/git-daemon.txt1
-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.txt1
-rw-r--r--Documentation/git-fast-import.txt1
-rw-r--r--Documentation/git-fmt-merge-msg.txt1
-rw-r--r--Documentation/git-format-patch.txt15
-rw-r--r--Documentation/git-fsck.txt6
-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-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.txt1
-rw-r--r--Documentation/git-init.txt1
-rw-r--r--Documentation/git-instaweb.txt1
-rw-r--r--Documentation/git-local-fetch.txt1
-rw-r--r--Documentation/git-log.txt1
-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.txt4
-rw-r--r--Documentation/git-mergetool.txt1
-rw-r--r--Documentation/git-mktag.txt1
-rw-r--r--Documentation/git-mktree.txt1
-rw-r--r--Documentation/git-mv.txt1
-rw-r--r--Documentation/git-name-rev.txt8
-rw-r--r--Documentation/git-p4import.txt1
-rw-r--r--Documentation/git-pack-objects.txt25
-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.txt1
-rw-r--r--Documentation/git-push.txt1
-rw-r--r--Documentation/git-quiltimport.txt1
-rw-r--r--Documentation/git-read-tree.txt1
-rw-r--r--Documentation/git-rebase.txt1
-rw-r--r--Documentation/git-reflog.txt1
-rw-r--r--Documentation/git-relink.txt1
-rw-r--r--Documentation/git-remote.txt1
-rw-r--r--Documentation/git-repack.txt6
-rw-r--r--Documentation/git-request-pull.txt1
-rw-r--r--Documentation/git-rev-list.txt10
-rw-r--r--Documentation/git-rev-parse.txt1
-rw-r--r--Documentation/git-revert.txt1
-rw-r--r--Documentation/git-rm.txt1
-rw-r--r--Documentation/git-runstatus.txt1
-rw-r--r--Documentation/git-send-email.txt3
-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.txt1
-rw-r--r--Documentation/git-ssh-upload.txt1
-rw-r--r--Documentation/git-status.txt1
-rw-r--r--Documentation/git-stripspace.txt1
-rw-r--r--Documentation/git-submodule.txt65
-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.txt1
-rw-r--r--Documentation/gitk.txt1
-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
-rw-r--r--Documentation/merge-options.txt5
-rw-r--r--Documentation/pretty-formats.txt1
-rw-r--r--Documentation/pretty-options.txt1
-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/user-manual.txt38
-rwxr-xr-xGIT-VERSION-GEN4
-rw-r--r--INSTALL3
-rw-r--r--Makefile37
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-annotate.c1
-rw-r--r--builtin-apply.c48
-rw-r--r--builtin-archive.c2
-rw-r--r--builtin-branch.c73
-rw-r--r--builtin-count-objects.c2
-rw-r--r--builtin-describe.c14
-rw-r--r--builtin-diff-index.c2
-rw-r--r--builtin-fetch--tool.c2
-rw-r--r--builtin-fmt-merge-msg.c1
-rw-r--r--builtin-fsck.c55
-rw-r--r--builtin-gc.c36
-rw-r--r--builtin-log.c105
-rw-r--r--builtin-ls-files.c2
-rw-r--r--builtin-ls-tree.c35
-rw-r--r--builtin-mailinfo.c4
-rw-r--r--builtin-mailsplit.c142
-rw-r--r--builtin-merge-file.c6
-rw-r--r--builtin-name-rev.c24
-rw-r--r--builtin-pack-objects.c718
-rw-r--r--builtin-pack-refs.c66
-rw-r--r--builtin-push.c324
-rw-r--r--builtin-reflog.c2
-rw-r--r--builtin-rerere.c1
-rw-r--r--builtin-revert.c9
-rw-r--r--builtin-shortlog.c1
-rw-r--r--builtin-stripspace.c2
-rw-r--r--builtin-update-index.c4
-rw-r--r--builtin-update-ref.c11
-rw-r--r--builtin.h3
-rw-r--r--cache-tree.c2
-rw-r--r--cache.h24
-rw-r--r--commit.c23
-rw-r--r--commit.h4
-rw-r--r--compat/mmap.c1
-rw-r--r--config.c20
-rw-r--r--config.mak.in1
-rw-r--r--connect.c310
-rw-r--r--contrib/README1
-rw-r--r--contrib/blameview/README1
-rwxr-xr-xcontrib/gitview/gitview13
-rw-r--r--contrib/hooks/post-receive-email2
-rw-r--r--contrib/remotes2config.sh2
-rwxr-xr-xcontrib/workdir/git-new-workdir12
-rw-r--r--convert-objects.c2
-rw-r--r--copy.c1
-rw-r--r--csum-file.c12
-rw-r--r--csum-file.h2
-rw-r--r--ctype.c1
-rw-r--r--daemon.c6
-rw-r--r--date.c10
-rw-r--r--diff-delta.c129
-rw-r--r--diff-lib.c2
-rw-r--r--diff.c17
-rw-r--r--diff.h2
-rw-r--r--diffcore-pickaxe.c2
-rw-r--r--dir.c6
-rw-r--r--dir.h2
-rw-r--r--entry.c6
-rw-r--r--environment.c7
-rw-r--r--fast-import.c2
-rw-r--r--fetch-pack.c4
-rw-r--r--fetch.c4
-rwxr-xr-xgit-applymbox.sh121
-rwxr-xr-xgit-applypatch.sh212
-rwxr-xr-xgit-archimport.perl175
-rwxr-xr-xgit-checkout.sh14
-rwxr-xr-xgit-clone.sh7
-rwxr-xr-xgit-commit.sh2
-rwxr-xr-xgit-cvsexportcommit.perl10
-rwxr-xr-xgit-cvsimport.perl12
-rwxr-xr-xgit-cvsserver.perl19
-rwxr-xr-xgit-fetch.sh10
-rwxr-xr-xgit-gui/GIT-VERSION-GEN2
-rw-r--r--git-gui/lib/class.tcl1
-rwxr-xr-xgit-merge-one-file.sh2
-rwxr-xr-xgit-merge.sh21
-rwxr-xr-xgit-mergetool.sh2
-rw-r--r--git-p4import.py1
-rwxr-xr-xgit-pull.sh3
-rwxr-xr-xgit-rebase.sh7
-rwxr-xr-xgit-repack.sh25
-rwxr-xr-xgit-submodule.sh194
-rwxr-xr-xgit-svnimport.perl4
-rwxr-xr-xgit-tag.sh49
-rwxr-xr-xgit-verify-tag.sh1
-rw-r--r--git.spec.in2
-rwxr-xr-xgitk2
-rw-r--r--gitweb/README1
-rwxr-xr-xgitweb/gitweb.perl64
-rw-r--r--grep.c12
-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.c4
-rw-r--r--imap-send.c2
-rw-r--r--index-pack.c208
-rw-r--r--list-objects.c2
-rw-r--r--local-fetch.c8
-rw-r--r--lockfile.c1
-rw-r--r--mailmap.c1
-rw-r--r--match-trees.c1
-rw-r--r--merge-index.c2
-rw-r--r--merge-recursive.c6
-rw-r--r--mktag.c9
-rw-r--r--mozilla-sha1/sha1.c19
-rw-r--r--mozilla-sha1/sha1.h18
-rw-r--r--object-refs.c2
-rw-r--r--object.c3
-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--patch-id.c2
-rw-r--r--path-list.c1
-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.c14
-rw-r--r--quote.h2
-rw-r--r--read-cache.c16
-rw-r--r--receive-pack.c2
-rw-r--r--refs.c57
-rw-r--r--refs.h3
-rw-r--r--remote.c568
-rw-r--r--remote.h41
-rw-r--r--revision.c28
-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--setup.c4
-rw-r--r--sha1_file.c120
-rw-r--r--sha1_name.c11
-rw-r--r--shallow.c1
-rw-r--r--ssh-upload.c10
-rw-r--r--strbuf.c1
-rw-r--r--t/Makefile1
-rw-r--r--t/lib-read-tree-m-3way.sh2
-rwxr-xr-xt/t0000-basic.sh2
-rwxr-xr-xt/t1200-tutorial.sh1
-rwxr-xr-xt/t1300-repo-config.sh1
-rwxr-xr-xt/t2000-checkout-cache-clash.sh2
-rwxr-xr-xt/t2001-checkout-cache-clash.sh1
-rwxr-xr-xt/t3030-merge-recursive.sh1
-rwxr-xr-xt/t3200-branch.sh16
-rwxr-xr-xt/t3403-rebase-skip.sh1
-rwxr-xr-xt/t4006-diff-mode.sh1
-rwxr-xr-xt/t4100-apply-stat.sh1
-rwxr-xr-xt/t4110-apply-scan.sh1
-rwxr-xr-xt/t4112-apply-renames.sh16
-rwxr-xr-xt/t4118-apply-empty-context.sh1
-rwxr-xr-xt/t4119-apply-config.sh2
-rwxr-xr-xt/t4121-apply-diffs.sh1
-rwxr-xr-xt/t4122-apply-symlink-inside.sh1
-rwxr-xr-xt/t4200-rerere.sh2
-rwxr-xr-xt/t5000-tar-tree.sh7
-rwxr-xr-xt/t5400-send-pack.sh2
-rwxr-xr-xt/t5516-fetch-push.sh82
-rwxr-xr-xt/t5520-pull.sh1
-rwxr-xr-xt/t5701-clone-local.sh46
-rwxr-xr-xt/t5710-info-alternate.sh1
-rwxr-xr-xt/t6000lib.sh16
-rwxr-xr-xt/t6002-rev-list-bisect.sh8
-rwxr-xr-xt/t6021-merge-criss-cross.sh2
-rwxr-xr-xt/t6023-merge-file.sh6
-rwxr-xr-xt/t6024-recursive-merge.sh14
-rwxr-xr-xt/t6030-bisect-porcelain.sh1
-rwxr-xr-xt/t6101-rev-parse-parents.sh11
-rwxr-xr-xt/t7400-submodule-basic.sh143
-rwxr-xr-xt/t9107-git-svn-migrate.sh1
-rw-r--r--t/t9111/svnsync.dump2
-rwxr-xr-xt/t9400-git-cvsserver-server.sh237
-rwxr-xr-xt/t9500-gitweb-standalone-no-errors.sh518
-rw-r--r--t/test-lib.sh2
-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--tree-walk.c1
-rw-r--r--tree.c11
-rw-r--r--upload-pack.c4
-rw-r--r--var.c4
-rw-r--r--wt-status.c2
-rw-r--r--xdiff-interface.c8
-rw-r--r--xdiff-interface.h1
-rw-r--r--xdiff/xdiff.h1
-rw-r--r--xdiff/xdiffi.c1
-rw-r--r--xdiff/xdiffi.h1
-rw-r--r--xdiff/xemit.c5
-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
348 files changed, 4645 insertions, 3000 deletions
diff --git a/.gitignore b/.gitignore
index 4dc0c39..27e5aeb 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
@@ -126,6 +125,7 @@ git-ssh-push
git-ssh-upload
git-status
git-stripspace
+git-submodule
git-svn
git-svnimport
git-symbolic-ref
@@ -152,6 +152,7 @@ test-delta
test-dump-cache-tree
test-genrandom
test-match-trees
+test-sha1
common-cmds.h
*.tar.gz
*.dsc
diff --git a/.mailmap b/.mailmap
index 4e0615e..aa8ee6b 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>
@@ -19,8 +21,8 @@ Jon Loeliger <jdl@freescale.com>
Jon Seymour <jon@blackcubes.dyndns.org>
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>
Michele Ballabio <barra_cuda@katamail.com>
@@ -34,12 +36,11 @@ 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>
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/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..d111661
--- /dev/null
+++ b/Documentation/RelNotes-1.5.3.txt
@@ -0,0 +1,109 @@
+GIT v1.5.3 Release Notes (draft)
+========================
+
+Updates since v1.5.2
+--------------------
+
+* An initial interation of Porcelain level superproject support
+ started to take shape.
+
+* Thee are a handful pack-objects changes to help you cope better with
+ repositories with pathologically large blobs in them.
+
+* New commands and options.
+
+ - "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" can be told to split resulting packs to avoid
+ exceeding limit specified with "--max-pack-size".
+
+* Updated behavior of existing commands.
+
+ - "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-apply --whitespace=strip" removes blank lines added at
+ the end of the file.
+
+ - fetch over git native protocols with -v shows connection
+ status, and the IP address of the other end, to help
+ diagnosing problems.
+
+ - core.legacyheaders is no more, although we still can read
+ objects created in a new loose object format.
+
+ - "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.
+
+
+* Builds
+
+ -
+
+* Performance Tweaks
+
+ - git-pack-objects avoids re-deltification cost by caching
+ small enough delta results it creates while looking for the
+ best delta candidates.
+
+ - 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.
+
+Fixes since v1.5.2
+------------------
+
+All of the fixes in v1.5.2 maintenance series are included in
+this release, unless otherwise noted.
+
+* Bugfixes
+
+ - .... This has not
+ been backported to 1.5.2.x series, as it is rather an
+ intrusive change.
+
+
+--
+exec >/var/tmp/1
+O=v1.5.2-45-ged82edc
+O=v1.5.2-172-g1a8b769
+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 60e15ba..99302c5 100644
--- a/Documentation/asciidoc.conf
+++ b/Documentation/asciidoc.conf
@@ -54,5 +54,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..a181f75 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
@@ -180,6 +178,7 @@ git-ssh-fetch synchingrepositories
git-ssh-upload synchingrepositories
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 7d9afe2..de408b6 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -204,23 +204,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
@@ -397,6 +390,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
@@ -563,6 +561,22 @@ 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.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 +682,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-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..18d49d2 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>::
@@ -139,28 +139,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 +233,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..b2a0593 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -100,8 +100,8 @@
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
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/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..76d2b05 100644
--- a/Documentation/git-add.txt
+++ b/Documentation/git-add.txt
@@ -228,4 +228,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-branch.txt b/Documentation/git-branch.txt
index 8dc5171..8d72bb9 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -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..ea26da8 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -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 27b67b8..b62c970 100644
--- a/Documentation/git-cherry.txt
+++ b/Documentation/git-cherry.txt
@@ -64,4 +64,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-clone.txt b/Documentation/git-clone.txt
index ac938d3..4a5bab5 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -175,4 +175,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..9586b97 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
------------------
@@ -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-config.txt b/Documentation/git-config.txt
index 056b147..f2c6717 100644
--- a/Documentation/git-config.txt
+++ b/Documentation/git-config.txt
@@ -291,4 +291,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 fd7f540..827711c 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..3985e01 100644
--- a/Documentation/git-cvsimport.txt
+++ b/Documentation/git-cvsimport.txt
@@ -37,7 +37,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.
@@ -67,7 +67,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 +89,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 +156,3 @@ Documentation by Matthias Urlichs <smurf@smurf.noris.de>.
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-daemon.txt b/Documentation/git-daemon.txt
index 9ddab71..4b30b18 100644
--- a/Documentation/git-daemon.txt
+++ b/Documentation/git-daemon.txt
@@ -235,4 +235,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..639b969 100644
--- a/Documentation/git-diff.txt
+++ b/Documentation/git-diff.txt
@@ -138,4 +138,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 8d06775..5eacab0 100644
--- a/Documentation/git-fast-import.txt
+++ b/Documentation/git-fast-import.txt
@@ -908,4 +908,3 @@ Documentation by Shawn O. Pearce <spearce@spearce.org>.
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 a33d157..647de90 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
@@ -60,6 +63,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.
@@ -170,4 +178,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..234c22f 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] [<object>*]
DESCRIPTION
-----------
@@ -61,6 +61,9 @@ 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.
+
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 +145,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-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..ab0201a 100644
--- a/Documentation/git-init-db.txt
+++ b/Documentation/git-init-db.txt
@@ -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..413ed65 100644
--- a/Documentation/git-init.txt
+++ b/Documentation/git-init.txt
@@ -108,4 +108,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..19b5f88 100644
--- a/Documentation/git-local-fetch.txt
+++ b/Documentation/git-local-fetch.txt
@@ -62,4 +62,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..6157edb 100644
--- a/Documentation/git-log.txt
+++ b/Documentation/git-log.txt
@@ -101,4 +101,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..d285cba 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
@@ -95,7 +95,7 @@ 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
+3. the tree gets committed, and
4. the `HEAD` pointer gets advanced.
Because of 2., we require that the original state of the index
diff --git a/Documentation/git-mergetool.txt b/Documentation/git-mergetool.txt
index add01e8..b89c51c 100644
--- a/Documentation/git-mergetool.txt
+++ b/Documentation/git-mergetool.txt
@@ -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..0ac3be1 100644
--- a/Documentation/git-mktag.txt
+++ b/Documentation/git-mktag.txt
@@ -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-p4import.txt b/Documentation/git-p4import.txt
index 714abbe..9967587 100644
--- a/Documentation/git-p4import.txt
+++ b/Documentation/git-p4import.txt
@@ -165,4 +165,3 @@ Written by Sean Estabrooks <seanlkml@sympatico.ca>
GIT
---
Part of the gitlink:git[7] suite
-
diff --git a/Documentation/git-pack-objects.txt b/Documentation/git-pack-objects.txt
index bd3ee45..e3549b5 100644
--- a/Documentation/git-pack-objects.txt
+++ b/Documentation/git-pack-objects.txt
@@ -85,6 +85,11 @@ base-name::
times to get to the necessary object.
The default value for --window is 10 and --depth is 50.
+--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 +132,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 +185,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..84693f8 100644
--- a/Documentation/git-pull.txt
+++ b/Documentation/git-pull.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..366c5db 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -110,4 +110,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..84184d6 100644
--- a/Documentation/git-read-tree.txt
+++ b/Documentation/git-read-tree.txt
@@ -356,4 +356,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..0c00090 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -237,4 +237,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-reflog.txt b/Documentation/git-reflog.txt
index 1e343bc..f717e1e 100644
--- a/Documentation/git-reflog.txt
+++ b/Documentation/git-reflog.txt
@@ -65,4 +65,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 3dde713..ab232c2 100644
--- a/Documentation/git-remote.txt
+++ b/Documentation/git-remote.txt
@@ -128,4 +128,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 cc3b0b2..c33a512 100644
--- a/Documentation/git-repack.txt
+++ b/Documentation/git-repack.txt
@@ -65,6 +65,11 @@ OPTIONS
to be applied that many times to get to the necessary object.
The default value for --window is 10 and --depth is 50.
+--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
-------------
@@ -96,4 +101,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-rev-list.txt b/Documentation/git-rev-list.txt
index c3c2043..0dba73f 100644
--- a/Documentation/git-rev-list.txt
+++ b/Documentation/git-rev-list.txt
@@ -25,6 +25,7 @@ SYNOPSIS
[ \--cherry-pick ]
[ \--encoding[=<encoding>] ]
[ \--(author|committer|grep)=<pattern> ]
+ [ \--regexp-ignore-case ] [ \--extended-regexp ]
[ \--date={local|relative|default} ]
[ [\--objects | \--objects-edge] [ \--unpacked ] ]
[ \--pretty | \--header ]
@@ -214,6 +215,15 @@ limiting may be applied.
Limit the commits output to ones with log message that
matches the specified pattern (regular expression).
+--regexp-ignore-case::
+
+ Match the regexp limiting patterns without regard to letters case.
+
+--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.
diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index 7757abe..e1cb4ef 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -286,4 +286,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..78f45dc 100644
--- a/Documentation/git-rm.txt
+++ b/Documentation/git-rm.txt
@@ -95,4 +95,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..946bd76 100644
--- a/Documentation/git-send-email.txt
+++ b/Documentation/git-send-email.txt
@@ -78,7 +78,7 @@ 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.
@@ -137,4 +137,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..aaf3db0 100644
--- a/Documentation/git-ssh-fetch.txt
+++ b/Documentation/git-ssh-fetch.txt
@@ -48,4 +48,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..4796224 100644
--- a/Documentation/git-ssh-upload.txt
+++ b/Documentation/git-ssh-upload.txt
@@ -44,4 +44,3 @@ Documentation by Daniel Barkalow
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..cb0424f
--- /dev/null
+++ b/Documentation/git-submodule.txt
@@ -0,0 +1,65 @@
+git-submodule(1)
+================
+
+NAME
+----
+git-submodule - Initialize, update or inspect submodules
+
+
+SYNOPSIS
+--------
+'git-submodule' [--quiet] [--cached] [status|init|update] [--] [<path>...]
+
+
+COMMANDS
+--------
+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. clone the git repositories specified
+ in the .gitmodules file and checkout the submodule commits specified
+ in the index of the containing repository. This will make the
+ submodules HEAD be detached.
+
+update::
+ Update the initialized submodules, i.e. checkout the submodule commits
+ specified in the index of the containing repository. This will make
+ the submodules HEAD be detached.
+
+
+OPTIONS
+-------
+-q, --quiet::
+ Only print error messages.
+
+--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 cloning 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 "module.$path.url".
+
+
+AUTHOR
+------
+Written by Lars Hjemli <hjemli@gmail.com>
+
+GIT
+---
+Part of the gitlink:git[7] suite
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..ba077c3 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -428,4 +428,3 @@ contributors on the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite
-
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/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/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..c551ea6 100644
--- a/Documentation/pretty-formats.txt
+++ b/Documentation/pretty-formats.txt
@@ -121,4 +121,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..6338def 100644
--- a/Documentation/pretty-options.txt
+++ b/Documentation/pretty-options.txt
@@ -11,4 +11,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/user-manual.txt b/Documentation/user-manual.txt
index 7eaafa8..957cd00 100644
--- a/Documentation/user-manual.txt
+++ b/Documentation/user-manual.txt
@@ -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;
@@ -1056,7 +1056,7 @@ $ git show
-------------------------------------------------
As a special shortcut,
-
+
-------------------------------------------------
$ git commit -a
-------------------------------------------------
@@ -1554,7 +1554,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}
@@ -1630,7 +1630,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
@@ -1793,7 +1793,7 @@ like this:
you push
your personal repo ------------------> your public repo
- ^ |
+ ^ |
| |
| you pull | they pull
| |
@@ -2359,7 +2359,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]:
@@ -2735,7 +2735,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
@@ -2757,7 +2757,7 @@ independently of the contents or the type of the object: all objects can
be validated by verifying that (a) their hashes match the content of the
file and (b) the object successfully inflates to a stream of bytes that
forms a sequence of <ascii type without space> + <space> + <ascii decimal
-size> + <byte\0> + <binary object data>.
+size> + <byte\0> + <binary object data>.
The structured objects can further have their structure and
connectivity to other objects verified. This is generally done with
@@ -2954,7 +2954,7 @@ 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
@@ -2974,7 +2974,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
@@ -3437,7 +3437,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:
------------------------------------------------
@@ -3448,12 +3448,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 bd30398..289c806 100755
--- a/GIT-VERSION-GEN
+++ b/GIT-VERSION-GEN
@@ -1,7 +1,7 @@
#!/bin/sh
GVF=GIT-VERSION-FILE
-DEF_VER=v1.5.2.1.GIT
+DEF_VER=v1.5.2.GIT
LF='
'
@@ -43,5 +43,3 @@ test "$VN" = "$VC" || {
echo >&2 "GIT_VERSION = $VN"
echo "GIT_VERSION = $VN" >$GVF
}
-
-
diff --git a/INSTALL b/INSTALL
index 361c65b..95269cc 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
@@ -111,4 +111,3 @@ Issues of note:
would instead give you a copy of what you see at:
http://www.kernel.org/pub/software/scm/git/docs/
-
diff --git a/Makefile b/Makefile
index fb11fa1..0f75955 100644
--- a/Makefile
+++ b/Makefile
@@ -206,10 +206,10 @@ SCRIPT_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
SCRIPT_PERL = \
git-add--interactive.perl \
@@ -238,7 +238,6 @@ 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 \
@@ -296,7 +295,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 \
@@ -318,7 +318,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 \
@@ -941,7 +941,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
all:: $(TEST_PROGRAMS)
@@ -954,26 +954,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
@@ -1064,8 +1050,9 @@ dist-doc:
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)
+ $(LIB_FILE) $(XDIFF_LIB)
rm -f $(ALL_PROGRAMS) $(BUILT_INS) git$X
+ rm -f $(TEST_PROGRAMS)
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
diff --git a/RelNotes b/RelNotes
index 403fb97..0de5e66 120000
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes-1.5.2.1.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-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 0399743..c6f736c 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)
@@ -1657,7 +1657,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;
}
@@ -1671,6 +1671,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;
@@ -1678,6 +1679,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;
@@ -1699,6 +1701,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 */
@@ -1716,9 +1719,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 */
@@ -1728,6 +1736,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;
}
@@ -1770,9 +1782,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.
@@ -2865,18 +2884,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-branch.c b/builtin-branch.c
index 8956d0f..da48051 100644
--- a/builtin-branch.c
+++ b/builtin-branch.c
@@ -55,7 +55,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);
@@ -72,7 +72,7 @@ int git_branch_config(const char *var, const char *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];
@@ -317,8 +317,6 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev)
static char *config_repo;
static char *config_remote;
static const char *start_ref;
-static int start_len;
-static int base_len;
static int get_remote_branch_name(const char *value)
{
@@ -334,26 +332,41 @@ static int get_remote_branch_name(const char *value)
end = value + strlen(value);
- /* Try an exact match first. */
+ /*
+ * 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. */
+ /* Truncate the value before the colon. */
nfasprintf(&config_repo, "%.*s", colon - value, value);
return 1;
}
- /* Try with a wildcard match now. */
- if (end - value > 2 && end[-2] == '/' && end[-1] == '*' &&
- colon - value > 2 && colon[-2] == '/' && colon[-1] == '*' &&
- (end - 2) - (colon + 1) == base_len &&
- !strncmp(colon + 1, start_ref, base_len)) {
- /* Replace the star with the remote branch name. */
- nfasprintf(&config_repo, "%.*s%s",
- (colon - 2) - value, value,
- start_ref + base_len);
- return 1;
- }
+ /*
+ * Is this a wildcard match?
+ */
+ if ((end - 2 <= value) || end[-2] != '/' || end[-1] != '*' ||
+ (colon - 2 <= value) || colon[-2] != '/' || colon[-1] != '*')
+ return 0;
- 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)
@@ -363,10 +376,12 @@ static int get_remote_config(const char *key, const char *value)
return 0;
var = strrchr(key, '.');
- if (var == key + 6)
+ if (var == key + 6 || strcmp(var, ".fetch"))
return 0;
-
- if (!strcmp(var, ".fetch") && get_remote_branch_name(value))
+ /*
+ * 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;
@@ -392,14 +407,14 @@ static void set_branch_merge(const char *name, const char *config_remote,
static void set_branch_defaults(const char *name, const char *real_ref)
{
- const char *slash = strrchr(real_ref, '/');
-
- if (!slash)
- return;
-
+ /*
+ * 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;
- start_len = strlen(real_ref);
- base_len = slash - real_ref;
git_config(get_remote_config);
if (!config_repo && !config_remote &&
!prefixcmp(real_ref, "refs/heads/")) {
@@ -462,7 +477,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));
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-fetch--tool.c b/builtin-fetch--tool.c
index 12adb38..ed4d5de 100644
--- a/builtin-fetch--tool.c
+++ b/builtin-fetch--tool.c
@@ -42,7 +42,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-fsck.c b/builtin-fsck.c
index 44ce629..944a496 100644
--- a/builtin-fsck.c
+++ b/builtin-fsck.c
@@ -20,6 +20,7 @@ static int check_strict;
static int keep_cache_objects;
static unsigned char head_sha1[20];
static int errors_found;
+static int verbose;
#define ERROR_OBJECT 01
#define ERROR_REACHABLE 02
@@ -149,6 +150,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 +165,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 +236,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 +267,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 +328,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 +351,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 +360,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 +465,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 +502,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 +575,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 +594,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 +619,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,7 +641,7 @@ 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)
{
@@ -645,6 +681,10 @@ int cmd_fsck(int argc, char **argv, const char *prefix)
check_strict = 1;
continue;
}
+ if (!strcmp(arg, "--verbose")) {
+ verbose = 1;
+ continue;
+ }
if (*arg == '-')
usage(fsck_usage);
}
@@ -668,7 +708,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 +719,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 +758,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..45025fb 100644
--- a/builtin-gc.c
+++ b/builtin-gc.c
@@ -15,13 +15,15 @@
#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 +36,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 +73,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-log.c b/builtin-log.c
index 3744712..0aede76 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -60,13 +60,7 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
rev->always_show_header = 0;
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;
@@ -298,7 +292,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 +310,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 +434,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;
@@ -465,6 +469,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 +546,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)
@@ -614,7 +622,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);
diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index f7c066b..5398a41 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))
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..489c2c5 100644
--- a/builtin-mailinfo.c
+++ b/builtin-mailinfo.c
@@ -851,8 +851,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-file.c b/builtin-merge-file.c
index 9135773..10ec63b 100644
--- a/builtin-merge-file.c
+++ b/builtin-merge-file.c
@@ -36,9 +36,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);
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..3d396ca 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"
@@ -15,17 +16,16 @@
#include "progress.h"
static const char pack_usage[] = "\
-git-pack-objects [{ -q | --progress | --all-progress }] \n\
+git-pack-objects [{ -q | --progress | --all-progress }] [--max-pack-size=N] \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]";
+ [--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 */
@@ -35,14 +35,16 @@ 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) */
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 +54,30 @@ 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;
/*
* The object names in objects array are hashed with this hashtable,
@@ -234,15 +244,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 +356,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 +404,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 +454,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 +499,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 +557,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 +587,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 +704,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 +736,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 +749,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 +765,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 +830,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 +851,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 +986,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 +1048,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 +1060,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 +1115,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 +1150,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 +1203,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 +1216,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;
@@ -1282,6 +1272,23 @@ struct unpacked {
struct delta_index *index;
};
+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.
@@ -1338,31 +1345,45 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
/* 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);
}
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);
}
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;
+ }
}
delta_buf = create_delta(src->index, trg->data, trg_size, &delta_size, max_size);
if (!delta_buf)
return 0;
+ if (trg_entry->delta_data) {
+ delta_cache_size -= trg_entry->delta_size;
+ free(trg_entry->delta_data);
+ }
+ trg_entry->delta_data = 0;
trg_entry->delta = src_entry;
trg_entry->delta_size = delta_size;
trg_entry->depth = src_entry->depth + 1;
- free(delta_buf);
+
+ 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;
}
@@ -1412,6 +1433,10 @@ static void find_deltas(struct object_entry **list, int window, int depth)
if (entry->size < 50)
continue;
+
+ if (entry->no_try_delta)
+ continue;
+
free_delta_index(n->index);
n->index = NULL;
free(n->data);
@@ -1494,6 +1519,24 @@ static int git_pack_config(const char *k, const char *v)
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 +1544,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 +1566,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 +1632,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 +1643,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 +1665,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);
@@ -1655,6 +1714,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 +1751,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 +1782,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 +1810,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..1952950 100644
--- a/builtin-pack-refs.c
+++ b/builtin-pack-refs.c
@@ -12,9 +12,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 +41,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 +55,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 +87,51 @@ 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 (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 +140,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-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..f6409b9 100644
--- a/builtin-rerere.c
+++ b/builtin-rerere.c
@@ -434,4 +434,3 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
path_list_clear(&merge_rr, 1);
return 0;
}
-
diff --git a/builtin-revert.c b/builtin-revert.c
index ea2f15b..8f02ed7 100644
--- a/builtin-revert.c
+++ b/builtin-revert.c
@@ -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;
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-stripspace.c b/builtin-stripspace.c
index f0d4d9e..62bd4b5 100644
--- a/builtin-stripspace.c
+++ b/builtin-stripspace.c
@@ -26,7 +26,7 @@ static int cleanup(char *line)
return 1;
}
-void stripspace(FILE *in, FILE *out)
+static void stripspace(FILE *in, FILE *out)
{
int empties = -1;
int incomplete = 0;
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..feac2ed 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++) {
@@ -30,6 +31,10 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
delete = 1;
continue;
}
+ if (!strcmp("--no-deref", argv[i])) {
+ ref_flags |= REF_NODEREF;
+ continue;
+ }
if (!refname) {
refname = argv[i];
continue;
@@ -59,7 +64,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.h b/builtin.h
index d3f3a74..da4834c 100644
--- a/builtin.h
+++ b/builtin.h
@@ -7,9 +7,6 @@ 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 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..350a79b 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)
diff --git a/cache.h b/cache.h
index 5dff2f1..5e7381e 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)
@@ -273,7 +273,6 @@ 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 has_symlinks;
extern int assume_unchanged;
@@ -283,6 +282,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;
@@ -354,7 +355,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);
@@ -463,11 +463,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 +479,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);
diff --git a/commit.c b/commit.c
index 5632e32..4ca4d44 100644
--- a/commit.c
+++ b/commit.c
@@ -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;
@@ -1116,15 +1116,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 +1151,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 +1179,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 +1211,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..a313b53 100644
--- a/commit.h
+++ b/commit.h
@@ -66,15 +66,13 @@ extern unsigned long pretty_print_commit(enum cmit_fmt fmt, const struct commit
/** 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..58d3ed5 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;
@@ -299,8 +301,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 +318,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;
}
@@ -610,7 +621,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;
@@ -978,4 +989,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/connect.c b/connect.c
index da89c9c..7fab9c0 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;
@@ -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;
-}
-
enum protocol {
PROTO_LOCAL = 1,
PROTO_SSH,
@@ -391,16 +153,34 @@ static enum protocol get_protocol(const char *name)
#ifndef NO_IPV6
+static const char *ai_name(const struct addrinfo *ai)
+{
+ static char addr[INET_ADDRSTRLEN];
+ if ( AF_INET == ai->ai_family ) {
+ struct sockaddr_in *in;
+ in = (struct sockaddr_in *)ai->ai_addr;
+ inet_ntop(ai->ai_family, &in->sin_addr, addr, sizeof(addr));
+ } else if ( AF_INET6 == ai->ai_family ) {
+ struct sockaddr_in6 *in;
+ in = (struct sockaddr_in6 *)ai->ai_addr;
+ inet_ntop(ai->ai_family, &in->sin6_addr, addr, sizeof(addr));
+ } else {
+ strcpy(addr, "(unknown)");
+ }
+ return addr;
+}
+
/*
* Returns a connected socket() fd, or else die()s.
*/
-static int git_tcp_connect_sock(char *host)
+static int git_tcp_connect_sock(char *host, int flags)
{
int sockfd = -1, saved_errno = 0;
char *colon, *end;
const char *port = STR(DEFAULT_GIT_PORT);
struct addrinfo hints, *ai0, *ai;
int gai;
+ int cnt = 0;
if (host[0] == '[') {
end = strchr(host + 1, ']');
@@ -425,10 +205,16 @@ static int git_tcp_connect_sock(char *host)
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
+ if (flags & CONNECT_VERBOSE)
+ fprintf(stderr, "Looking up %s ... ", host);
+
gai = getaddrinfo(host, port, &hints, &ai);
if (gai)
die("Unable to look up %s (port %s) (%s)", host, port, gai_strerror(gai));
+ if (flags & CONNECT_VERBOSE)
+ fprintf(stderr, "done.\nConnecting to %s (port %s) ... ", host, port);
+
for (ai0 = ai; ai; ai = ai->ai_next) {
sockfd = socket(ai->ai_family,
ai->ai_socktype, ai->ai_protocol);
@@ -438,10 +224,18 @@ static int git_tcp_connect_sock(char *host)
}
if (connect(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {
saved_errno = errno;
+ fprintf(stderr, "%s[%d: %s]: net=%s, errno=%s\n",
+ host,
+ cnt,
+ ai_name(ai),
+ hstrerror(h_errno),
+ strerror(saved_errno));
close(sockfd);
sockfd = -1;
continue;
}
+ if (flags & CONNECT_VERBOSE)
+ fprintf(stderr, "%s ", ai_name(ai));
break;
}
@@ -450,6 +244,9 @@ static int git_tcp_connect_sock(char *host)
if (sockfd < 0)
die("unable to connect a socket (%s)", strerror(saved_errno));
+ if (flags & CONNECT_VERBOSE)
+ fprintf(stderr, "done.\n");
+
return sockfd;
}
@@ -458,7 +255,7 @@ static int git_tcp_connect_sock(char *host)
/*
* Returns a connected socket() fd, or else die()s.
*/
-static int git_tcp_connect_sock(char *host)
+static int git_tcp_connect_sock(char *host, int flags)
{
int sockfd = -1, saved_errno = 0;
char *colon, *end;
@@ -467,6 +264,7 @@ static int git_tcp_connect_sock(char *host)
struct sockaddr_in sa;
char **ap;
unsigned int nport;
+ int cnt;
if (host[0] == '[') {
end = strchr(host + 1, ']');
@@ -485,6 +283,9 @@ static int git_tcp_connect_sock(char *host)
port = colon + 1;
}
+ if (flags & CONNECT_VERBOSE)
+ fprintf(stderr, "Looking up %s ... ", host);
+
he = gethostbyname(host);
if (!he)
die("Unable to look up %s (%s)", host, hstrerror(h_errno));
@@ -497,7 +298,10 @@ static int git_tcp_connect_sock(char *host)
nport = se->s_port;
}
- for (ap = he->h_addr_list; *ap; ap++) {
+ if (flags & CONNECT_VERBOSE)
+ fprintf(stderr, "done.\nConnecting to %s (port %s) ... ", host, port);
+
+ for (cnt = 0, ap = he->h_addr_list; *ap; ap++, cnt++) {
sockfd = socket(he->h_addrtype, SOCK_STREAM, 0);
if (sockfd < 0) {
saved_errno = errno;
@@ -511,25 +315,37 @@ static int git_tcp_connect_sock(char *host)
if (connect(sockfd, (struct sockaddr *)&sa, sizeof sa) < 0) {
saved_errno = errno;
+ fprintf(stderr, "%s[%d: %s]: net=%s, errno=%s\n",
+ host,
+ cnt,
+ inet_ntoa(*(struct in_addr *)&sa.sin_addr),
+ hstrerror(h_errno),
+ strerror(saved_errno));
close(sockfd);
sockfd = -1;
continue;
}
+ if (flags & CONNECT_VERBOSE)
+ fprintf(stderr, "%s ",
+ inet_ntoa(*(struct in_addr *)&sa.sin_addr));
break;
}
if (sockfd < 0)
die("unable to connect a socket (%s)", strerror(saved_errno));
+ if (flags & CONNECT_VERBOSE)
+ fprintf(stderr, "done.\n");
+
return sockfd;
}
#endif /* NO_IPV6 */
-static void git_tcp_connect(int fd[2], char *host)
+static void git_tcp_connect(int fd[2], char *host, int flags)
{
- int sockfd = git_tcp_connect_sock(host);
+ int sockfd = git_tcp_connect_sock(host, flags);
fd[0] = sockfd;
fd[1] = dup(sockfd);
@@ -574,7 +390,7 @@ static int git_proxy_command_options(const char *var, const char *value)
}
if (0 <= matchlen) {
/* core.gitproxy = none for kernel.org */
- if (matchlen == 4 &&
+ if (matchlen == 4 &&
!memcmp(value, "none", 4))
matchlen = 0;
git_proxy_command = xmalloc(matchlen + 1);
@@ -646,7 +462,7 @@ static void git_proxy_connect(int fd[2], char *host)
*
* Does not return a negative value on error; it just dies.
*/
-pid_t git_connect(int fd[2], char *url, const char *prog)
+pid_t git_connect(int fd[2], char *url, const char *prog, int flags)
{
char *host, *path = url;
char *end;
@@ -719,7 +535,7 @@ pid_t git_connect(int fd[2], char *url, const char *prog)
if (git_use_proxy(host))
git_proxy_connect(fd, host);
else
- git_tcp_connect(fd, host);
+ git_tcp_connect(fd, host, flags);
/*
* Separate original protocol components prog and path
* from extended components with a NUL byte.
diff --git a/contrib/README b/contrib/README
index e1c0a01..05f291c 100644
--- a/contrib/README
+++ b/contrib/README
@@ -41,4 +41,3 @@ submit a patch to create a subdirectory of contrib/ and put your
stuff there.
-jc
-
diff --git a/contrib/blameview/README b/contrib/blameview/README
index 50a6f67..fada5ce 100644
--- a/contrib/blameview/README
+++ b/contrib/blameview/README
@@ -7,4 +7,3 @@ To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: git@vger.kernel.org
Date: Sat, 27 Jan 2007 18:52:38 -0500
Message-ID: <20070127235238.GA28706@coredump.intra.peff.net>
-
diff --git a/contrib/gitview/gitview b/contrib/gitview/gitview
index 2d80e2b..098cb01 100755
--- a/contrib/gitview/gitview
+++ b/contrib/gitview/gitview
@@ -259,10 +259,13 @@ class CellRendererGraph(gtk.GenericCellRenderer):
self.set_colour(ctx, colour, 0.0, 0.5)
ctx.show_text(name)
-class Commit:
+class Commit(object):
""" This represent a commit object obtained after parsing the git-rev-list
output """
+ __slots__ = ['children_sha1', 'message', 'author', 'date', 'committer',
+ 'commit_date', 'commit_sha1', 'parent_sha1']
+
children_sha1 = {}
def __init__(self, commit_lines):
@@ -339,7 +342,7 @@ class Commit:
fp.close()
return diff
-class AnnotateWindow:
+class AnnotateWindow(object):
"""Annotate window.
This object represents and manages a single window containing the
annotate information of the file
@@ -519,7 +522,7 @@ class AnnotateWindow:
self.io_watch_tag = gobject.io_add_watch(fp, gobject.IO_IN, self.data_ready)
-class DiffWindow:
+class DiffWindow(object):
"""Diff window.
This object represents and manages a single window containing the
differences between two revisions on a branch.
@@ -674,7 +677,7 @@ class DiffWindow:
fp.close()
dialog.destroy()
-class GitView:
+class GitView(object):
""" This is the main class
"""
version = "0.9"
@@ -1277,5 +1280,3 @@ if __name__ == "__main__":
view = GitView( without_diff != 1)
view.run(sys.argv[without_diff:])
-
-
diff --git a/contrib/hooks/post-receive-email b/contrib/hooks/post-receive-email
index d1bef91..c589a39 100644
--- a/contrib/hooks/post-receive-email
+++ b/contrib/hooks/post-receive-email
@@ -199,7 +199,7 @@ generate_email_footer()
hooks/post-receive
- --
+ --
$projectdesc
EOF
}
diff --git a/contrib/remotes2config.sh b/contrib/remotes2config.sh
index dc09eae..0c8b954 100644
--- a/contrib/remotes2config.sh
+++ b/contrib/remotes2config.sh
@@ -31,5 +31,3 @@ if [ -d "$GIT_DIR"/remotes ]; then
esac
done
fi
-
-
diff --git a/contrib/workdir/git-new-workdir b/contrib/workdir/git-new-workdir
index 9877b98..f2a3615 100755
--- a/contrib/workdir/git-new-workdir
+++ b/contrib/workdir/git-new-workdir
@@ -20,17 +20,19 @@ new_workdir=$2
branch=$3
# want to make sure that what is pointed to has a .git directory ...
-test -d "$orig_git/.git" || die "\"$orig_git\" is not a git repository!"
+git_dir=$(cd "$orig_git" 2>/dev/null &&
+ git rev-parse --git-dir 2>/dev/null) ||
+ die "\"$orig_git\" is not a git repository!"
# don't link to a workdir
-if test -L "$orig_git/.git/config"
+if test -L "$git_dir/config"
then
die "\"$orig_git\" is a working directory only, please specify" \
"a complete repository."
fi
# make sure the the links use full paths
-orig_git=$(cd "$orig_git"; pwd)
+git_dir=$(cd "$git_dir"; pwd)
# create the workdir
mkdir -p "$new_workdir/.git" || die "unable to create \"$new_workdir\"!"
@@ -45,13 +47,13 @@ do
mkdir -p "$(dirname "$new_workdir/.git/$x")"
;;
esac
- ln -s "$orig_git/.git/$x" "$new_workdir/.git/$x"
+ ln -s "$git_dir/$x" "$new_workdir/.git/$x"
done
# now setup the workdir
cd "$new_workdir"
# copy the HEAD from the original repository as a default branch
-cp "$orig_git/.git/HEAD" .git/HEAD
+cp "$git_dir/HEAD" .git/HEAD
# checkout the branch (either the same as HEAD from the original repository, or
# the one that was asked for)
git checkout -f $branch
diff --git a/convert-objects.c b/convert-objects.c
index cefbceb..90e7900 100644
--- a/convert-objects.c
+++ b/convert-objects.c
@@ -194,7 +194,7 @@ static unsigned long parse_oldstyle_date(const char *buf)
fmt++;
} while (*buf && *fmt);
printf("left: %s\n", buf);
- return mktime(&tm);
+ return mktime(&tm);
}
static int convert_date_line(char *dst, void **buf, unsigned long *sp)
diff --git a/copy.c b/copy.c
index d340bb2..c225d1b 100644
--- a/copy.c
+++ b/copy.c
@@ -34,4 +34,3 @@ int copy_fd(int ifd, int ofd)
close(ifd);
return 0;
}
-
diff --git a/csum-file.c b/csum-file.c
index 7c806ad..5109342 100644
--- a/csum-file.c
+++ b/csum-file.c
@@ -29,18 +29,20 @@ static void sha1flush(struct sha1file *f, unsigned int count)
}
}
-int sha1close(struct sha1file *f, unsigned char *result, int update)
+int sha1close(struct sha1file *f, unsigned char *result, int final)
{
unsigned offset = f->offset;
if (offset) {
SHA1_Update(&f->ctx, f->buffer, offset);
sha1flush(f, offset);
+ f->offset = 0;
}
+ if (!final)
+ return 0; /* only want to flush (no checksum write, no close) */
SHA1_Final(f->buffer, &f->ctx);
if (result)
hashcpy(result, f->buffer);
- if (update)
- sha1flush(f, 20);
+ sha1flush(f, 20);
if (close(f->fd))
die("%s: sha1 file error on close (%s)", f->name, strerror(errno));
free(f);
@@ -119,14 +121,14 @@ struct sha1file *sha1fd(int fd, const char *name)
return f;
}
-int sha1write_compressed(struct sha1file *f, void *in, unsigned int size)
+int sha1write_compressed(struct sha1file *f, void *in, unsigned int size, int level)
{
z_stream stream;
unsigned long maxsize;
void *out;
memset(&stream, 0, sizeof(stream));
- deflateInit(&stream, zlib_compression_level);
+ deflateInit(&stream, level);
maxsize = deflateBound(&stream, size);
out = xmalloc(maxsize);
diff --git a/csum-file.h b/csum-file.h
index 7e13391..4e8b83e 100644
--- a/csum-file.h
+++ b/csum-file.h
@@ -16,7 +16,7 @@ extern struct sha1file *sha1fd(int fd, const char *name);
extern struct sha1file *sha1create(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
extern int sha1close(struct sha1file *, unsigned char *, int);
extern int sha1write(struct sha1file *, void *, unsigned int);
-extern int sha1write_compressed(struct sha1file *, void *, unsigned int);
+extern int sha1write_compressed(struct sha1file *, void *, unsigned int, int);
extern void crc32_begin(struct sha1file *);
extern uint32_t crc32_end(struct sha1file *);
diff --git a/ctype.c b/ctype.c
index 56bdffa..ee06eb7 100644
--- a/ctype.c
+++ b/ctype.c
@@ -20,4 +20,3 @@ unsigned char sane_ctype[256] = {
AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, 0, 0, 0, 0, 0, /* 112-15 */
/* Nothing in the 128.. range */
};
-
diff --git a/daemon.c b/daemon.c
index 674e30d..a3f2ac1 100644
--- a/daemon.c
+++ b/daemon.c
@@ -133,7 +133,7 @@ static int avoid_alias(char *p)
{
int sl, ndot;
- /*
+ /*
* This resurrects the belts and suspenders paranoia check by HPA
* done in <435560F7.4080006@zytor.com> thread, now enter_repo()
* does not do getcwd() based path canonicalizations.
@@ -247,7 +247,7 @@ static char *path_ok(struct interp *itable)
int pathlen = strlen(path);
/* The validation is done on the paths after enter_repo
- * appends optional {.git,.git/.git} and friends, but
+ * appends optional {.git,.git/.git} and friends, but
* it does not use getcwd(). So if your /pub is
* a symlink to /mnt/pub, you can whitelist /pub and
* do not have to say /mnt/pub.
@@ -439,7 +439,7 @@ static void parse_extra_args(struct interp *table, char *extra_args, int buflen)
}
}
-void fill_in_extra_table_entries(struct interp *itable)
+static void fill_in_extra_table_entries(struct interp *itable)
{
char *hp;
diff --git a/date.c b/date.c
index 4690371..316841e 100644
--- a/date.c
+++ b/date.c
@@ -403,7 +403,7 @@ static int match_multi_number(unsigned long num, char c, const char *date, char
}
/*
- * We've seen a digit. Time? Year? Date?
+ * We've seen a digit. Time? Year? Date?
*/
static int match_digit(const char *date, struct tm *tm, int *offset, int *tm_gmt)
{
@@ -495,7 +495,7 @@ static int match_digit(const char *date, struct tm *tm, int *offset, int *tm_gmt
} else if (num > 0 && num < 13) {
tm->tm_mon = num-1;
}
-
+
return n;
}
@@ -569,13 +569,13 @@ int parse_date(const char *date, char *result, int maxlen)
if (!match) {
/* BAD CRAP */
match = 1;
- }
+ }
date += match;
}
/* mktime uses local timezone */
- then = my_mktime(&tm);
+ then = my_mktime(&tm);
if (offset == -1)
offset = (then - mktime(&tm)) / 60;
@@ -691,7 +691,7 @@ static const struct typelen {
{ "days", 24*60*60 },
{ "weeks", 7*24*60*60 },
{ NULL }
-};
+};
static const char *approxidate_alpha(const char *date, struct tm *tm, int *num)
{
diff --git a/diff-delta.c b/diff-delta.c
index 9f998d0..faf96e4 100644
--- a/diff-delta.c
+++ b/diff-delta.c
@@ -1,21 +1,14 @@
/*
* diff-delta.c: generate a delta between two buffers
*
- * Many parts of this file have been lifted from LibXDiff version 0.10.
- * http://www.xmailserver.org/xdiff-lib.html
+ * This code was greatly inspired by parts of LibXDiff from Davide Libenzi
+ * http://www.xmailserver.org/xdiff-lib.html
*
- * LibXDiff was written by Davide Libenzi <davidel@xmailserver.org>
- * Copyright (C) 2003 Davide Libenzi
+ * Rewritten for GIT by Nicolas Pitre <nico@cam.org>, (C) 2005-2007
*
- * Many mods for GIT usage by Nicolas Pitre <nico@cam.org>, (C) 2005.
- *
- * This file is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Use of this within git automatically means that the LGPL
- * licensing gets turned into GPLv2 within this project.
+ * This code is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
#include "git-compat-util.h"
@@ -246,7 +239,7 @@ create_delta(const struct delta_index *index,
const void *trg_buf, unsigned long trg_size,
unsigned long *delta_size, unsigned long max_size)
{
- unsigned int i, outpos, outsize, val;
+ unsigned int i, outpos, outsize, moff, msize, val;
int inscnt;
const unsigned char *ref_data, *ref_top, *data, *top;
unsigned char *out;
@@ -291,30 +284,33 @@ create_delta(const struct delta_index *index,
}
inscnt = i;
+ moff = 0;
+ msize = 0;
while (data < top) {
- unsigned int moff = 0, msize = 0;
- struct index_entry *entry;
- val ^= U[data[-RABIN_WINDOW]];
- val = ((val << 8) | *data) ^ T[val >> RABIN_SHIFT];
- i = val & index->hash_mask;
- for (entry = index->hash[i]; entry; entry = entry->next) {
- const unsigned char *ref = entry->ptr;
- const unsigned char *src = data;
- unsigned int ref_size = ref_top - ref;
- if (entry->val != val)
- continue;
- if (ref_size > top - src)
- ref_size = top - src;
- if (ref_size > 0x10000)
- ref_size = 0x10000;
- if (ref_size <= msize)
- break;
- while (ref_size-- && *src++ == *ref)
- ref++;
- if (msize < ref - entry->ptr) {
- /* this is our best match so far */
- msize = ref - entry->ptr;
- moff = entry->ptr - ref_data;
+ if (msize < 4096) {
+ struct index_entry *entry;
+ val ^= U[data[-RABIN_WINDOW]];
+ val = ((val << 8) | *data) ^ T[val >> RABIN_SHIFT];
+ i = val & index->hash_mask;
+ for (entry = index->hash[i]; entry; entry = entry->next) {
+ const unsigned char *ref = entry->ptr;
+ const unsigned char *src = data;
+ unsigned int ref_size = ref_top - ref;
+ if (entry->val != val)
+ continue;
+ if (ref_size > top - src)
+ ref_size = top - src;
+ if (ref_size <= msize)
+ break;
+ while (ref_size-- && *src++ == *ref)
+ ref++;
+ if (msize < ref - entry->ptr) {
+ /* this is our best match so far */
+ msize = ref - entry->ptr;
+ moff = entry->ptr - ref_data;
+ if (msize >= 4096) /* good enough */
+ break;
+ }
}
}
@@ -327,27 +323,13 @@ create_delta(const struct delta_index *index,
out[outpos - inscnt - 1] = inscnt;
inscnt = 0;
}
+ msize = 0;
} else {
+ unsigned int left;
unsigned char *op;
- if (msize >= RABIN_WINDOW) {
- const unsigned char *sk;
- sk = data + msize - RABIN_WINDOW;
- val = 0;
- for (i = 0; i < RABIN_WINDOW; i++)
- val = ((val << 8) | *sk++) ^ T[val >> RABIN_SHIFT];
- } else {
- const unsigned char *sk = data + 1;
- for (i = 1; i < msize; i++) {
- val ^= U[sk[-RABIN_WINDOW]];
- val = ((val << 8) | *sk++) ^ T[val >> RABIN_SHIFT];
- }
- }
-
if (inscnt) {
while (moff && ref_data[moff-1] == data[-1]) {
- if (msize == 0x10000)
- break;
/* we can match one byte back */
msize++;
moff--;
@@ -363,23 +345,40 @@ create_delta(const struct delta_index *index,
inscnt = 0;
}
- data += msize;
+ /* A copy op is currently limited to 64KB (pack v2) */
+ left = (msize < 0x10000) ? 0 : (msize - 0x10000);
+ msize -= left;
+
op = out + outpos++;
i = 0x80;
- if (moff & 0xff) { out[outpos++] = moff; i |= 0x01; }
- moff >>= 8;
- if (moff & 0xff) { out[outpos++] = moff; i |= 0x02; }
- moff >>= 8;
- if (moff & 0xff) { out[outpos++] = moff; i |= 0x04; }
- moff >>= 8;
- if (moff & 0xff) { out[outpos++] = moff; i |= 0x08; }
+ if (moff & 0x000000ff)
+ out[outpos++] = moff >> 0, i |= 0x01;
+ if (moff & 0x0000ff00)
+ out[outpos++] = moff >> 8, i |= 0x02;
+ if (moff & 0x00ff0000)
+ out[outpos++] = moff >> 16, i |= 0x04;
+ if (moff & 0xff000000)
+ out[outpos++] = moff >> 24, i |= 0x08;
- if (msize & 0xff) { out[outpos++] = msize; i |= 0x10; }
- msize >>= 8;
- if (msize & 0xff) { out[outpos++] = msize; i |= 0x20; }
+ if (msize & 0x00ff)
+ out[outpos++] = msize >> 0, i |= 0x10;
+ if (msize & 0xff00)
+ out[outpos++] = msize >> 8, i |= 0x20;
*op = i;
+
+ data += msize;
+ moff += msize;
+ msize = left;
+
+ if (msize < 4096) {
+ int j;
+ val = 0;
+ for (j = -RABIN_WINDOW; j < 0; j++)
+ val = ((val << 8) | data[j])
+ ^ T[val >> RABIN_SHIFT];
+ }
}
if (outpos >= outsize - MAX_OP_SIZE) {
@@ -389,7 +388,7 @@ create_delta(const struct delta_index *index,
outsize = max_size + MAX_OP_SIZE + 1;
if (max_size && outpos > max_size)
break;
- out = xrealloc(out, outsize);
+ out = realloc(out, outsize);
if (!out) {
free(tmp);
return NULL;
diff --git a/diff-lib.c b/diff-lib.c
index 07f4e81..7fb19c7 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -664,7 +664,7 @@ int run_diff_index(struct rev_info *revs, int cached)
const char *tree_name;
int match_missing = 0;
- /*
+ /*
* Backward compatibility wart - "diff-index -m" does
* not mean "do not ignore merges", but totally different.
*/
diff --git a/diff.c b/diff.c
index af282dd..1d234d3 100644
--- a/diff.c
+++ b/diff.c
@@ -1107,10 +1107,8 @@ static void setup_diff_attr_check(struct git_attr_check *check)
check->attr = attr_diff;
}
-#define FIRST_FEW_BYTES 8000
static int file_is_binary(struct diff_filespec *one)
{
- unsigned long sz;
struct git_attr_check attr_diff_check;
setup_diff_attr_check(&attr_diff_check);
@@ -1127,10 +1125,7 @@ static int file_is_binary(struct diff_filespec *one)
return 0;
diff_populate_filespec(one, 0);
}
- sz = one->size;
- if (FIRST_FEW_BYTES < sz)
- sz = FIRST_FEW_BYTES;
- return !!memchr(one->data, 0, sz);
+ return buffer_is_binary(one->data, one->size);
}
static void builtin_diff(const char *name_a,
@@ -1465,7 +1460,7 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only)
if (size_only && 0 < s->size)
return 0;
- if (S_ISDIRLNK(s->mode))
+ if (S_ISGITLINK(s->mode))
return diff_populate_gitlink(s, size_only);
if (!s->sha1_valid ||
@@ -2108,6 +2103,8 @@ static int opt_arg(const char *arg, int arg_short, const char *arg_long, int *va
return 1;
}
+static int diff_scoreopt_parse(const char *opt);
+
int diff_opt_parse(struct diff_options *options, const char **av, int ac)
{
const char *arg = av[0];
@@ -2279,7 +2276,7 @@ static int parse_num(const char **cp_p)
return (int)((num >= scale) ? MAX_SCORE : (MAX_SCORE * num / scale));
}
-int diff_scoreopt_parse(const char *opt)
+static int diff_scoreopt_parse(const char *opt)
{
int opt1, opt2, cmd;
@@ -3036,7 +3033,7 @@ void diff_addremove(struct diff_options *options,
* entries to the diff-core. They will be prefixed
* with something like '=' or '*' (I haven't decided
* which but should not make any difference).
- * Feeding the same new and old to diff_change()
+ * Feeding the same new and old to diff_change()
* also has the same effect.
* Before the final output happens, they are pruned after
* merged into rename/copy pairs as appropriate.
@@ -3063,7 +3060,7 @@ void diff_change(struct diff_options *options,
unsigned old_mode, unsigned new_mode,
const unsigned char *old_sha1,
const unsigned char *new_sha1,
- const char *base, const char *path)
+ const char *base, const char *path)
{
char concatpath[PATH_MAX];
struct diff_filespec *one, *two;
diff --git a/diff.h b/diff.h
index 63738c1..a7ee6d8 100644
--- a/diff.h
+++ b/diff.h
@@ -155,8 +155,6 @@ extern void diff_unmerge(struct diff_options *,
unsigned mode,
const unsigned char *sha1);
-extern int diff_scoreopt_parse(const char *opt);
-
#define DIFF_SETUP_REVERSE 1
#define DIFF_SETUP_USE_CACHE 2
#define DIFF_SETUP_USE_SIZE_CACHE 4
diff --git a/diffcore-pickaxe.c b/diffcore-pickaxe.c
index c4a77d7..af9fffe 100644
--- a/diffcore-pickaxe.c
+++ b/diffcore-pickaxe.c
@@ -102,7 +102,7 @@ void diffcore_pickaxe(const char *needle, int opts)
for (i = 0; i < q->nr; i++)
diff_free_filepair(q->queue[i]);
}
- else
+ else
/* Showing only the filepairs that has the needle */
for (i = 0; i < q->nr; i++) {
struct diff_filepair *p = q->queue[i];
diff --git a/dir.c b/dir.c
index 11fab7f..f543f50 100644
--- a/dir.c
+++ b/dir.c
@@ -321,7 +321,7 @@ static enum exist_status directory_exists_in_index(const char *dirname, int len)
break;
if (endchar == '/')
return index_directory;
- if (!endchar && S_ISDIRLNK(ntohl(ce->ce_mode)))
+ if (!endchar && S_ISGITLINK(ntohl(ce->ce_mode)))
return index_gitdir;
}
return index_nonexistent;
@@ -356,7 +356,7 @@ static enum exist_status directory_exists_in_index(const char *dirname, int len)
* also true and the directory is empty, in which case
* we just ignore it entirely.
* (b) if it looks like a git directory, and we don't have
- * 'no_dirlinks' set we treat it as a gitlink, and show it
+ * 'no_gitlinks' set we treat it as a gitlink, and show it
* as a directory.
* (c) otherwise, we recurse into it.
*/
@@ -383,7 +383,7 @@ static enum directory_treatment treat_directory(struct dir_struct *dir,
case index_nonexistent:
if (dir->show_other_directories)
break;
- if (!dir->no_dirlinks) {
+ if (!dir->no_gitlinks) {
unsigned char sha1[20];
if (resolve_gitlink_ref(dirname, "HEAD", sha1) == 0)
return show_directory;
diff --git a/dir.h b/dir.h
index 817c674..172147f 100644
--- a/dir.h
+++ b/dir.h
@@ -34,7 +34,7 @@ struct dir_struct {
unsigned int show_ignored:1,
show_other_directories:1,
hide_empty_directories:1,
- no_dirlinks:1;
+ no_gitlinks:1;
struct dir_entry **entries;
/* Exclude info */
diff --git a/entry.c b/entry.c
index 82bf725..c540ae1 100644
--- a/entry.c
+++ b/entry.c
@@ -31,7 +31,7 @@ static void remove_subtree(const char *path)
struct dirent *de;
char pathbuf[PATH_MAX];
char *name;
-
+
if (!dir)
die("cannot opendir %s (%s)", path, strerror(errno));
strcpy(pathbuf, path);
@@ -145,7 +145,7 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout
"symlink %s (%s)", path, strerror(errno));
}
break;
- case S_IFDIRLNK:
+ case S_IFGITLINK:
if (to_tempfile)
return error("git-checkout-index: cannot create temporary subproject %s", path);
if (mkdir(path, 0777) < 0)
@@ -194,7 +194,7 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *t
unlink(path);
if (S_ISDIR(st.st_mode)) {
/* If it is a gitlink, leave it alone! */
- if (S_ISDIRLNK(ntohl(ce->ce_mode)))
+ if (S_ISGITLINK(ntohl(ce->ce_mode)))
return 0;
if (!state->force)
return error("%s is a directory", path);
diff --git a/environment.c b/environment.c
index 2231659..8b9b89d 100644
--- a/environment.c
+++ b/environment.c
@@ -11,7 +11,6 @@
char git_default_email[MAX_GITNAME];
char git_default_name[MAX_GITNAME];
-int use_legacy_headers = 1;
int trust_executable_bit = 1;
int has_symlinks = 1;
int assume_unchanged;
@@ -24,7 +23,9 @@ const char *git_commit_encoding;
const char *git_log_output_encoding;
int shared_repository = PERM_UMASK;
const char *apply_default_whitespace;
-int zlib_compression_level = Z_DEFAULT_COMPRESSION;
+int zlib_compression_level = Z_BEST_SPEED;
+int core_compression_level;
+int core_compression_seen;
size_t packed_git_window_size = DEFAULT_PACKED_GIT_WINDOW_SIZE;
size_t packed_git_limit = DEFAULT_PACKED_GIT_LIMIT;
size_t delta_base_cache_limit = 16 * 1024 * 1024;
@@ -104,5 +105,3 @@ char *get_graft_file(void)
setup_git_env();
return git_graft_file;
}
-
-
diff --git a/fast-import.c b/fast-import.c
index 17554f6..f9bfcc7 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -1272,7 +1272,7 @@ static int update_branch(struct branch *b)
if (read_ref(b->name, old_sha1))
hashclr(old_sha1);
- lock = lock_any_ref_for_update(b->name, old_sha1);
+ lock = lock_any_ref_for_update(b->name, old_sha1, 0);
if (!lock)
return error("Unable to lock %s", b->name);
if (!force_update && !is_null_sha1(old_sha1)) {
diff --git a/fetch-pack.c b/fetch-pack.c
index 06f4aec..9c81305 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -114,7 +114,7 @@ static const unsigned char* get_rev(void)
commit->object.flags |= POPPED;
if (!(commit->object.flags & COMMON))
non_common_revs--;
-
+
parents = commit->parents;
if (commit->object.flags & COMMON) {
@@ -733,7 +733,7 @@ int main(int argc, char **argv)
}
if (!dest)
usage(fetch_pack_usage);
- pid = git_connect(fd, dest, uploadpack);
+ pid = git_connect(fd, dest, uploadpack, verbose ? CONNECT_VERBOSE : 0);
if (pid < 0)
return 1;
if (heads && nr_heads)
diff --git a/fetch.c b/fetch.c
index 8e29d31..dda33e5 100644
--- a/fetch.c
+++ b/fetch.c
@@ -15,7 +15,7 @@ int get_verbosely = 0;
int get_recover = 0;
static unsigned char current_commit_sha1[20];
-void pull_say(const char *fmt, const char *hex)
+void pull_say(const char *fmt, const char *hex)
{
if (get_verbosely)
fprintf(stderr, fmt, hex);
@@ -153,7 +153,7 @@ static int process(struct object *obj)
return 0;
prefetch(obj->sha1);
}
-
+
object_list_insert(obj, process_queue_end);
process_queue_end = &(*process_queue_end)->next;
return 0;
diff --git a/git-applymbox.sh b/git-applymbox.sh
deleted file mode 100755
index c18e80f..0000000
--- a/git-applymbox.sh
+++ /dev/null
@@ -1,121 +0,0 @@
-#!/bin/sh
-##
-## "dotest" is my stupid name for my patch-application script, which
-## I never got around to renaming after I tested it. We're now on the
-## second generation of scripts, still called "dotest".
-##
-## Update: Ryan Anderson finally shamed me into naming this "applymbox".
-##
-## You give it a mbox-format collection of emails, and it will try to
-## apply them to the kernel using "applypatch"
-##
-## The patch application may fail in the middle. In which case:
-## (1) look at .dotest/patch and fix it up to apply
-## (2) re-run applymbox with -c .dotest/msg-number for the current one.
-## Pay a special attention to the commit log message if you do this and
-## use a Signoff_file, because applypatch wants to append the sign-off
-## message to msg-clean every time it is run.
-##
-## git-am is supposed to be the newer and better tool for this job.
-
-USAGE='[-u] [-k] [-q] [-m] (-c .dotest/<num> | mbox) [signoff]'
-. git-sh-setup
-
-git var GIT_COMMITTER_IDENT >/dev/null || exit
-
-keep_subject= query_apply= continue= utf8=-u resume=t
-while case "$#" in 0) break ;; esac
-do
- case "$1" in
- -u) utf8=-u ;;
- -n) utf8=-n ;;
- -k) keep_subject=-k ;;
- -q) query_apply=t ;;
- -c) continue="$2"; resume=f; shift ;;
- -m) fall_back_3way=t ;;
- -*) usage ;;
- *) break ;;
- esac
- shift
-done
-
-case "$continue" in
-'')
- rm -rf .dotest
- mkdir .dotest
- num_msgs=$(git-mailsplit "$1" .dotest) || exit 1
- echo "$num_msgs patch(es) to process."
- shift
-esac
-
-files=$(git-diff-index --cached --name-only HEAD) || exit
-if [ "$files" ]; then
- echo "Dirty index: cannot apply patches (dirty: $files)" >&2
- exit 1
-fi
-
-case "$query_apply" in
-t) touch .dotest/.query_apply
-esac
-case "$fall_back_3way" in
-t) : >.dotest/.3way
-esac
-case "$keep_subject" in
--k) : >.dotest/.keep_subject
-esac
-
-signoff="$1"
-set x .dotest/0*
-shift
-while case "$#" in 0) break;; esac
-do
- i="$1"
- case "$resume,$continue" in
- f,$i) resume=t;;
- f,*) shift
- continue;;
- *)
- git-mailinfo $keep_subject $utf8 \
- .dotest/msg .dotest/patch <$i >.dotest/info || exit 1
- test -s .dotest/patch || {
- echo "Patch is empty. Was it split wrong?"
- exit 1
- }
- git-stripspace < .dotest/msg > .dotest/msg-clean
- ;;
- esac
- while :; # for fixing up and retry
- do
- git-applypatch .dotest/msg-clean .dotest/patch .dotest/info "$signoff"
- case "$?" in
- 0)
- # Remove the cleanly applied one to reduce clutter.
- rm -f .dotest/$i
- ;;
- 2)
- # 2 is a special exit code from applypatch to indicate that
- # the patch wasn't applied, but continue anyway
- ;;
- *)
- ret=$?
- if test -f .dotest/.query_apply
- then
- echo >&2 "* Patch failed."
- echo >&2 "* You could fix it up in your editor and"
- echo >&2 " retry. If you want to do so, say yes here"
- echo >&2 " AFTER fixing .dotest/patch up."
- echo >&2 -n "Retry [y/N]? "
- read yesno
- case "$yesno" in
- [Yy]*)
- continue ;;
- esac
- fi
- exit $ret
- esac
- break
- done
- shift
-done
-# return to pristine
-rm -fr .dotest
diff --git a/git-applypatch.sh b/git-applypatch.sh
deleted file mode 100755
index 8df2aee..0000000
--- a/git-applypatch.sh
+++ /dev/null
@@ -1,212 +0,0 @@
-#!/bin/sh
-##
-## applypatch takes four file arguments, and uses those to
-## apply the unpacked patch (surprise surprise) that they
-## represent to the current tree.
-##
-## The arguments are:
-## $1 - file with commit message
-## $2 - file with the actual patch
-## $3 - "info" file with Author, email and subject
-## $4 - optional file containing signoff to add
-##
-
-USAGE='<msg> <patch> <info> [<signoff>]'
-. git-sh-setup
-
-case "$#" in 3|4) ;; *) usage ;; esac
-
-final=.dotest/final-commit
-##
-## If this file exists, we ask before applying
-##
-query_apply=.dotest/.query_apply
-
-## We do not munge the first line of the commit message too much
-## if this file exists.
-keep_subject=.dotest/.keep_subject
-
-## We do not attempt the 3-way merge fallback unless this file exists.
-fall_back_3way=.dotest/.3way
-
-MSGFILE=$1
-PATCHFILE=$2
-INFO=$3
-SIGNOFF=$4
-EDIT=${VISUAL:-${EDITOR:-vi}}
-
-export GIT_AUTHOR_NAME="$(sed -n '/^Author/ s/Author: //p' "$INFO")"
-export GIT_AUTHOR_EMAIL="$(sed -n '/^Email/ s/Email: //p' "$INFO")"
-export GIT_AUTHOR_DATE="$(sed -n '/^Date/ s/Date: //p' "$INFO")"
-export SUBJECT="$(sed -n '/^Subject/ s/Subject: //p' "$INFO")"
-
-if test '' != "$SIGNOFF"
-then
- if test -f "$SIGNOFF"
- then
- SIGNOFF=`cat "$SIGNOFF"` || exit
- elif case "$SIGNOFF" in yes | true | me | please) : ;; *) false ;; esac
- then
- SIGNOFF=`git-var GIT_COMMITTER_IDENT | sed -e '
- s/>.*/>/
- s/^/Signed-off-by: /'
- `
- else
- SIGNOFF=
- fi
- if test '' != "$SIGNOFF"
- then
- LAST_SIGNED_OFF_BY=`
- sed -ne '/^Signed-off-by: /p' "$MSGFILE" |
- tail -n 1
- `
- test "$LAST_SIGNED_OFF_BY" = "$SIGNOFF" || {
- test '' = "$LAST_SIGNED_OFF_BY" && echo
- echo "$SIGNOFF"
- } >>"$MSGFILE"
- fi
-fi
-
-patch_header=
-test -f "$keep_subject" || patch_header='[PATCH] '
-
-{
- echo "$patch_header$SUBJECT"
- if test -s "$MSGFILE"
- then
- echo
- cat "$MSGFILE"
- fi
-} >"$final"
-
-interactive=yes
-test -f "$query_apply" || interactive=no
-
-while [ "$interactive" = yes ]; do
- echo "Commit Body is:"
- echo "--------------------------"
- cat "$final"
- echo "--------------------------"
- printf "Apply? [y]es/[n]o/[e]dit/[a]ccept all "
- read reply
- case "$reply" in
- y|Y) interactive=no;;
- n|N) exit 2;; # special value to tell dotest to keep going
- e|E) "$EDIT" "$final";;
- a|A) rm -f "$query_apply"
- interactive=no ;;
- esac
-done
-
-if test -x "$GIT_DIR"/hooks/applypatch-msg
-then
- "$GIT_DIR"/hooks/applypatch-msg "$final" || exit
-fi
-
-echo
-echo Applying "'$SUBJECT'"
-echo
-
-git-apply --index "$PATCHFILE" || {
-
- # git-apply exits with status 1 when the patch does not apply,
- # but it die()s with other failures, most notably upon corrupt
- # patch. In the latter case, there is no point to try applying
- # it to another tree and do 3-way merge.
- test $? = 1 || exit 1
-
- test -f "$fall_back_3way" || exit 1
-
- # Here if we know which revision the patch applies to,
- # we create a temporary working tree and index, apply the
- # patch, and attempt 3-way merge with the resulting tree.
-
- O_OBJECT=`cd "$GIT_OBJECT_DIRECTORY" && pwd`
- rm -fr .patch-merge-*
-
- if git-apply -z --index-info "$PATCHFILE" \
- >.patch-merge-index-info 2>/dev/null &&
- GIT_INDEX_FILE=.patch-merge-tmp-index \
- git-update-index -z --index-info <.patch-merge-index-info &&
- GIT_INDEX_FILE=.patch-merge-tmp-index \
- git-write-tree >.patch-merge-tmp-base &&
- (
- mkdir .patch-merge-tmp-dir &&
- cd .patch-merge-tmp-dir &&
- GIT_INDEX_FILE="../.patch-merge-tmp-index" \
- GIT_OBJECT_DIRECTORY="$O_OBJECT" \
- git-apply $binary --index
- ) <"$PATCHFILE"
- then
- echo Using index info to reconstruct a base tree...
- mv .patch-merge-tmp-base .patch-merge-base
- mv .patch-merge-tmp-index .patch-merge-index
- else
- (
- N=10
-
- # Otherwise, try nearby trees that can be used to apply the
- # patch.
- git-rev-list --max-count=$N HEAD
-
- # or hoping the patch is against known tags...
- git-ls-remote --tags .
- ) |
- while read base junk
- do
- # Try it if we have it as a tree.
- git-cat-file tree "$base" >/dev/null 2>&1 || continue
-
- rm -fr .patch-merge-tmp-* &&
- mkdir .patch-merge-tmp-dir || break
- (
- cd .patch-merge-tmp-dir &&
- GIT_INDEX_FILE=../.patch-merge-tmp-index &&
- GIT_OBJECT_DIRECTORY="$O_OBJECT" &&
- export GIT_INDEX_FILE GIT_OBJECT_DIRECTORY &&
- git-read-tree "$base" &&
- git-apply --index &&
- mv ../.patch-merge-tmp-index ../.patch-merge-index &&
- echo "$base" >../.patch-merge-base
- ) <"$PATCHFILE" 2>/dev/null && break
- done
- fi
-
- test -f .patch-merge-index &&
- his_tree=$(GIT_INDEX_FILE=.patch-merge-index git-write-tree) &&
- orig_tree=$(cat .patch-merge-base) &&
- rm -fr .patch-merge-* || exit 1
-
- echo Falling back to patching base and 3-way merge using $orig_tree...
-
- # This is not so wrong. Depending on which base we picked,
- # orig_tree may be wildly different from ours, but his_tree
- # has the same set of wildly different changes in parts the
- # patch did not touch, so resolve ends up canceling them,
- # saying that we reverted all those changes.
-
- if git-merge-resolve $orig_tree -- HEAD $his_tree
- then
- echo Done.
- else
- echo Failed to merge in the changes.
- exit 1
- fi
-}
-
-if test -x "$GIT_DIR"/hooks/pre-applypatch
-then
- "$GIT_DIR"/hooks/pre-applypatch || exit
-fi
-
-tree=$(git-write-tree) || exit 1
-echo Wrote tree $tree
-parent=$(git-rev-parse --verify HEAD) &&
-commit=$(git-commit-tree $tree -p $parent <"$final") || exit 1
-echo Committed: $commit
-git-update-ref -m "applypatch: $SUBJECT" HEAD $commit $parent || exit
-
-if test -x "$GIT_DIR"/hooks/post-applypatch
-then
- "$GIT_DIR"/hooks/post-applypatch
-fi
diff --git a/git-archimport.perl b/git-archimport.perl
index c1e7c1d..b210772 100755
--- a/git-archimport.perl
+++ b/git-archimport.perl
@@ -3,19 +3,19 @@
# This tool is copyright (c) 2005, Martin Langhoff.
# It is released under the Gnu Public License, version 2.
#
-# The basic idea is to walk the output of tla abrowse,
-# fetch the changesets and apply them.
+# The basic idea is to walk the output of tla abrowse,
+# fetch the changesets and apply them.
#
=head1 Invocation
- git-archimport [ -h ] [ -v ] [ -o ] [ -a ] [ -f ] [ -T ]
- [ -D depth] [ -t tempdir ] <archive>/<branch> [ <archive>/<branch> ]
+ git-archimport [ -h ] [ -v ] [ -o ] [ -a ] [ -f ] [ -T ]
+ [ -D depth] [ -t tempdir ] <archive>/<branch> [ <archive>/<branch> ]
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
+it will just import it as a regular commit. If it can find it, it will mark it
as a merge whenever possible.
See man (1) git-archimport for more details.
@@ -25,14 +25,14 @@ See man (1) git-archimport for more details.
- create tag objects instead of ref tags
- audit shell-escaping of filenames
- hide our private tags somewhere smarter
- - find a way to make "cat *patches | patch" safe even when patchfiles are missing newlines
+ - find a way to make "cat *patches | patch" safe even when patchfiles are missing newlines
- sort and apply patches by graphing ancestry relations instead of just
relying in dates supplied in the changeset itself.
tla ancestry-graph -m could be helpful here...
=head1 Devel tricks
-Add print in front of the shell commands invoked via backticks.
+Add print in front of the shell commands invoked via backticks.
=head1 Devel Notes
@@ -126,16 +126,16 @@ sub do_abrowse {
my $stage = shift;
while (my ($limit, $level) = each %arch_branches) {
next unless $level == $stage;
-
- open ABROWSE, "$TLA abrowse -fkD --merges $limit |"
+
+ open ABROWSE, "$TLA abrowse -fkD --merges $limit |"
or die "Problems with tla abrowse: $!";
-
+
my %ps = (); # the current one
my $lastseen = '';
-
+
while (<ABROWSE>) {
chomp;
-
+
# first record padded w 8 spaces
if (s/^\s{8}\b//) {
my ($id, $type) = split(m/\s+/, $_, 2);
@@ -147,13 +147,13 @@ sub do_abrowse {
push (@psets, \%last_ps);
$psets{ $last_ps{id} } = \%last_ps;
}
-
+
my $branch = extract_versionname($id);
%ps = ( id => $id, branch => $branch );
if (%last_ps && ($last_ps{branch} eq $branch)) {
$ps{parent_id} = $last_ps{id};
}
-
+
$arch_branches{$branch} = 1;
$lastseen = 'id';
@@ -166,16 +166,16 @@ sub do_abrowse {
$ps{type} = 't';
# read which revision we've tagged when we parse the log
$ps{tag} = $1;
- } else {
+ } else {
warn "Unknown type $type";
}
$arch_branches{$branch} = 1;
$lastseen = 'id';
- } elsif (s/^\s{10}//) {
- # 10 leading spaces or more
+ } elsif (s/^\s{10}//) {
+ # 10 leading spaces or more
# indicate commit metadata
-
+
# date
if ($lastseen eq 'id' && m/^(\d{4}-\d\d-\d\d \d\d:\d\d:\d\d)/){
$ps{date} = $1;
@@ -186,12 +186,12 @@ sub do_abrowse {
} elsif ($lastseen eq 'merges' && s/^\s{2}//) {
my $id = $_;
push (@{$ps{merges}}, $id);
-
+
# aggressive branch finding:
if ($opt_D) {
my $branch = extract_versionname($id);
my $repo = extract_reponame($branch);
-
+
if (archive_reachable($repo) &&
!defined $arch_branches{$branch}) {
$arch_branches{$branch} = $stage + 1;
@@ -208,10 +208,10 @@ sub do_abrowse {
if (@psets && $psets[$#psets]{branch} eq $ps{branch}) {
$temp{parent_id} = $psets[$#psets]{id};
}
- push (@psets, \%temp);
+ push (@psets, \%temp);
$psets{ $temp{id} } = \%temp;
- }
-
+ }
+
close ABROWSE or die "$TLA abrowse failed on $limit\n";
}
} # end foreach $root
@@ -253,7 +253,7 @@ unless (-d $git_dir) { # initial import
while (my $file = readdir(DIR)) {
# skip non-interesting-files
next unless -f "$ptag_dir/$file";
-
+
# convert first '--' to '/' from old git-archimport to use
# as an archivename/c--b--v private tag
if ($file !~ m!,!) {
@@ -275,7 +275,7 @@ sub extract_reponame {
my $fq_cvbr = shift; # archivename/[[[[category]branch]version]revision]
return (split(/\//, $fq_cvbr))[0];
}
-
+
sub extract_versionname {
my $name = shift;
$name =~ s/--(?:patch|version(?:fix)?|base)-\d+$//;
@@ -283,7 +283,7 @@ sub extract_versionname {
}
# convert a fully-qualified revision or version to a unique dirname:
-# normalperson@yhbt.net-05/mpd--uclinux--1--patch-2
+# normalperson@yhbt.net-05/mpd--uclinux--1--patch-2
# becomes: normalperson@yhbt.net-05,mpd--uclinux--1
#
# the git notion of a branch is closer to
@@ -339,7 +339,7 @@ sub git_branchname {
sub process_patchset_accurate {
my $ps = shift;
-
+
# switch to that branch if we're not already in that branch:
if (-e "$git_dir/refs/heads/$ps->{branch}") {
system('git-checkout','-f',$ps->{branch}) == 0 or die "$! $?\n";
@@ -348,7 +348,7 @@ sub process_patchset_accurate {
my $rm = safe_pipe_capture('git-ls-files','--others','-z');
rmtree(split(/\0/,$rm)) if $rm;
}
-
+
# Apply the import/changeset/merge into the working tree
my $dir = sync_to_ps($ps);
# read the new log entry:
@@ -361,9 +361,9 @@ sub process_patchset_accurate {
parselog($ps, \@commitlog);
if ($ps->{id} =~ /--base-0$/ && $ps->{id} ne $psets[0]{id}) {
- # this should work when importing continuations
+ # this should work when importing continuations
if ($ps->{tag} && (my $branchpoint = eval { ptag($ps->{tag}) })) {
-
+
# find where we are supposed to branch from
if (! -e "$git_dir/refs/heads/$ps->{branch}") {
system('git-branch',$ps->{branch},$branchpoint) == 0 or die "$! $?\n";
@@ -388,8 +388,8 @@ sub process_patchset_accurate {
}
# allow multiple bases/imports here since Arch supports cherry-picks
# from unrelated trees
- }
-
+ }
+
# update the index with all the changes we got
system('git-diff-files --name-only -z | '.
'git-update-index --remove -z --stdin') == 0 or die "$! $?\n";
@@ -402,7 +402,7 @@ sub process_patchset_accurate {
# does not handle permissions or any renames involving directories
sub process_patchset_fast {
my $ps = shift;
- #
+ #
# create the branch if needed
#
if ($ps->{type} eq 'i' && !$import) {
@@ -417,9 +417,9 @@ sub process_patchset_fast {
# new branch! we need to verify a few things
die "Branch on a non-tag!" unless $ps->{type} eq 't';
my $branchpoint = ptag($ps->{tag});
- die "Tagging from unknown id unsupported: $ps->{tag}"
+ die "Tagging from unknown id unsupported: $ps->{tag}"
unless $branchpoint;
-
+
# find where we are supposed to branch from
if (! -e "$git_dir/refs/heads/$ps->{branch}") {
system('git-branch',$ps->{branch},$branchpoint) == 0 or die "$! $?\n";
@@ -435,13 +435,13 @@ sub process_patchset_fast {
}
system('git-checkout',$ps->{branch}) == 0 or die "$! $?\n";
return 0;
- }
+ }
die $! if $?;
- }
+ }
#
# Apply the import/changeset/merge into the working tree
- #
+ #
if ($ps->{type} eq 'i' || $ps->{type} eq 't') {
apply_import($ps) or die $!;
$stats{import_or_tag}++;
@@ -455,10 +455,10 @@ sub process_patchset_fast {
# prepare update git's index, based on what arch knows
# about the pset, resolve parents, etc
#
-
- my @commitlog = safe_pipe_capture($TLA,'cat-archive-log',$ps->{id});
+
+ my @commitlog = safe_pipe_capture($TLA,'cat-archive-log',$ps->{id});
die "Error in cat-archive-log: $!" if $?;
-
+
parselog($ps,\@commitlog);
# imports don't give us good info
@@ -485,10 +485,10 @@ sub process_patchset_fast {
if (@$ren % 2) {
die "Odd number of entries in rename!?";
}
-
+
while (@$ren) {
my $from = shift @$ren;
- my $to = shift @$ren;
+ my $to = shift @$ren;
unless (-d dirname($to)) {
mkpath(dirname($to)); # will die on err
@@ -529,20 +529,20 @@ if ($opt_f) {
"Things may be a bit slow\n";
*process_patchset = *process_patchset_accurate;
}
-
+
foreach my $ps (@psets) {
# process patchsets
$ps->{branch} = git_branchname($ps->{id});
#
- # ensure we have a clean state
- #
+ # ensure we have a clean state
+ #
if (my $dirty = `git-diff-files`) {
die "Unclean tree when about to process $ps->{id} " .
" - did we fail to commit cleanly before?\n$dirty";
}
die $! if $?;
-
+
#
# skip commits already in repo
#
@@ -559,7 +559,7 @@ foreach my $ps (@psets) {
my $tree = `git-write-tree`;
die "cannot write tree $!" if $?;
chomp $tree;
-
+
#
# Who's your daddy?
#
@@ -570,18 +570,18 @@ foreach my $ps (@psets) {
close HEAD;
chomp $p;
push @par, '-p', $p;
- } else {
+ } else {
if ($ps->{type} eq 's') {
warn "Could not find the right head for the branch $ps->{branch}";
}
}
}
-
+
if ($ps->{merges}) {
push @par, find_parents($ps);
}
- #
+ #
# Commit, tag and clean state
#
$ENV{TZ} = 'GMT';
@@ -592,14 +592,14 @@ foreach my $ps (@psets) {
$ENV{GIT_COMMITTER_EMAIL} = $ps->{email};
$ENV{GIT_COMMITTER_DATE} = $ps->{date};
- my $pid = open2(*READER, *WRITER,'git-commit-tree',$tree,@par)
+ my $pid = open2(*READER, *WRITER,'git-commit-tree',$tree,@par)
or die $!;
print WRITER $ps->{summary},"\n\n";
print WRITER $ps->{message},"\n";
-
+
# make it easy to backtrack and figure out which Arch revision this was:
print WRITER 'git-archimport-id: ',$ps->{id},"\n";
-
+
close WRITER;
my $commitid = <READER>; # read
chomp $commitid;
@@ -611,7 +611,7 @@ foreach my $ps (@psets) {
}
#
# Update the branch
- #
+ #
open HEAD, ">","$git_dir/refs/heads/$ps->{branch}";
print HEAD $commitid;
close HEAD;
@@ -640,7 +640,7 @@ exit 0;
sub sync_to_ps {
my $ps = shift;
my $tree_dir = $tmp.'/'.tree_dirname($ps->{id});
-
+
$opt_v && print "sync_to_ps($ps->{id}) method: ";
if (-d $tree_dir) {
@@ -674,7 +674,7 @@ sub sync_to_ps {
safe_pipe_capture($TLA,'get','--no-pristine',$ps->{id},$tree_dir);
$stats{get_new}++;
}
-
+
# added -I flag to rsync since we're going to fast! AIEEEEE!!!!
system('rsync','-aI','--delete','--exclude',$git_dir,
# '--exclude','.arch-inventory',
@@ -691,15 +691,15 @@ sub apply_import {
mkpath($tmp);
safe_pipe_capture($TLA,'get','-s','--no-pristine',$ps->{id},"$tmp/import");
- die "Cannot get import: $!" if $?;
+ die "Cannot get import: $!" if $?;
system('rsync','-aI','--delete', '--exclude',$git_dir,
'--exclude','.arch-ids','--exclude','{arch}',
"$tmp/import/", './');
die "Cannot rsync import:$!" if $?;
-
+
rmtree("$tmp/import");
die "Cannot remove tempdir: $!" if $?;
-
+
return 1;
}
@@ -712,13 +712,13 @@ sub apply_cset {
# get the changeset
safe_pipe_capture($TLA,'get-changeset',$ps->{id},"$tmp/changeset");
die "Cannot get changeset: $!" if $?;
-
+
# apply patches
if (`find $tmp/changeset/patches -type f -name '*.patch'`) {
# this can be sped up considerably by doing
# (find | xargs cat) | patch
# but that can get mucked up by patches
- # with missing trailing newlines or the standard
+ # with missing trailing newlines or the standard
# 'missing newline' flag in the patch - possibly
# produced with an old/buggy diff.
# slow and safe, we invoke patch once per patchfile
@@ -741,7 +741,7 @@ sub apply_cset {
# bring in new files
system('rsync','-aI','--exclude',$git_dir,
- '--exclude','.arch-ids',
+ '--exclude','.arch-ids',
'--exclude', '{arch}',
"$tmp/changeset/new-files-archive/",'./');
@@ -789,7 +789,7 @@ sub parselog {
removed_files => 1,
removed_directories => 1,
);
-
+
chomp (@$log);
while ($_ = shift @$log) {
if (/^Continuation-of:\s*(.*)/) {
@@ -828,7 +828,7 @@ sub parselog {
}
}
}
-
+
# drop leading empty lines from the log message
while (@$log && $log->[0] eq '') {
shift @$log;
@@ -842,7 +842,7 @@ sub parselog {
$ps->{summary} = $log->[0] . '...';
}
$ps->{message} = join("\n",@$log);
-
+
# skip Arch control files, unescape pika-escaped files
foreach my $k (keys %want_headers) {
next unless (defined $ps->{$k});
@@ -867,7 +867,7 @@ sub parselog {
# write/read a tag
sub tag {
my ($tag, $commit) = @_;
-
+
if ($opt_o) {
$tag =~ s|/|--|g;
} else {
@@ -875,7 +875,7 @@ sub tag {
$patchname =~ s/.*--//;
$tag = git_branchname ($tag) . '--' . $patchname;
}
-
+
if ($commit) {
open(C,">","$git_dir/refs/tags/$tag")
or die "Cannot create tag $tag: $!\n";
@@ -902,8 +902,8 @@ sub ptag {
my ($tag, $commit) = @_;
# don't use subdirs for tags yet, it could screw up other porcelains
- $tag =~ s|/|,|g;
-
+ $tag =~ s|/|,|g;
+
my $tag_file = "$ptag_dir/$tag";
my $tag_branch_dir = dirname($tag_file);
mkpath($tag_branch_dir) unless (-d $tag_branch_dir);
@@ -915,7 +915,7 @@ sub ptag {
or die "Cannot write tag $tag: $!\n";
close(C)
or die "Cannot write tag $tag: $!\n";
- $rptags{$commit} = $tag
+ $rptags{$commit} = $tag
unless $tag =~ m/--base-0$/;
} else { # read
# if the tag isn't there, return 0
@@ -941,7 +941,7 @@ sub find_parents {
# Identify what branches are merging into me
# and whether we are fully merged
# git-merge-base <headsha> <headsha> should tell
- # me what the base of the merge should be
+ # me what the base of the merge should be
#
my $ps = shift;
@@ -963,14 +963,14 @@ sub find_parents {
}
#
- # foreach branch find a merge base and walk it to the
+ # foreach branch find a merge base and walk it to the
# head where we are, collecting the merged patchsets that
# Arch has recorded. Keep that in @have
# Compare that with the commits on the other branch
# between merge-base and the tip of the branch (@need)
# and see if we have a series of consecutive patches
# starting from the merge base. The tip of the series
- # of consecutive patches merged is our new parent for
+ # of consecutive patches merged is our new parent for
# that branch.
#
foreach my $branch (keys %branches) {
@@ -979,13 +979,13 @@ sub find_parents {
next unless -e "$git_dir/refs/heads/$branch";
my $mergebase = `git-merge-base $branch $ps->{branch}`;
- if ($?) {
- # Don't die here, Arch supports one-way cherry-picking
- # between branches with no common base (or any relationship
- # at all beforehand)
- warn "Cannot find merge base for $branch and $ps->{branch}";
- next;
- }
+ if ($?) {
+ # Don't die here, Arch supports one-way cherry-picking
+ # between branches with no common base (or any relationship
+ # at all beforehand)
+ warn "Cannot find merge base for $branch and $ps->{branch}";
+ next;
+ }
chomp $mergebase;
# now walk up to the mergepoint collecting what patches we have
@@ -1010,7 +1010,7 @@ sub find_parents {
# merge what we have with what ancestors have
%have = (%have, %ancestorshave);
- # see what the remote branch has - these are the merges we
+ # see what the remote branch has - these are the merges we
# will want to have in a consecutive series from the mergebase
my $otherbranchtip = git_rev_parse($branch);
my @needraw = `git-rev-list --topo-order $otherbranchtip ^$mergebase`;
@@ -1018,7 +1018,7 @@ sub find_parents {
foreach my $needps (@needraw) { # get the psets
$needps = commitid2pset($needps);
# git-rev-list will also
- # list commits merged in via earlier
+ # list commits merged in via earlier
# merges. we are only interested in commits
# from the branch we're looking at
if ($branch eq $needps->{branch}) {
@@ -1054,7 +1054,7 @@ sub find_parents {
next unless ref $psets{$p}{merges};
my @merges = @{$psets{$p}{merges}};
foreach my $merge (@merges) {
- if ($parents{$merge}) {
+ if ($parents{$merge}) {
delete $parents{$merge};
}
}
@@ -1079,10 +1079,10 @@ sub git_rev_parse {
sub commitid2pset {
my $commitid = shift;
chomp $commitid;
- my $name = $rptags{$commitid}
+ my $name = $rptags{$commitid}
|| die "Cannot find reverse tag mapping for $commitid";
$name =~ s|,|/|;
- my $ps = $psets{$name}
+ my $ps = $psets{$name}
|| (print Dumper(sort keys %psets)) && die "Cannot find patchset for $name";
return $ps;
}
@@ -1112,7 +1112,7 @@ sub archive_reachable {
my $archive = shift;
return 1 if $reachable{$archive};
return 0 if $unreachable{$archive};
-
+
if (system "$TLA whereis-archive $archive >/dev/null") {
if ($opt_a && (system($TLA,'register-archive',
"http://mirrors.sourcecontrol.net/$archive") == 0)) {
@@ -1127,4 +1127,3 @@ sub archive_reachable {
return 1;
}
}
-
diff --git a/git-checkout.sh b/git-checkout.sh
index 7c5ca3d..33f1e87 100755
--- a/git-checkout.sh
+++ b/git-checkout.sh
@@ -211,7 +211,7 @@ else
esac
# Match the index to the working tree, and do a three-way.
- git diff-files --name-only | git update-index --remove --stdin &&
+ git diff-files --name-only | git update-index --remove --stdin &&
work=`git write-tree` &&
git read-tree $v --reset -u $new || exit
@@ -246,7 +246,7 @@ else
(exit $saved_err)
fi
-#
+#
# Switch the HEAD pointer to the new branch if we
# checked out a branch head, and remove any potential
# old MERGE_HEAD's (subsequent commits will clearly not
@@ -271,15 +271,7 @@ if [ "$?" -eq 0 ]; then
fi
elif test -n "$detached"
then
- # NEEDSWORK: we would want a command to detach the HEAD
- # atomically, instead of this handcrafted command sequence.
- # Perhaps:
- # git update-ref --detach HEAD $new
- # or something like that...
- #
- git-rev-parse HEAD >"$GIT_DIR/HEAD.new" &&
- mv "$GIT_DIR/HEAD.new" "$GIT_DIR/HEAD" &&
- git-update-ref -m "checkout: moving to $arg" HEAD "$detached" ||
+ git-update-ref --no-deref -m "checkout: moving to $arg" HEAD "$detached" ||
die "Cannot detach HEAD"
if test -n "$detach_warn"
then
diff --git a/git-clone.sh b/git-clone.sh
index fdd354f..3a41062 100755
--- a/git-clone.sh
+++ b/git-clone.sh
@@ -2,7 +2,7 @@
#
# Copyright (c) 2005, Linus Torvalds
# Copyright (c) 2005, Junio C Hamano
-#
+#
# Clone a repository into a different directory that does not yet exist.
# See git-sh-setup why.
@@ -20,7 +20,7 @@ usage() {
get_repo_base() {
(
cd "`/bin/pwd`" &&
- cd "$1" &&
+ cd "$1" || cd "$1.git" &&
{
cd .git
pwd
@@ -98,7 +98,7 @@ while
*,--na|*,--nak|*,--nake|*,--naked|\
*,-b|*,--b|*,--ba|*,--bar|*,--bare) bare=yes ;;
*,-l|*,--l|*,--lo|*,--loc|*,--loca|*,--local) use_local=yes ;;
- *,-s|*,--s|*,--sh|*,--sha|*,--shar|*,--share|*,--shared)
+ *,-s|*,--s|*,--sh|*,--sha|*,--shar|*,--share|*,--shared)
local_shared=yes; use_local=yes ;;
1,--template) usage ;;
*,--template)
@@ -410,4 +410,3 @@ fi
rm -f "$GIT_DIR/CLONE_HEAD" "$GIT_DIR/REMOTE_HEAD"
trap - 0
-
diff --git a/git-commit.sh b/git-commit.sh
index e8b60f7..5547a02 100755
--- a/git-commit.sh
+++ b/git-commit.sh
@@ -557,7 +557,7 @@ then
} >>"$GIT_DIR"/COMMIT_EDITMSG
else
# we need to check if there is anything to commit
- run_status >/dev/null
+ run_status >/dev/null
fi
if [ "$?" != "0" -a ! -f "$GIT_DIR/MERGE_HEAD" -a -z "$amend" ]
then
diff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl
index d6ae99b..e9832d2 100755
--- a/git-cvsexportcommit.perl
+++ b/git-cvsexportcommit.perl
@@ -15,9 +15,9 @@ unless ($ENV{GIT_DIR} && -r $ENV{GIT_DIR}){
die "GIT_DIR is not defined or is unreadable";
}
-our ($opt_h, $opt_P, $opt_p, $opt_v, $opt_c, $opt_f, $opt_a, $opt_m, $opt_d);
+our ($opt_h, $opt_P, $opt_p, $opt_v, $opt_c, $opt_f, $opt_a, $opt_m, $opt_d, $opt_u);
-getopts('hPpvcfam:d:');
+getopts('uhPpvcfam:d:');
$opt_h && usage();
@@ -178,6 +178,10 @@ foreach my $f (@files) {
my %cvsstat;
if (@canstatusfiles) {
+ if ($opt_u) {
+ my @updated = safe_pipe_capture(@cvs, 'update', @canstatusfiles);
+ print @updated;
+ }
my @cvsoutput;
@cvsoutput= safe_pipe_capture(@cvs, 'status', @canstatusfiles);
my $matchcount = 0;
@@ -193,7 +197,7 @@ if (@canstatusfiles) {
# ... validate new files,
foreach my $f (@afiles) {
if (defined ($cvsstat{$f}) and $cvsstat{$f} ne "Unknown") {
- $dirty = 1;
+ $dirty = 1;
warn "File $f is already known in your CVS checkout -- perhaps it has been added by another user. Or this may indicate that it exists on a different branch. If this is the case, use -f to force the merge.\n";
warn "Status was: $cvsstat{$f}\n";
}
diff --git a/git-cvsimport.perl b/git-cvsimport.perl
index 4e6c9c6..3225a2a 100755
--- a/git-cvsimport.perl
+++ b/git-cvsimport.perl
@@ -145,7 +145,7 @@ my $cvs_tree;
if ($#ARGV == 0) {
$cvs_tree = $ARGV[0];
} elsif (-f 'CVS/Repository') {
- open my $f, '<', 'CVS/Repository' or
+ open my $f, '<', 'CVS/Repository' or
die 'Failed to open CVS/Repository';
$cvs_tree = <$f>;
chomp $cvs_tree;
@@ -434,7 +434,7 @@ sub file {
my ($self,$fn,$rev) = @_;
my $res;
- my ($fh, $name) = tempfile('gitcvs.XXXXXX',
+ my ($fh, $name) = tempfile('gitcvs.XXXXXX',
DIR => File::Spec->tmpdir(), UNLINK => 1);
$self->_file($fn,$rev) and $res = $self->_line($fh);
@@ -520,8 +520,8 @@ sub is_sha1 {
sub get_headref ($$) {
my $name = shift;
- my $git_dir = shift;
-
+ my $git_dir = shift;
+
my $f = "$git_dir/refs/heads/$name";
if (open(my $fh, $f)) {
chomp(my $r = <$fh>);
@@ -771,7 +771,7 @@ sub commit {
$xtag =~ s/\s+\*\*.*$//; # Remove stuff like ** INVALID ** and ** FUNKY **
$xtag =~ tr/_/\./ if ( $opt_u );
$xtag =~ s/[\/]/$opt_s/g;
-
+
my $pid = open2($in, $out, 'git-mktag');
print $out "object $cid\n".
"type commit\n".
@@ -788,7 +788,7 @@ sub commit {
$? != 0 or $tagobj !~ /^[0123456789abcdef]{40}$/ ) {
die "Cannot create tag object $xtag: $!\n";
}
-
+
open(C,">$git_dir/refs/tags/$xtag")
or die "Cannot create tag $xtag: $!\n";
diff --git a/git-cvsserver.perl b/git-cvsserver.perl
index 1de5177..d41b29f 100755
--- a/git-cvsserver.perl
+++ b/git-cvsserver.perl
@@ -95,9 +95,10 @@ $state->{method} = 'ext';
if (@ARGV && $ARGV[0] eq 'pserver') {
$state->{method} = 'pserver';
my $line = <STDIN>; chomp $line;
- unless( $line eq 'BEGIN AUTH REQUEST') {
+ unless( $line =~ /^BEGIN (AUTH|VERIFICATION) REQUEST$/) {
die "E Do not understand $line - expecting BEGIN AUTH REQUEST\n";
}
+ my $request = $1;
$line = <STDIN>; chomp $line;
req_Root('root', $line) # reuse Root
or die "E Invalid root $line \n";
@@ -109,10 +110,11 @@ if (@ARGV && $ARGV[0] eq 'pserver') {
}
$line = <STDIN>; chomp $line; # validate the password?
$line = <STDIN>; chomp $line;
- unless ($line eq 'END AUTH REQUEST') {
- die "E Do not understand $line -- expecting END AUTH REQUEST\n";
+ unless ($line eq "END $request REQUEST") {
+ die "E Do not understand $line -- expecting END $request REQUEST\n";
}
print "I LOVE YOU\n";
+ exit if $request eq 'VERIFICATION'; # cvs login
# and now back to our regular programme...
}
@@ -165,6 +167,17 @@ sub req_Root
my ( $cmd, $data ) = @_;
$log->debug("req_Root : $data");
+ unless ($data =~ m#^/#) {
+ print "error 1 Root must be an absolute pathname\n";
+ return 0;
+ }
+
+ if ($state->{CVSROOT}
+ && ($state->{CVSROOT} ne $data)) {
+ print "error 1 Conflicting roots specified\n";
+ return 0;
+ }
+
$state->{CVSROOT} = $data;
$ENV{GIT_DIR} = $state->{CVSROOT} . "/";
diff --git a/git-fetch.sh b/git-fetch.sh
index 0e05cf1..6d3a346 100755
--- a/git-fetch.sh
+++ b/git-fetch.sh
@@ -61,7 +61,7 @@ do
quiet=--quiet
;;
-v|--verbose)
- verbose=Yes
+ verbose="$verbose"Yes
;;
-k|--k|--ke|--kee|--keep)
keep='-k -k'
@@ -201,8 +201,14 @@ fetch_all_at_once () {
echo "$ls_remote_result" | \
git-fetch--tool pick-rref "$rref" "-"
else
+ flags=
+ case $verbose in
+ YesYes*)
+ flags="-v"
+ ;;
+ esac
git-fetch-pack --thin $exec $keep $shallow_depth \
- $quiet $no_progress "$remote" $rref ||
+ $quiet $no_progress $flags "$remote" $rref ||
echo failed "$remote"
fi
fi
diff --git a/git-gui/GIT-VERSION-GEN b/git-gui/GIT-VERSION-GEN
index 25647c8..eee495a 100755
--- a/git-gui/GIT-VERSION-GEN
+++ b/git-gui/GIT-VERSION-GEN
@@ -78,5 +78,3 @@ test "$VN" = "$VC" || {
echo >&2 "GITGUI_VERSION = $VN"
echo "GITGUI_VERSION = $VN" >$GVF
}
-
-
diff --git a/git-gui/lib/class.tcl b/git-gui/lib/class.tcl
index 88b0565..72494c1 100644
--- a/git-gui/lib/class.tcl
+++ b/git-gui/lib/class.tcl
@@ -151,4 +151,3 @@ auto_mkindex_parser::command constructor {name args} {
[format { [list source [file join $dir %s]]} \
[file split $scriptFile]] "\n"
}
-
diff --git a/git-merge-one-file.sh b/git-merge-one-file.sh
index 7d62d79..254d210 100755
--- a/git-merge-one-file.sh
+++ b/git-merge-one-file.sh
@@ -88,7 +88,7 @@ case "${1:-.}${2:-.}${3:-.}" in
# remove lines that are unique to ours.
orig=`git-unpack-file $2`
sz0=`wc -c <"$orig"`
- diff -u -La/$orig -Lb/$orig $orig $src2 | git-apply --no-add
+ diff -u -La/$orig -Lb/$orig $orig $src2 | git-apply --no-add
sz1=`wc -c <"$orig"`
# If we do not have enough common material, it is not
diff --git a/git-merge.sh b/git-merge.sh
index b2f8a2a..981d69d 100755
--- a/git-merge.sh
+++ b/git-merge.sh
@@ -3,7 +3,7 @@
# Copyright (c) 2005 Junio C Hamano
#
-USAGE='[-n] [--no-commit] [--squash] [-s <strategy>] [-m=<merge-message>] <commit>+'
+USAGE='[-n] [--summary] [--no-commit] [--squash] [-s <strategy>] [-m=<merge-message>] <commit>+'
SUBDIRECTORY_OK=Yes
. git-sh-setup
@@ -88,11 +88,11 @@ finish () {
'')
;;
?*)
- case "$no_summary" in
- '')
- git-diff-tree --stat --summary -M "$head" "$1"
- ;;
- esac
+ if test "$show_diffstat" = t
+ then
+ # We want color (if set), but no pager
+ GIT_PAGER='' git-diff --stat --summary -M "$head" "$1"
+ fi
;;
esac
}
@@ -125,7 +125,9 @@ do
case "$1" in
-n|--n|--no|--no-|--no-s|--no-su|--no-sum|--no-summ|\
--no-summa|--no-summar|--no-summary)
- no_summary=t ;;
+ show_diffstat=false ;;
+ --summary)
+ show_diffstat=t ;;
--sq|--squ|--squa|--squas|--squash)
squash=t no_commit=t ;;
--no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit)
@@ -167,6 +169,11 @@ do
shift
done
+if test -z "$show_diffstat"; then
+ test "$(git-config --bool merge.diffstat)" = false && show_diffstat=false
+ test -z "$show_diffstat" && show_diffstat=t
+fi
+
# This could be traditional "merge <msg> HEAD <commit>..." and the
# way we can tell it is to see if the second token is HEAD, but some
# people might have misused the interface and used a committish that
diff --git a/git-mergetool.sh b/git-mergetool.sh
index e62351b..bb21b03 100755
--- a/git-mergetool.sh
+++ b/git-mergetool.sh
@@ -5,7 +5,7 @@
# Copyright (c) 2006 Theodore Y. Ts'o
#
# This file is licensed under the GPL v2, or a later version
-# at the discretion of Junio C Hammano.
+# at the discretion of Junio C Hamano.
#
USAGE='[--tool=tool] [file to merge] ...'
diff --git a/git-p4import.py b/git-p4import.py
index 60a758b..0f3d97b 100644
--- a/git-p4import.py
+++ b/git-p4import.py
@@ -358,4 +358,3 @@ for id in changes:
if stitch == 1:
git.clean_directories()
stitch = 0
-
diff --git a/git-pull.sh b/git-pull.sh
index a3665d7..ba0ca07 100755
--- a/git-pull.sh
+++ b/git-pull.sh
@@ -22,6 +22,9 @@ do
-n|--n|--no|--no-|--no-s|--no-su|--no-sum|--no-summ|\
--no-summa|--no-summar|--no-summary)
no_summary=-n ;;
+ --summary)
+ no_summary=$1
+ ;;
--no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit)
no_commit=--no-commit ;;
--sq|--squ|--squa|--squas|--squash)
diff --git a/git-rebase.sh b/git-rebase.sh
index 2dc2c4f..2aa3a01 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -55,7 +55,7 @@ continue_merge () {
if test -n "$unmerged"
then
echo "You still have unmerged paths in your index"
- echo "did you forget update-index?"
+ echo "did you forget to use git add?"
die "$RESOLVEMSG"
fi
@@ -126,7 +126,7 @@ do
--continue)
git-diff-files --quiet || {
echo "You must edit all merge conflicts and then"
- echo "mark them as resolved using git update-index"
+ echo "mark them as resolved using git add"
exit 1
}
if test -d "$dotest"
@@ -307,7 +307,8 @@ fi
if test -n "$verbose"
then
echo "Changes from $mb to $onto:"
- git-diff-tree --stat --summary "$mb" "$onto"
+ # We want color (if set), but no pager
+ GIT_PAGER='' git-diff --stat --summary "$mb" "$onto"
fi
# Rewind the head to "$onto"; this saves our current head in ORIG_HEAD.
diff --git a/git-repack.sh b/git-repack.sh
index ddfa8b4..8c32724 100755
--- a/git-repack.sh
+++ b/git-repack.sh
@@ -3,12 +3,12 @@
# Copyright (c) 2005 Linus Torvalds
#
-USAGE='[-a] [-d] [-f] [-l] [-n] [-q] [--window=N] [--depth=N]'
+USAGE='[-a] [-d] [-f] [-l] [-n] [-q] [--max-pack-size=N] [--window=N] [--depth=N]'
SUBDIRECTORY_OK='Yes'
. git-sh-setup
no_update_info= all_into_one= remove_redundant=
-local= quiet= no_reuse_delta= extra=
+local= quiet= no_reuse= extra=
while case "$#" in 0) break ;; esac
do
case "$1" in
@@ -16,8 +16,9 @@ do
-a) all_into_one=t ;;
-d) remove_redundant=t ;;
-q) quiet=-q ;;
- -f) no_reuse_delta=--no-reuse-delta ;;
+ -f) no_reuse=--no-reuse-object ;;
-l) local=--local ;;
+ --max-pack-size=*) extra="$extra $1" ;;
--window=*) extra="$extra $1" ;;
--depth=*) extra="$extra $1" ;;
*) usage ;;
@@ -35,7 +36,7 @@ true)
esac
PACKDIR="$GIT_OBJECT_DIRECTORY/pack"
-PACKTMP="$GIT_DIR/.tmp-$$-pack"
+PACKTMP="$GIT_OBJECT_DIRECTORY/.tmp-$$-pack"
rm -f "$PACKTMP"-*
trap 'rm -f "$PACKTMP"-*' 0 1 2 3 15
@@ -61,12 +62,14 @@ case ",$all_into_one," in
;;
esac
-args="$args $local $quiet $no_reuse_delta$extra"
-name=$(git-pack-objects --non-empty --all --reflog $args </dev/null "$PACKTMP") ||
+args="$args $local $quiet $no_reuse$extra"
+names=$(git-pack-objects --non-empty --all --reflog $args </dev/null "$PACKTMP") ||
exit 1
-if [ -z "$name" ]; then
+if [ -z "$names" ]; then
echo Nothing new to pack.
-else
+fi
+for name in $names ; do
+ fullbases="$fullbases pack-$name"
chmod a-w "$PACKTMP-$name.pack"
chmod a-w "$PACKTMP-$name.idx"
if test "$quiet" != '-q'; then
@@ -92,7 +95,7 @@ else
exit 1
}
rm -f "$PACKDIR/old-pack-$name.pack" "$PACKDIR/old-pack-$name.idx"
-fi
+done
if test "$remove_redundant" = t
then
@@ -103,8 +106,8 @@ then
( cd "$PACKDIR" &&
for e in $existing
do
- case "$e" in
- pack-$name) ;;
+ case " $fullbases " in
+ *" $e "*) ;;
*) rm -f "$e.pack" "$e.idx" "$e.keep" ;;
esac
done
diff --git a/git-submodule.sh b/git-submodule.sh
new file mode 100755
index 0000000..6ed5a6c
--- /dev/null
+++ b/git-submodule.sh
@@ -0,0 +1,194 @@
+#!/bin/sh
+#
+# git-submodules.sh: init, update or list git submodules
+#
+# Copyright (c) 2007 Lars Hjemli
+
+USAGE='[--quiet] [--cached] [status|init|update] [--] [<path>...]'
+. git-sh-setup
+require_work_tree
+
+init=
+update=
+status=
+quiet=
+cached=
+
+#
+# print stuff on stdout unless -q was specified
+#
+say()
+{
+ if test -z "$quiet"
+ then
+ echo "$@"
+ fi
+}
+
+#
+# Run clone + checkout on missing submodules
+#
+# $@ = requested paths (default to all)
+#
+modules_init()
+{
+ git ls-files --stage -- "$@" | grep -e '^160000 ' |
+ while read mode sha1 stage path
+ do
+ # Skip submodule paths that already contain a .git directory.
+ # This will also trigger if $path is a symlink to a git
+ # repository
+ test -d "$path"/.git && continue
+
+ # If there already is a directory at the submodule path,
+ # expect it to be empty (since that is the default checkout
+ # action) and try to remove it.
+ # Note: if $path is a symlink to a directory the test will
+ # succeed but the rmdir will fail. We might want to fix this.
+ if test -d "$path"
+ then
+ rmdir "$path" 2>/dev/null ||
+ die "Directory '$path' exist, but is neither empty nor a git repository"
+ fi
+
+ test -e "$path" &&
+ die "A file already exist at path '$path'"
+
+ url=$(GIT_CONFIG=.gitmodules git-config module."$path".url)
+ test -z "$url" &&
+ die "No url found for submodule '$path' in .gitmodules"
+
+ # MAYBE FIXME: this would be the place to check GIT_CONFIG
+ # for a preferred url for this submodule, possibly like this:
+ #
+ # modname=$(GIT_CONFIG=.gitmodules git-config module."$path".name)
+ # alturl=$(git-config module."$modname".url)
+ #
+ # This would let the versioned .gitmodules file use the submodule
+ # path as key, while the unversioned GIT_CONFIG would use the
+ # logical modulename (if present) as key. But this would need
+ # another fallback mechanism if the module wasn't named.
+
+ git-clone -n "$url" "$path" ||
+ die "Clone of submodule '$path' failed"
+
+ (unset GIT_DIR && cd "$path" && git-checkout -q "$sha1") ||
+ die "Checkout of submodule '$path' failed"
+
+ say "Submodule '$path' initialized"
+ done
+}
+
+#
+# Checkout correct revision of each initialized submodule
+#
+# $@ = requested paths (default to all)
+#
+modules_update()
+{
+ git ls-files --stage -- "$@" | grep -e '^160000 ' |
+ while read mode sha1 stage path
+ do
+ if ! test -d "$path"/.git
+ then
+ # Only mention uninitialized submodules when its
+ # path have been specified
+ test "$#" != "0" &&
+ say "Submodule '$path' not initialized"
+ continue;
+ fi
+ subsha1=$(unset GIT_DIR && cd "$path" &&
+ git-rev-parse --verify HEAD) ||
+ die "Unable to find current revision of submodule '$path'"
+
+ if test "$subsha1" != "$sha1"
+ then
+ (unset GIT_DIR && cd "$path" && git-fetch &&
+ git-checkout -q "$sha1") ||
+ die "Unable to checkout '$sha1' in submodule '$path'"
+
+ say "Submodule '$path': checked out '$sha1'"
+ fi
+ done
+}
+
+#
+# List all registered submodules, prefixed with:
+# - submodule not initialized
+# + different revision checked out
+#
+# If --cached was specified the revision in the index will be printed
+# instead of the currently checked out revision.
+#
+# $@ = requested paths (default to all)
+#
+modules_list()
+{
+ git ls-files --stage -- "$@" | grep -e '^160000 ' |
+ while read mode sha1 stage path
+ do
+ if ! test -d "$path"/.git
+ then
+ say "-$sha1 $path"
+ continue;
+ fi
+ revname=$(unset GIT_DIR && cd "$path" && git-describe $sha1)
+ if git diff-files --quiet -- "$path"
+ then
+ say " $sha1 $path ($revname)"
+ else
+ if test -z "$cached"
+ then
+ sha1=$(unset GIT_DIR && cd "$path" && git-rev-parse --verify HEAD)
+ revname=$(unset GIT_DIR && cd "$path" && git-describe $sha1)
+ fi
+ say "+$sha1 $path ($revname)"
+ fi
+ done
+}
+
+while case "$#" in 0) break ;; esac
+do
+ case "$1" in
+ init)
+ init=1
+ ;;
+ update)
+ update=1
+ ;;
+ status)
+ status=1
+ ;;
+ -q|--quiet)
+ quiet=1
+ ;;
+ --cached)
+ cached=1
+ ;;
+ --)
+ break
+ ;;
+ -*)
+ usage
+ ;;
+ *)
+ break
+ ;;
+ esac
+ shift
+done
+
+case "$init,$update,$status,$cached" in
+1,,,)
+ modules_init "$@"
+ ;;
+,1,,)
+ modules_update "$@"
+ ;;
+,,*,*)
+ modules_list "$@"
+ ;;
+*)
+ usage
+ ;;
+esac
diff --git a/git-svnimport.perl b/git-svnimport.perl
index 3af8c7e..f459762 100755
--- a/git-svnimport.perl
+++ b/git-svnimport.perl
@@ -542,7 +542,7 @@ sub copy_path($$$$$$$$) {
if ($node_kind eq $SVN::Node::dir) {
$srcpath =~ s#/*$#/#;
}
-
+
my $pid = open my $f,'-|';
die $! unless defined $pid;
if (!$pid) {
@@ -560,7 +560,7 @@ sub copy_path($$$$$$$$) {
} else {
$p = $path;
}
- push(@$new,[$mode,$sha1,$p]);
+ push(@$new,[$mode,$sha1,$p]);
}
close($f) or
print STDERR "$newrev:$newbranch: could not list files in $oldpath \@ $rev\n";
diff --git a/git-tag.sh b/git-tag.sh
index 6f0b7a7..c840439 100755
--- a/git-tag.sh
+++ b/git-tag.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# Copyright (c) 2005 Linus Torvalds
-USAGE='-l [<pattern>] | [-a | -s | -u <key-id>] [-f | -d | -v] [-m <msg>] <tagname> [<head>]'
+USAGE='[-n [<num>]] -l [<pattern>] | [-a | -s | -u <key-id>] [-f | -d | -v] [-m <msg>] <tagname> [<head>]'
SUBDIRECTORY_OK='Yes'
. git-sh-setup
@@ -13,6 +13,7 @@ message=
username=
list=
verify=
+LINES=0
while case "$#" in 0) break ;; esac
do
case "$1" in
@@ -26,17 +27,44 @@ do
-f)
force=1
;;
- -l)
- case "$#" in
- 1)
- set x . ;;
+ -n)
+ case $2 in
+ -*) LINES=1 # no argument
+ ;;
+ *) shift
+ LINES=$(expr "$1" : '\([0-9]*\)')
+ [ -z "$LINES" ] && LINES=1 # 1 line is default when -n is used
+ ;;
esac
+ ;;
+ -l)
+ list=1
shift
- git rev-parse --symbolic --tags | sort | grep "$@"
- exit $?
+ PATTERN="$1" # select tags by shell pattern, not re
+ git rev-parse --symbolic --tags | sort |
+ while read TAG
+ do
+ case "$TAG" in
+ *$PATTERN*) ;;
+ *) continue ;;
+ esac
+ [ "$LINES" -le 0 ] && { echo "$TAG"; continue ;}
+ OBJTYPE=$(git cat-file -t "$TAG")
+ case $OBJTYPE in
+ tag) ANNOTATION=$(git cat-file tag "$TAG" |
+ sed -e '1,/^$/d' \
+ -e '/^-----BEGIN PGP SIGNATURE-----$/Q' )
+ printf "%-15s %s\n" "$TAG" "$ANNOTATION" |
+ sed -e '2,$s/^/ /' \
+ -e "${LINES}q"
+ ;;
+ *) echo "$TAG"
+ ;;
+ esac
+ done
;;
-m)
- annotate=1
+ annotate=1
shift
message="$1"
if test "$#" = "0"; then
@@ -62,7 +90,7 @@ do
username="$1"
;;
-d)
- shift
+ shift
had_error=0
for tag
do
@@ -97,6 +125,8 @@ do
shift
done
+[ -n "$list" ] && exit 0
+
name="$1"
[ "$name" ] || usage
prev=0000000000000000000000000000000000000000
@@ -150,4 +180,3 @@ if [ "$annotate" ]; then
fi
git update-ref "refs/tags/$name" "$object" "$prev"
-
diff --git a/git-verify-tag.sh b/git-verify-tag.sh
index 8db7dd0..f2d5597 100755
--- a/git-verify-tag.sh
+++ b/git-verify-tag.sh
@@ -42,4 +42,3 @@ cat "$GIT_DIR/.tmp-vtag" |
sed '/-----BEGIN PGP/Q' |
gpg --verify "$GIT_DIR/.tmp-vtag" - || exit 1
rm -f "$GIT_DIR/.tmp-vtag"
-
diff --git a/git.spec.in b/git.spec.in
index 3a45eb8..b9dc1d5 100644
--- a/git.spec.in
+++ b/git.spec.in
@@ -63,7 +63,7 @@ Git tools for importing Perforce repositories.
%package email
Summary: Git tools for sending email
Group: Development/Tools
-Requires: git-core = %{version}-%{release}
+Requires: git-core = %{version}-%{release}
%description email
Git tools for sending email.
diff --git a/gitk b/gitk
index a57e84c..87c3690 100755
--- a/gitk
+++ b/gitk
@@ -337,7 +337,7 @@ proc readrefs {} {
set tagids($name) $commit
lappend idtags($commit) $name
}
- }
+ }
catch {
set tagcontents($name) [exec git cat-file tag $id]
}
diff --git a/gitweb/README b/gitweb/README
index e02e90f..7186ced 100644
--- a/gitweb/README
+++ b/gitweb/README
@@ -79,4 +79,3 @@ Originally written by:
Any comment/question/concern to:
Git mailing list <git@vger.kernel.org>
-
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 5c7011a..e92596c 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -94,6 +94,13 @@ our $default_text_plain_charset = undef;
# (relative to the current git repository)
our $mimetypes_file = undef;
+# assume this charset if line contains non-UTF-8 characters;
+# it should be valid encoding (see Encoding::Supported(3pm) for list),
+# for which encoding all byte sequences are valid, for example
+# 'iso-8859-1' aka 'latin1' (it is decoded without checking, so it
+# could be even 'utf-8' for the old behavior)
+our $fallback_encoding = 'latin1';
+
# You define site-wide feature defaults here; override them with
# $GITWEB_CONFIG as necessary.
our %feature = (
@@ -132,7 +139,7 @@ our %feature = (
# $feature{'snapshot'}{'default'} = [undef];
# To have project specific config enable override in $GITWEB_CONFIG
# $feature{'snapshot'}{'override'} = 1;
- # and in project config gitweb.snapshot = none|gzip|bzip2;
+ # and in project config gitweb.snapshot = none|gzip|bzip2|zip;
'snapshot' => {
'sub' => \&feature_snapshot,
'override' => 0,
@@ -244,6 +251,8 @@ sub feature_snapshot {
return ('x-gzip', 'gz', 'gzip');
} elsif ($val eq 'bzip2') {
return ('x-bzip2', 'bz2', 'bzip2');
+ } elsif ($val eq 'zip') {
+ return ('x-zip', 'zip', '');
} elsif ($val eq 'none') {
return ();
}
@@ -600,6 +609,20 @@ sub validate_refname {
return $input;
}
+# decode sequences of octets in utf8 into Perl's internal form,
+# which is utf-8 with utf8 flag set if needed. gitweb writes out
+# in utf-8 thanks to "binmode STDOUT, ':utf8'" at beginning
+sub to_utf8 {
+ my $str = shift;
+ my $res;
+ eval { $res = decode_utf8($str, Encode::FB_CROAK); };
+ if (defined $res) {
+ return $res;
+ } else {
+ return decode($fallback_encoding, $str, Encode::FB_DEFAULT);
+ }
+}
+
# quote unsafe chars, but keep the slash, even when it's not
# correct, but quoted slashes look too horrible in bookmarks
sub esc_param {
@@ -624,7 +647,7 @@ sub esc_html ($;%) {
my $str = shift;
my %opts = @_;
- $str = decode_utf8($str);
+ $str = to_utf8($str);
$str = $cgi->escapeHTML($str);
if ($opts{'-nbsp'}) {
$str =~ s/ /&nbsp;/g;
@@ -638,7 +661,7 @@ sub esc_path {
my $str = shift;
my %opts = @_;
- $str = decode_utf8($str);
+ $str = to_utf8($str);
$str = $cgi->escapeHTML($str);
if ($opts{'-nbsp'}) {
$str =~ s/ /&nbsp;/g;
@@ -923,7 +946,7 @@ sub format_subject_html {
if (length($short) < length($long)) {
return $cgi->a({-href => $href, -class => "list subject",
- -title => decode_utf8($long)},
+ -title => to_utf8($long)},
esc_html($short) . $extra);
} else {
return $cgi->a({-href => $href, -class => "list subject"},
@@ -1237,7 +1260,7 @@ sub git_get_projects_list {
if (check_export_ok("$projectroot/$path")) {
my $pr = {
path => $path,
- owner => decode_utf8($owner),
+ owner => to_utf8($owner),
};
push @list, $pr;
(my $forks_path = $path) =~ s/\.git$//;
@@ -1267,7 +1290,7 @@ sub git_get_project_owner {
$pr = unescape($pr);
$ow = unescape($ow);
if ($pr eq $project) {
- $owner = decode_utf8($ow);
+ $owner = to_utf8($ow);
last;
}
}
@@ -1757,7 +1780,7 @@ sub get_file_owner {
}
my $owner = $gcos;
$owner =~ s/[,;].*$//;
- return decode_utf8($owner);
+ return to_utf8($owner);
}
## ......................................................................
@@ -1840,7 +1863,7 @@ sub git_header_html {
my $title = "$site_name";
if (defined $project) {
- $title .= " - " . decode_utf8($project);
+ $title .= " - " . to_utf8($project);
if (defined $action) {
$title .= "/$action";
if (defined $file_name) {
@@ -2114,7 +2137,7 @@ sub git_print_page_path {
print "<div class=\"page_path\">";
print $cgi->a({-href => href(action=>"tree", hash_base=>$hb),
- -title => 'tree root'}, decode_utf8("[$project]"));
+ -title => 'tree root'}, to_utf8("[$project]"));
print " / ";
if (defined $name) {
my @dirname = split '/', $name;
@@ -2934,7 +2957,7 @@ sub git_project_list_body {
($pr->{'age'}, $pr->{'age_string'}) = @aa;
if (!defined $pr->{'descr'}) {
my $descr = git_get_project_description($pr->{'path'}) || "";
- $pr->{'descr_long'} = decode_utf8($descr);
+ $pr->{'descr_long'} = to_utf8($descr);
$pr->{'descr'} = chop_str($descr, 25, 5);
}
if (!defined $pr->{'owner'}) {
@@ -3976,19 +3999,26 @@ sub git_snapshot {
$hash = git_get_head_hash($project);
}
- my $filename = decode_utf8(basename($project)) . "-$hash.tar.$suffix";
+ my $git = git_cmd_str();
+ my $name = $project;
+ $name =~ s/\047/\047\\\047\047/g;
+ my $filename = to_utf8(basename($project));
+ my $cmd;
+ if ($suffix eq 'zip') {
+ $filename .= "-$hash.$suffix";
+ $cmd = "$git archive --format=zip --prefix=\'$name\'/ $hash";
+ } else {
+ $filename .= "-$hash.tar.$suffix";
+ $cmd = "$git archive --format=tar --prefix=\'$name\'/ $hash | $command";
+ }
print $cgi->header(
-type => "application/$ctype",
-content_disposition => 'inline; filename="' . "$filename" . '"',
-status => '200 OK');
- my $git = git_cmd_str();
- my $name = $project;
- $name =~ s/\047/\047\\\047\047/g;
- open my $fd, "-|",
- "$git archive --format=tar --prefix=\'$name\'/ $hash | $command"
- or die_error(undef, "Execute git-tar-tree failed");
+ open my $fd, "-|", $cmd
+ or die_error(undef, "Execute git-archive failed");
binmode STDOUT, ':raw';
print <$fd>;
binmode STDOUT, ':utf8'; # as set at the beginning of gitweb.cgi
diff --git a/grep.c b/grep.c
index fcc6762..f67d671 100644
--- a/grep.c
+++ b/grep.c
@@ -1,5 +1,6 @@
#include "cache.h"
#include "grep.h"
+#include "xdiff-interface.h"
void append_grep_pattern(struct grep_opt *opt, const char *pat,
const char *origin, int no, enum grep_pat_token t)
@@ -232,17 +233,6 @@ static void show_line(struct grep_opt *opt, const char *bol, const char *eol,
printf("%.*s\n", (int)(eol-bol), bol);
}
-/*
- * NEEDSWORK: share code with diff.c
- */
-#define FIRST_FEW_BYTES 8000
-static int buffer_is_binary(const char *ptr, unsigned long size)
-{
- if (FIRST_FEW_BYTES < size)
- size = FIRST_FEW_BYTES;
- return !!memchr(ptr, 0, size);
-}
-
static int fixmatch(const char *pattern, char *line, regmatch_t *match)
{
char *hit = strstr(line, pattern);
diff --git a/help.c b/help.c
index 6a9af4d..1cd33ec 100644
--- a/help.c
+++ b/help.c
@@ -219,5 +219,3 @@ int cmd_help(int argc, const char **argv, const char *prefix)
return 0;
}
-
-
diff --git a/http-fetch.c b/http-fetch.c
index 09baedc..202fae0 100644
--- a/http-fetch.c
+++ b/http-fetch.c
@@ -828,7 +828,7 @@ static void abort_object_request(struct object_request *obj_req)
}
unlink(obj_req->tmpfile);
if (obj_req->slot) {
- release_active_slot(obj_req->slot);
+ release_active_slot(obj_req->slot);
obj_req->slot = NULL;
}
release_object_request(obj_req);
diff --git a/http-push.c b/http-push.c
index e3f7675..7c3720f 100644
--- a/http-push.c
+++ b/http-push.c
@@ -9,6 +9,7 @@
#include "diff.h"
#include "revision.h"
#include "exec_cmd.h"
+#include "remote.h"
#include <expat.h>
@@ -517,7 +518,7 @@ static void start_put(struct transfer_request *request)
request->buffer.size = stream.total_out;
request->buffer.posn = 0;
- request->url = xmalloc(strlen(remote->url) +
+ request->url = xmalloc(strlen(remote->url) +
strlen(request->lock->token) + 51);
strcpy(request->url, remote->url);
posn = request->url + strlen(remote->url);
diff --git a/http.c b/http.c
index ae27e0c..c6fb8ac 100644
--- a/http.c
+++ b/http.c
@@ -137,7 +137,7 @@ static int http_options(const char *var, const char *value)
return 0;
}
-#ifdef USE_CURL_MULTI
+#ifdef USE_CURL_MULTI
if (!strcmp("http.maxrequests", var)) {
if (max_requests == -1)
max_requests = git_config_int(var, value);
diff --git a/ident.c b/ident.c
index 69a04b8..3d49608 100644
--- a/ident.c
+++ b/ident.c
@@ -196,9 +196,9 @@ const char *fmt_ident(const char *name, const char *email,
if (!name)
name = git_default_name;
if (!email)
- email = getenv("EMAIL");
- if (!email)
email = git_default_email;
+ if (!email)
+ email = getenv("EMAIL");
if (!*name) {
struct passwd *pw;
diff --git a/imap-send.c b/imap-send.c
index 4283a4a..a5a0696 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -1239,7 +1239,7 @@ split_msg( msg_data_t *all_msgs, msg_data_t *msg, int *ofs )
msg->data[ msg->len ] = 0;
*ofs += msg->len;
- return 1;
+ return 1;
}
static imap_server_conf_t server =
diff --git a/index-pack.c b/index-pack.c
index 58c4a9c..82c8da3 100644
--- a/index-pack.c
+++ b/index-pack.c
@@ -13,13 +13,11 @@ static const char index_pack_usage[] =
struct object_entry
{
- off_t offset;
+ struct pack_idx_entry idx;
unsigned long size;
unsigned int hdr_size;
- uint32_t crc32;
enum object_type type;
enum object_type real_type;
- unsigned char sha1[20];
};
union delta_base {
@@ -197,7 +195,7 @@ static void *unpack_raw_entry(struct object_entry *obj, union delta_base *delta_
unsigned shift;
void *data;
- obj->offset = consumed_bytes;
+ obj->idx.offset = consumed_bytes;
input_crc32 = crc32(0, Z_NULL, 0);
p = fill(1);
@@ -229,15 +227,15 @@ static void *unpack_raw_entry(struct object_entry *obj, union delta_base *delta_
while (c & 128) {
base_offset += 1;
if (!base_offset || MSB(base_offset, 7))
- bad_object(obj->offset, "offset value overflow for delta base object");
+ bad_object(obj->idx.offset, "offset value overflow for delta base object");
p = fill(1);
c = *p;
use(1);
base_offset = (base_offset << 7) + (c & 127);
}
- delta_base->offset = obj->offset - base_offset;
- if (delta_base->offset >= obj->offset)
- bad_object(obj->offset, "delta base offset is out of bound");
+ delta_base->offset = obj->idx.offset - base_offset;
+ if (delta_base->offset >= obj->idx.offset)
+ bad_object(obj->idx.offset, "delta base offset is out of bound");
break;
case OBJ_COMMIT:
case OBJ_TREE:
@@ -245,19 +243,19 @@ static void *unpack_raw_entry(struct object_entry *obj, union delta_base *delta_
case OBJ_TAG:
break;
default:
- bad_object(obj->offset, "unknown object type %d", obj->type);
+ bad_object(obj->idx.offset, "unknown object type %d", obj->type);
}
- obj->hdr_size = consumed_bytes - obj->offset;
+ obj->hdr_size = consumed_bytes - obj->idx.offset;
- data = unpack_entry_data(obj->offset, obj->size);
- obj->crc32 = input_crc32;
+ data = unpack_entry_data(obj->idx.offset, obj->size);
+ obj->idx.crc32 = input_crc32;
return data;
}
static void *get_data_from_pack(struct object_entry *obj)
{
- unsigned long from = obj[0].offset + obj[0].hdr_size;
- unsigned long len = obj[1].offset - from;
+ unsigned long from = obj[0].idx.offset + obj[0].hdr_size;
+ unsigned long len = obj[1].idx.offset - from;
unsigned long rdy = 0;
unsigned char *src, *data;
z_stream stream;
@@ -360,11 +358,11 @@ static void resolve_delta(struct object_entry *delta_obj, void *base_data,
&result_size);
free(delta_data);
if (!result)
- bad_object(delta_obj->offset, "failed to apply delta");
- sha1_object(result, result_size, type, delta_obj->sha1);
+ bad_object(delta_obj->idx.offset, "failed to apply delta");
+ sha1_object(result, result_size, type, delta_obj->idx.sha1);
nr_resolved_deltas++;
- hashcpy(delta_base.sha1, delta_obj->sha1);
+ hashcpy(delta_base.sha1, delta_obj->idx.sha1);
if (!find_delta_children(&delta_base, &first, &last)) {
for (j = first; j <= last; j++) {
struct object_entry *child = objects + deltas[j].obj_no;
@@ -374,7 +372,7 @@ static void resolve_delta(struct object_entry *delta_obj, void *base_data,
}
memset(&delta_base, 0, sizeof(delta_base));
- delta_base.offset = delta_obj->offset;
+ delta_base.offset = delta_obj->idx.offset;
if (!find_delta_children(&delta_base, &first, &last)) {
for (j = first; j <= last; j++) {
struct object_entry *child = objects + deltas[j].obj_no;
@@ -418,12 +416,12 @@ static void parse_pack_objects(unsigned char *sha1)
delta->obj_no = i;
delta++;
} else
- sha1_object(data, obj->size, obj->type, obj->sha1);
+ sha1_object(data, obj->size, obj->type, obj->idx.sha1);
free(data);
if (verbose)
display_progress(&progress, i+1);
}
- objects[i].offset = consumed_bytes;
+ objects[i].idx.offset = consumed_bytes;
if (verbose)
stop_progress(&progress);
@@ -465,10 +463,10 @@ static void parse_pack_objects(unsigned char *sha1)
if (obj->type == OBJ_REF_DELTA || obj->type == OBJ_OFS_DELTA)
continue;
- hashcpy(base.sha1, obj->sha1);
+ hashcpy(base.sha1, obj->idx.sha1);
ref = !find_delta_children(&base, &ref_first, &ref_last);
memset(&base, 0, sizeof(base));
- base.offset = obj->offset;
+ base.offset = obj->idx.offset;
ofs = !find_delta_children(&base, &ofs_first, &ofs_last);
if (!ref && !ofs)
continue;
@@ -535,11 +533,11 @@ static void append_obj_to_pack(const unsigned char *sha1, void *buf,
}
header[n++] = c;
write_or_die(output_fd, header, n);
- obj[0].crc32 = crc32(0, Z_NULL, 0);
- obj[0].crc32 = crc32(obj[0].crc32, header, n);
- obj[1].offset = obj[0].offset + n;
- obj[1].offset += write_compressed(output_fd, buf, size, &obj[0].crc32);
- hashcpy(obj->sha1, sha1);
+ obj[0].idx.crc32 = crc32(0, Z_NULL, 0);
+ obj[0].idx.crc32 = crc32(obj[0].idx.crc32, header, n);
+ obj[1].idx.offset = obj[0].idx.offset + n;
+ obj[1].idx.offset += write_compressed(output_fd, buf, size, &obj[0].idx.crc32);
+ hashcpy(obj->idx.sha1, sha1);
}
static int delta_pos_compare(const void *_a, const void *_b)
@@ -602,145 +600,6 @@ static void fix_unresolved_deltas(int nr_unresolved)
free(sorted_by_pos);
}
-static uint32_t index_default_version = 1;
-static uint32_t index_off32_limit = 0x7fffffff;
-
-static int sha1_compare(const void *_a, const void *_b)
-{
- struct object_entry *a = *(struct object_entry **)_a;
- struct object_entry *b = *(struct object_entry **)_b;
- return hashcmp(a->sha1, b->sha1);
-}
-
-/*
- * On entry *sha1 contains the pack content SHA1 hash, on exit it is
- * the SHA1 hash of sorted object names.
- */
-static const char *write_index_file(const char *index_name, unsigned char *sha1)
-{
- struct sha1file *f;
- struct object_entry **sorted_by_sha, **list, **last;
- uint32_t array[256];
- int i, fd;
- SHA_CTX ctx;
- uint32_t index_version;
-
- if (nr_objects) {
- sorted_by_sha =
- xcalloc(nr_objects, sizeof(struct object_entry *));
- list = sorted_by_sha;
- last = sorted_by_sha + nr_objects;
- for (i = 0; i < nr_objects; ++i)
- sorted_by_sha[i] = &objects[i];
- qsort(sorted_by_sha, nr_objects, sizeof(sorted_by_sha[0]),
- sha1_compare);
- }
- else
- sorted_by_sha = list = last = NULL;
-
- if (!index_name) {
- static char tmpfile[PATH_MAX];
- snprintf(tmpfile, sizeof(tmpfile),
- "%s/tmp_idx_XXXXXX", get_object_directory());
- fd = mkstemp(tmpfile);
- index_name = xstrdup(tmpfile);
- } else {
- unlink(index_name);
- fd = open(index_name, O_CREAT|O_EXCL|O_WRONLY, 0600);
- }
- if (fd < 0)
- die("unable to create %s: %s", index_name, strerror(errno));
- f = sha1fd(fd, index_name);
-
- /* if last object's offset is >= 2^31 we should use index V2 */
- index_version = (objects[nr_objects-1].offset >> 31) ? 2 : index_default_version;
-
- /* 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);
- 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 *obj = *next;
- if (obj->sha1[0] != i)
- break;
- next++;
- }
- 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_objects; i++) {
- struct object_entry *obj = *list++;
- if (index_version < 2) {
- uint32_t offset = htonl(obj->offset);
- sha1write(f, &offset, 4);
- }
- sha1write(f, obj->sha1, 20);
- SHA1_Update(&ctx, obj->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 *obj = *list++;
- uint32_t crc32_val = htonl(obj->crc32);
- sha1write(f, &crc32_val, 4);
- }
-
- /* write the 32-bit offset table */
- list = sorted_by_sha;
- for (i = 0; i < nr_objects; i++) {
- struct object_entry *obj = *list++;
- uint32_t offset = (obj->offset <= index_off32_limit) ?
- obj->offset : (0x80000000 | nr_large_offset++);
- offset = htonl(offset);
- sha1write(f, &offset, 4);
- }
-
- /* write the large offset table */
- list = sorted_by_sha;
- while (nr_large_offset) {
- struct object_entry *obj = *list++;
- uint64_t offset = obj->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--;
- }
- }
- }
-
- sha1write(f, sha1, 20);
- sha1close(f, NULL, 1);
- free(sorted_by_sha);
- SHA1_Final(sha1, &ctx);
- return index_name;
-}
-
static void final(const char *final_pack_name, const char *curr_pack_name,
const char *final_index_name, const char *curr_index_name,
const char *keep_name, const char *keep_msg,
@@ -830,6 +689,7 @@ int main(int argc, char **argv)
const char *curr_index, *index_name = NULL;
const char *keep_name = NULL, *keep_msg = NULL;
char *index_name_buf = NULL, *keep_name_buf = NULL;
+ struct pack_idx_entry **idx_objects;
unsigned char sha1[20];
for (i = 1; i < argc; i++) {
@@ -865,12 +725,12 @@ int main(int argc, char **argv)
index_name = argv[++i];
} else 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);
} else
usage(index_pack_usage);
@@ -940,7 +800,13 @@ int main(int argc, char **argv)
nr_deltas - nr_resolved_deltas);
}
free(deltas);
- curr_index = write_index_file(index_name, sha1);
+
+ idx_objects = xmalloc((nr_objects) * sizeof(struct pack_idx_entry *));
+ for (i = 0; i < nr_objects; i++)
+ idx_objects[i] = &objects[i].idx;
+ curr_index = write_idx_file(index_name, idx_objects, nr_objects, sha1);
+ free(idx_objects);
+
final(pack_name, curr_pack,
index_name, curr_index,
keep_name, keep_msg,
diff --git a/list-objects.c b/list-objects.c
index 310f8d3..e5c88c2 100644
--- a/list-objects.c
+++ b/list-objects.c
@@ -87,7 +87,7 @@ static void process_tree(struct rev_info *revs,
process_tree(revs,
lookup_tree(entry.sha1),
p, &me, entry.path);
- else if (S_ISDIRLNK(entry.mode))
+ else if (S_ISGITLINK(entry.mode))
process_gitlink(revs, entry.sha1,
p, &me, entry.path);
else
diff --git a/local-fetch.c b/local-fetch.c
index 4b650ef..bf7ec6c 100644
--- a/local-fetch.c
+++ b/local-fetch.c
@@ -114,7 +114,7 @@ static int fetch_pack(const unsigned char *sha1)
return -1;
target = find_sha1_pack(sha1, packs);
if (!target)
- return error("Couldn't find %s: not separate or in any pack",
+ return error("Couldn't find %s: not separate or in any pack",
sha1_to_hex(sha1));
if (get_verbosely) {
fprintf(stderr, "Getting pack %s\n",
@@ -122,11 +122,11 @@ static int fetch_pack(const unsigned char *sha1)
fprintf(stderr, " which contains %s\n",
sha1_to_hex(sha1));
}
- sprintf(filename, "%s/objects/pack/pack-%s.pack",
+ sprintf(filename, "%s/objects/pack/pack-%s.pack",
path, sha1_to_hex(target->sha1));
copy_file(filename, sha1_pack_name(target->sha1),
sha1_to_hex(target->sha1), 1);
- sprintf(filename, "%s/objects/pack/pack-%s.idx",
+ sprintf(filename, "%s/objects/pack/pack-%s.idx",
path, sha1_to_hex(target->sha1));
copy_file(filename, sha1_pack_index_name(target->sha1),
sha1_to_hex(target->sha1), 1);
@@ -141,7 +141,7 @@ static int fetch_file(const unsigned char *sha1)
char *hex = sha1_to_hex(sha1);
char *dest_filename = sha1_file_name(sha1);
- if (object_name_start < 0) {
+ if (object_name_start < 0) {
strcpy(filename, path); /* e.g. git.git */
strcat(filename, "/objects/");
object_name_start = strlen(filename);
diff --git a/lockfile.c b/lockfile.c
index 23db35a..5ad2858 100644
--- a/lockfile.c
+++ b/lockfile.c
@@ -97,4 +97,3 @@ void rollback_lock_file(struct lock_file *lk)
unlink(lk->filename);
lk->filename[0] = 0;
}
-
diff --git a/mailmap.c b/mailmap.c
index cb567a2..8714167 100644
--- a/mailmap.c
+++ b/mailmap.c
@@ -89,4 +89,3 @@ int map_email(struct path_list *map, const char *email, char *name, int maxlen)
}
return 0;
}
-
diff --git a/match-trees.c b/match-trees.c
index 23cafe4..d7e29c4 100644
--- a/match-trees.c
+++ b/match-trees.c
@@ -301,4 +301,3 @@ void shift_tree(const unsigned char *hash1,
splice_tree(hash1, add_prefix, hash2, shifted);
}
-
diff --git a/merge-index.c b/merge-index.c
index 5599fd3..fa719cb 100644
--- a/merge-index.c
+++ b/merge-index.c
@@ -25,7 +25,7 @@ static void run_program(void)
static int merge_entry(int pos, const char *path)
{
int found;
-
+
if (pos >= active_nr)
die("git-merge-index: %s not in the cache", path);
arguments[0] = pgm;
diff --git a/merge-recursive.c b/merge-recursive.c
index 8f72b2c..4a82b74 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -680,6 +680,12 @@ static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,
{
xpparam_t xpp;
+ if (buffer_is_binary(orig->ptr, orig->size) ||
+ buffer_is_binary(src1->ptr, src1->size) ||
+ buffer_is_binary(src2->ptr, src2->size))
+ return error("Cannot merge binary files: %s vs. %s\n",
+ name1, name2);
+
memset(&xpp, 0, sizeof(xpp));
return xdl_merge(orig,
src1, name1,
diff --git a/mktag.c b/mktag.c
index 9310111..b82e377 100644
--- a/mktag.c
+++ b/mktag.c
@@ -11,16 +11,9 @@
* The first three lines are guaranteed to be at least 63 bytes:
* "object <sha1>\n" is 48 bytes, "type tag\n" at 9 bytes is the
* shortest possible type-line, and "tag .\n" at 6 bytes is the
- * shortest single-character-tag line.
- *
- * We also artificially limit the size of the full object 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.
+ * shortest single-character-tag line.
*/
-/* Some random size */
-#define MAXSIZE (8192)
-
/*
* We refuse to tag something we can't verify. Just because.
*/
diff --git a/mozilla-sha1/sha1.c b/mozilla-sha1/sha1.c
index 847531d..3f06b83 100644
--- a/mozilla-sha1/sha1.c
+++ b/mozilla-sha1/sha1.c
@@ -1,29 +1,29 @@
-/*
+/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
- *
+ *
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
- *
+ *
* The Original Code is SHA 180-1 Reference Implementation (Compact version)
- *
+ *
* The Initial Developer of the Original Code is Paul Kocher of
- * Cryptography Research. Portions created by Paul Kocher are
+ * Cryptography Research. Portions created by Paul Kocher are
* Copyright (C) 1995-9 by Cryptography Research, Inc. All
* Rights Reserved.
- *
+ *
* Contributor(s):
*
* Paul Kocher
- *
+ *
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
@@ -149,4 +149,3 @@ static void shaHashBlock(SHA_CTX *ctx) {
ctx->H[3] += D;
ctx->H[4] += E;
}
-
diff --git a/mozilla-sha1/sha1.h b/mozilla-sha1/sha1.h
index 5d82afa..16f2d3d 100644
--- a/mozilla-sha1/sha1.h
+++ b/mozilla-sha1/sha1.h
@@ -1,29 +1,29 @@
-/*
+/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
- *
+ *
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
- *
+ *
* The Original Code is SHA 180-1 Header File
- *
+ *
* The Initial Developer of the Original Code is Paul Kocher of
- * Cryptography Research. Portions created by Paul Kocher are
+ * Cryptography Research. Portions created by Paul Kocher are
* Copyright (C) 1995-9 by Cryptography Research, Inc. All
* Rights Reserved.
- *
+ *
* Contributor(s):
*
* Paul Kocher
- *
+ *
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
diff --git a/object-refs.c b/object-refs.c
index 022e8d8..5345671 100644
--- a/object-refs.c
+++ b/object-refs.c
@@ -85,5 +85,3 @@ void mark_reachable(struct object *obj, unsigned int mask)
mark_reachable(refs->ref[i], mask);
}
}
-
-
diff --git a/object.c b/object.c
index cfc4969..16793d9 100644
--- a/object.c
+++ b/object.c
@@ -160,8 +160,11 @@ struct object *parse_object_buffer(const unsigned char *sha1, enum object_type t
parse_tag_buffer(tag, buffer, size);
obj = &tag->object;
} else {
+ warning("object %s has unknown type id %d\n", sha1_to_hex(sha1), type);
obj = NULL;
}
+ if (obj && obj->type == OBJ_NONE)
+ obj->type = type;
*eaten_p = eaten;
return obj;
}
diff --git a/object.h b/object.h
index 94f19ee..397bbfa 100644
--- a/object.h
+++ b/object.h
@@ -66,7 +66,7 @@ void set_object_refs(struct object *obj, struct object_refs *refs);
void mark_reachable(struct object *obj, unsigned int mask);
-struct object_list *object_list_insert(struct object *item,
+struct object_list *object_list_insert(struct object *item,
struct object_list **list_p);
void object_list_append(struct object *item,
diff --git a/pack-check.c b/pack-check.c
index d04536b..d7dd62b 100644
--- a/pack-check.c
+++ b/pack-check.c
@@ -1,6 +1,23 @@
#include "cache.h"
#include "pack.h"
+struct idx_entry
+{
+ const unsigned char *sha1;
+ off_t offset;
+};
+
+static int compare_entries(const void *e1, const void *e2)
+{
+ const struct idx_entry *entry1 = e1;
+ const struct idx_entry *entry2 = e2;
+ if (entry1->offset < entry2->offset)
+ return -1;
+ if (entry1->offset > entry2->offset)
+ return 1;
+ return 0;
+}
+
static int verify_packfile(struct packed_git *p,
struct pack_window **w_curs)
{
@@ -11,6 +28,7 @@ static int verify_packfile(struct packed_git *p,
off_t offset = 0, pack_sig = p->pack_size - 20;
uint32_t nr_objects, i;
int err;
+ struct idx_entry *entries;
/* Note that the pack header checks are actually performed by
* use_pack when it first opens the pack file. If anything
@@ -41,44 +59,48 @@ static int verify_packfile(struct packed_git *p,
* we do not do scan-streaming check on the pack file.
*/
nr_objects = p->num_objects;
+ entries = xmalloc(nr_objects * sizeof(*entries));
+ /* first sort entries by pack offset, since unpacking them is more efficient that way */
+ for (i = 0; i < nr_objects; i++) {
+ entries[i].sha1 = nth_packed_object_sha1(p, i);
+ if (!entries[i].sha1)
+ die("internal error pack-check nth-packed-object");
+ entries[i].offset = find_pack_entry_one(entries[i].sha1, p);
+ if (!entries[i].offset)
+ die("internal error pack-check find-pack-entry-one");
+ }
+ qsort(entries, nr_objects, sizeof(*entries), compare_entries);
+
for (i = 0, err = 0; i < nr_objects; i++) {
- const unsigned char *sha1;
void *data;
enum object_type type;
unsigned long size;
- off_t offset;
- sha1 = nth_packed_object_sha1(p, i);
- if (!sha1)
- die("internal error pack-check nth-packed-object");
- offset = find_pack_entry_one(sha1, p);
- if (!offset)
- die("internal error pack-check find-pack-entry-one");
- data = unpack_entry(p, offset, &type, &size);
+ data = unpack_entry(p, entries[i].offset, &type, &size);
if (!data) {
err = error("cannot unpack %s from %s",
- sha1_to_hex(sha1), p->pack_name);
+ sha1_to_hex(entries[i].sha1), p->pack_name);
continue;
}
- if (check_sha1_signature(sha1, data, size, typename(type))) {
+ if (check_sha1_signature(entries[i].sha1, data, size, typename(type))) {
err = error("packed %s from %s is corrupt",
- sha1_to_hex(sha1), p->pack_name);
+ sha1_to_hex(entries[i].sha1), p->pack_name);
free(data);
continue;
}
free(data);
}
+ free(entries);
return err;
}
-#define MAX_CHAIN 40
+#define MAX_CHAIN 50
static void show_pack_info(struct packed_git *p)
{
- uint32_t nr_objects, i, chain_histogram[MAX_CHAIN];
-
+ uint32_t nr_objects, i, chain_histogram[MAX_CHAIN+1];
nr_objects = p->num_objects;
memset(chain_histogram, 0, sizeof(chain_histogram));
@@ -109,32 +131,37 @@ static void show_pack_info(struct packed_git *p)
printf("%-6s %lu %"PRIuMAX" %u %s\n",
type, size, (uintmax_t)offset,
delta_chain_length, sha1_to_hex(base_sha1));
- if (delta_chain_length < MAX_CHAIN)
+ if (delta_chain_length <= MAX_CHAIN)
chain_histogram[delta_chain_length]++;
else
chain_histogram[0]++;
}
}
- for (i = 0; i < MAX_CHAIN; i++) {
+ for (i = 0; i <= MAX_CHAIN; i++) {
if (!chain_histogram[i])
continue;
- printf("chain length %s %d: %d object%s\n",
- i ? "=" : ">=",
- i ? i : MAX_CHAIN,
- chain_histogram[i],
- 1 < chain_histogram[i] ? "s" : "");
+ printf("chain length = %d: %d object%s\n", i,
+ chain_histogram[i], chain_histogram[i] > 1 ? "s" : "");
}
+ if (chain_histogram[0])
+ printf("chain length > %d: %d object%s\n", MAX_CHAIN,
+ chain_histogram[0], chain_histogram[0] > 1 ? "s" : "");
}
int verify_pack(struct packed_git *p, int verbose)
{
- off_t index_size = p->index_size;
- const unsigned char *index_base = p->index_data;
+ off_t index_size;
+ const unsigned char *index_base;
SHA_CTX ctx;
unsigned char sha1[20];
int ret;
+ if (open_pack_index(p))
+ return error("packfile %s index not opened", p->pack_name);
+ index_size = p->index_size;
+ index_base = p->index_data;
+
ret = 0;
/* Verify SHA1 sum of the index file */
SHA1_Init(&ctx);
diff --git a/pack-redundant.c b/pack-redundant.c
index 87077e1..f5cd0ac 100644
--- a/pack-redundant.c
+++ b/pack-redundant.c
@@ -81,7 +81,7 @@ static struct llist * llist_copy(struct llist *list)
{
struct llist *ret;
struct llist_item *new, *old, *prev;
-
+
llist_init(&ret);
if ((ret->size = list->size) == 0)
@@ -100,7 +100,7 @@ static struct llist * llist_copy(struct llist *list)
}
new->next = NULL;
ret->back = new;
-
+
return ret;
}
@@ -550,6 +550,9 @@ static struct pack_list * add_pack(struct packed_git *p)
l.pack = p;
llist_init(&l.all_objects);
+ if (open_pack_index(p))
+ return NULL;
+
base = p->index_data;
base += 256 * 4 + ((p->index_version < 2) ? 4 : 8);
step = (p->index_version < 2) ? 24 : 20;
diff --git a/pack-write.c b/pack-write.c
index ae2e481..1cf5f7c 100644
--- a/pack-write.c
+++ b/pack-write.c
@@ -1,5 +1,147 @@
#include "cache.h"
#include "pack.h"
+#include "csum-file.h"
+
+uint32_t pack_idx_default_version = 1;
+uint32_t pack_idx_off32_limit = 0x7fffffff;
+
+static int sha1_compare(const void *_a, const void *_b)
+{
+ struct pack_idx_entry *a = *(struct pack_idx_entry **)_a;
+ struct pack_idx_entry *b = *(struct pack_idx_entry **)_b;
+ return hashcmp(a->sha1, b->sha1);
+}
+
+/*
+ * On entry *sha1 contains the pack content SHA1 hash, on exit it is
+ * the SHA1 hash of sorted object names. The objects array passed in
+ * will be sorted by SHA1 on exit.
+ */
+const char *write_idx_file(const char *index_name, struct pack_idx_entry **objects, int nr_objects, unsigned char *sha1)
+{
+ struct sha1file *f;
+ struct pack_idx_entry **sorted_by_sha, **list, **last;
+ off_t last_obj_offset = 0;
+ uint32_t array[256];
+ int i, fd;
+ SHA_CTX ctx;
+ uint32_t index_version;
+
+ if (nr_objects) {
+ sorted_by_sha = objects;
+ list = sorted_by_sha;
+ last = sorted_by_sha + nr_objects;
+ for (i = 0; i < nr_objects; ++i) {
+ if (objects[i]->offset > last_obj_offset)
+ last_obj_offset = objects[i]->offset;
+ }
+ qsort(sorted_by_sha, nr_objects, sizeof(sorted_by_sha[0]),
+ sha1_compare);
+ }
+ else
+ sorted_by_sha = list = last = NULL;
+
+ if (!index_name) {
+ static char tmpfile[PATH_MAX];
+ snprintf(tmpfile, sizeof(tmpfile),
+ "%s/tmp_idx_XXXXXX", get_object_directory());
+ fd = mkstemp(tmpfile);
+ index_name = xstrdup(tmpfile);
+ } else {
+ unlink(index_name);
+ fd = open(index_name, O_CREAT|O_EXCL|O_WRONLY, 0600);
+ }
+ if (fd < 0)
+ die("unable to create %s: %s", index_name, strerror(errno));
+ f = sha1fd(fd, index_name);
+
+ /* if last object's offset is >= 2^31 we should use index V2 */
+ index_version = (last_obj_offset >> 31) ? 2 : pack_idx_default_version;
+
+ /* 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);
+ 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 pack_idx_entry **next = list;
+ while (next < last) {
+ struct pack_idx_entry *obj = *next;
+ if (obj->sha1[0] != i)
+ break;
+ next++;
+ }
+ 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_objects; i++) {
+ struct pack_idx_entry *obj = *list++;
+ if (index_version < 2) {
+ uint32_t offset = htonl(obj->offset);
+ sha1write(f, &offset, 4);
+ }
+ sha1write(f, obj->sha1, 20);
+ SHA1_Update(&ctx, obj->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 pack_idx_entry *obj = *list++;
+ uint32_t crc32_val = htonl(obj->crc32);
+ sha1write(f, &crc32_val, 4);
+ }
+
+ /* write the 32-bit offset table */
+ list = sorted_by_sha;
+ for (i = 0; i < nr_objects; i++) {
+ struct pack_idx_entry *obj = *list++;
+ uint32_t offset = (obj->offset <= pack_idx_off32_limit) ?
+ obj->offset : (0x80000000 | nr_large_offset++);
+ offset = htonl(offset);
+ sha1write(f, &offset, 4);
+ }
+
+ /* write the large offset table */
+ list = sorted_by_sha;
+ while (nr_large_offset) {
+ struct pack_idx_entry *obj = *list++;
+ uint64_t offset = obj->offset;
+ if (offset > pack_idx_off32_limit) {
+ uint32_t split[2];
+ split[0] = htonl(offset >> 32);
+ split[1] = htonl(offset & 0xffffffff);
+ sha1write(f, split, 8);
+ nr_large_offset--;
+ }
+ }
+ }
+
+ sha1write(f, sha1, 20);
+ sha1close(f, NULL, 1);
+ SHA1_Final(sha1, &ctx);
+ return index_name;
+}
void fixup_pack_header_footer(int pack_fd,
unsigned char *pack_file_sha1,
diff --git a/pack.h b/pack.h
index d667fb8..f357c9f 100644
--- a/pack.h
+++ b/pack.h
@@ -34,6 +34,10 @@ struct pack_header {
*/
#define PACK_IDX_SIGNATURE 0xff744f63 /* "\377tOc" */
+/* These may be overridden by command-line parameters */
+extern uint32_t pack_idx_default_version;
+extern uint32_t pack_idx_off32_limit;
+
/*
* Packed object index header
*/
@@ -42,6 +46,16 @@ struct pack_idx_header {
uint32_t idx_version;
};
+/*
+ * Common part of object structure used for write_idx_file
+ */
+struct pack_idx_entry {
+ unsigned char sha1[20];
+ uint32_t crc32;
+ off_t offset;
+};
+
+extern const char *write_idx_file(const char *index_name, struct pack_idx_entry **objects, int nr_objects, unsigned char *sha1);
extern int verify_pack(struct packed_git *, int);
extern void fixup_pack_header_footer(int, unsigned char *, const char *, uint32_t);
diff --git a/patch-id.c b/patch-id.c
index 086d2d9..9349bc5 100644
--- a/patch-id.c
+++ b/patch-id.c
@@ -81,4 +81,4 @@ int main(int argc, char **argv)
generate_id_list();
return 0;
-}
+}
diff --git a/path-list.c b/path-list.c
index caaa5cc..dcb4b3a 100644
--- a/path-list.c
+++ b/path-list.c
@@ -100,4 +100,3 @@ void print_path_list(const char *text, const struct path_list *p)
for (i = 0; i < p->nr; i++)
printf("%s:%p\n", p->items[i].path, p->items[i].util);
}
-
diff --git a/peek-remote.c b/peek-remote.c
index 96bfac4..ceb7871 100644
--- a/peek-remote.c
+++ b/peek-remote.c
@@ -64,7 +64,7 @@ int main(int argc, char **argv)
if (!dest || i != argc - 1)
usage(peek_remote_usage);
- pid = git_connect(fd, dest, uploadpack);
+ pid = git_connect(fd, dest, uploadpack, 0);
if (pid < 0)
return 1;
ret = peek_remote(fd, flags);
diff --git a/perl/Makefile b/perl/Makefile
index 0d695fd..5e079ad 100644
--- a/perl/Makefile
+++ b/perl/Makefile
@@ -40,4 +40,3 @@ endif
# (even though GIT-CFLAGS aren't used yet. If ever)
../GIT-CFLAGS:
$(MAKE) -C .. GIT-CFLAGS
-
diff --git a/pkt-line.c b/pkt-line.c
index b605268..355546a 100644
--- a/pkt-line.c
+++ b/pkt-line.c
@@ -5,7 +5,7 @@
* Write a packetized stream, where each line is preceded by
* its length (including the header) as a 4-byte hex number.
* A length of 'zero' means end of stream (and a length of 1-3
- * would be an error).
+ * would be an error).
*
* This is all pretty stupid, but we use this packetized line
* format to make a streaming format possible without ever
diff --git a/ppc/sha1.c b/ppc/sha1.c
index 0820398..738e36c 100644
--- a/ppc/sha1.c
+++ b/ppc/sha1.c
@@ -50,7 +50,7 @@ int SHA1_Update(SHA_CTX *c, const void *ptr, unsigned long n)
p += nb;
}
return 0;
-}
+}
int SHA1_Final(unsigned char *hash, SHA_CTX *c)
{
diff --git a/progress.c b/progress.c
index 05f7890..4344f4e 100644
--- a/progress.c
+++ b/progress.c
@@ -62,11 +62,13 @@ int display_progress(struct progress *progress, unsigned n)
fprintf(stderr, "%s%4u%% (%u/%u) done\r",
progress->prefix, percent, n, progress->total);
progress_update = 0;
+ progress->need_lf = 1;
return 1;
}
} else if (progress_update) {
fprintf(stderr, "%s%u\r", progress->prefix, n);
progress_update = 0;
+ progress->need_lf = 1;
return 1;
}
return 0;
@@ -80,6 +82,7 @@ void start_progress(struct progress *progress, const char *title,
progress->total = total;
progress->last_percent = -1;
progress->delay = 0;
+ progress->need_lf = 0;
if (snprintf(buf, sizeof(buf), title, total))
fprintf(stderr, "%s\n", buf);
set_progress_signal();
@@ -95,12 +98,13 @@ void start_progress_delay(struct progress *progress, const char *title,
progress->delayed_percent_treshold = percent_treshold;
progress->delayed_title = title;
progress->delay = delay;
+ progress->need_lf = 0;
set_progress_signal();
}
void stop_progress(struct progress *progress)
{
clear_progress_signal();
- if (progress->total)
+ if (progress->need_lf)
fputc('\n', stderr);
}
diff --git a/progress.h b/progress.h
index 5ae1a89..a7c17ca 100644
--- a/progress.h
+++ b/progress.h
@@ -8,6 +8,7 @@ struct progress {
unsigned delay;
unsigned delayed_percent_treshold;
const char *delayed_title;
+ int need_lf;
};
int display_progress(struct progress *progress, unsigned n);
diff --git a/quote.c b/quote.c
index fb9e4ca..aa44009 100644
--- a/quote.c
+++ b/quote.c
@@ -20,7 +20,7 @@ static inline int need_bs_quote(char c)
return (c == '\'' || c == '!');
}
-size_t sq_quote_buf(char *dst, size_t n, const char *src)
+static size_t sq_quote_buf(char *dst, size_t n, const char *src)
{
char c;
char *bp = dst;
@@ -62,18 +62,6 @@ void sq_quote_print(FILE *stream, const char *src)
fputc('\'', stream);
}
-char *sq_quote(const char *src)
-{
- char *buf;
- size_t cnt;
-
- cnt = sq_quote_buf(NULL, 0, src) + 1;
- buf = xmalloc(cnt);
- sq_quote_buf(buf, cnt, src);
-
- return buf;
-}
-
char *sq_quote_argv(const char** argv, int count)
{
char *buf, *to;
diff --git a/quote.h b/quote.h
index bdc3610..8a59cc5 100644
--- a/quote.h
+++ b/quote.h
@@ -28,9 +28,7 @@
* excluding the final null regardless of the buffer size.
*/
-extern char *sq_quote(const char *src);
extern void sq_quote_print(FILE *stream, const char *src);
-extern size_t sq_quote_buf(char *dst, size_t n, const char *src);
extern char *sq_quote_argv(const char** argv, int count);
/*
diff --git a/read-cache.c b/read-cache.c
index d9f46da..4362b11 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -92,7 +92,7 @@ static int ce_compare_gitlink(struct cache_entry *ce)
/*
* We don't actually require that the .git directory
- * under DIRLNK directory be a valid git directory. It
+ * under GITLINK directory be a valid git directory. It
* might even be missing (in case nobody populated that
* sub-project).
*
@@ -115,7 +115,7 @@ static int ce_modified_check_fs(struct cache_entry *ce, struct stat *st)
return DATA_CHANGED;
break;
case S_IFDIR:
- if (S_ISDIRLNK(ntohl(ce->ce_mode)))
+ if (S_ISGITLINK(ntohl(ce->ce_mode)))
return 0;
default:
return TYPE_CHANGED;
@@ -142,7 +142,7 @@ static int ce_match_stat_basic(struct cache_entry *ce, struct stat *st)
(has_symlinks || !S_ISREG(st->st_mode)))
changed |= TYPE_CHANGED;
break;
- case S_IFDIRLNK:
+ case S_IFGITLINK:
if (!S_ISDIR(st->st_mode))
changed |= TYPE_CHANGED;
else if (ce_compare_gitlink(ce))
@@ -166,7 +166,7 @@ static int ce_match_stat_basic(struct cache_entry *ce, struct stat *st)
changed |= MTIME_CHANGED;
if (ce->ce_ctime.nsec != htonl(st->st_ctim.tv_nsec))
changed |= CTIME_CHANGED;
-#endif
+#endif
if (ce->ce_uid != htonl(st->st_uid) ||
ce->ce_gid != htonl(st->st_gid))
@@ -597,7 +597,7 @@ static int has_dir_name(struct index_state *istate,
* is being added, or we already have path and path/file is being
* added. Either one would result in a nonsense tree that has path
* twice when git-write-tree tries to write it out. Prevent it.
- *
+ *
* If ok-to-replace is specified, we remove the conflicting entries
* from the cache so the caller should recompute the insert position.
* When this happens, we return non-zero.
@@ -970,8 +970,8 @@ static int ce_write(SHA_CTX *context, int fd, void *data, unsigned int len)
write_buffer_len = buffered;
len -= partial;
data = (char *) data + partial;
- }
- return 0;
+ }
+ return 0;
}
static int write_index_ext_header(SHA_CTX *context, int fd,
@@ -1037,7 +1037,7 @@ static void ce_smudge_racily_clean_entry(struct cache_entry *ce)
* size to zero here, then the object name recorded
* in index is the 6-byte file but the cached stat information
* becomes zero --- which would then match what we would
- * obtain from the filesystem next time we stat("frotz").
+ * obtain from the filesystem next time we stat("frotz").
*
* However, the second update-index, before calling
* this function, notices that the cached size is 6
diff --git a/receive-pack.c b/receive-pack.c
index 26aa26b..d3c422b 100644
--- a/receive-pack.c
+++ b/receive-pack.c
@@ -209,7 +209,7 @@ static const char *update(struct command *cmd)
return NULL; /* good */
}
else {
- lock = lock_any_ref_for_update(name, old_sha1);
+ lock = lock_any_ref_for_update(name, old_sha1, 0);
if (!lock) {
error("failed to lock %s", name);
return "failed to lock";
diff --git a/refs.c b/refs.c
index 89876bf..ef4484d 100644
--- a/refs.c
+++ b/refs.c
@@ -603,15 +603,20 @@ int get_ref_sha1(const char *ref, unsigned char *sha1)
static inline int bad_ref_char(int ch)
{
- return (((unsigned) ch) <= ' ' ||
- ch == '~' || ch == '^' || ch == ':' ||
- /* 2.13 Pattern Matching Notation */
- ch == '?' || ch == '*' || ch == '[');
+ if (((unsigned) ch) <= ' ' ||
+ ch == '~' || ch == '^' || ch == ':')
+ return 1;
+ /* 2.13 Pattern Matching Notation */
+ if (ch == '?' || ch == '[') /* Unsupported */
+ return 1;
+ if (ch == '*') /* Supported at the end */
+ return 2;
+ return 0;
}
int check_ref_format(const char *ref)
{
- int ch, level;
+ int ch, level, bad_type;
const char *cp = ref;
level = 0;
@@ -622,13 +627,19 @@ int check_ref_format(const char *ref)
return -1; /* should not end with slashes */
/* we are at the beginning of the path component */
- if (ch == '.' || bad_ref_char(ch))
+ if (ch == '.')
return -1;
+ bad_type = bad_ref_char(ch);
+ if (bad_type) {
+ return (bad_type == 2 && !*cp) ? -3 : -1;
+ }
/* scan the rest of the path component */
while ((ch = *cp++) != 0) {
- if (bad_ref_char(ch))
- return -1;
+ bad_type = bad_ref_char(ch);
+ if (bad_type) {
+ return (bad_type == 2 && !*cp) ? -3 : -1;
+ }
if (ch == '/')
break;
if (ch == '.' && *cp == '.')
@@ -736,19 +747,20 @@ static int is_refname_available(const char *ref, const char *oldref,
return 1;
}
-static struct ref_lock *lock_ref_sha1_basic(const char *ref, const unsigned char *old_sha1, int *flag)
+static struct ref_lock *lock_ref_sha1_basic(const char *ref, const unsigned char *old_sha1, int flags, int *type_p)
{
char *ref_file;
const char *orig_ref = ref;
struct ref_lock *lock;
struct stat st;
int last_errno = 0;
+ int type;
int mustexist = (old_sha1 && !is_null_sha1(old_sha1));
lock = xcalloc(1, sizeof(struct ref_lock));
lock->lock_fd = -1;
- ref = resolve_ref(ref, lock->old_sha1, mustexist, flag);
+ ref = resolve_ref(ref, lock->old_sha1, mustexist, &type);
if (!ref && errno == EISDIR) {
/* we are trying to lock foo but we used to
* have foo/bar which now does not exist;
@@ -761,8 +773,10 @@ static struct ref_lock *lock_ref_sha1_basic(const char *ref, const unsigned char
error("there are still refs under '%s'", orig_ref);
goto error_return;
}
- ref = resolve_ref(orig_ref, lock->old_sha1, mustexist, flag);
+ ref = resolve_ref(orig_ref, lock->old_sha1, mustexist, &type);
}
+ if (type_p)
+ *type_p = type;
if (!ref) {
last_errno = errno;
error("unable to resolve reference %s: %s",
@@ -780,10 +794,15 @@ static struct ref_lock *lock_ref_sha1_basic(const char *ref, const unsigned char
lock->lk = xcalloc(1, sizeof(struct lock_file));
+ if (flags & REF_NODEREF)
+ ref = orig_ref;
lock->ref_name = xstrdup(ref);
lock->orig_ref_name = xstrdup(orig_ref);
ref_file = git_path("%s", ref);
- lock->force_write = lstat(ref_file, &st) && errno == ENOENT;
+ if (lstat(ref_file, &st) && errno == ENOENT)
+ lock->force_write = 1;
+ if ((flags & REF_NODEREF) && (type & REF_ISSYMREF))
+ lock->force_write = 1;
if (safe_create_leading_directories(ref_file)) {
last_errno = errno;
@@ -806,14 +825,14 @@ struct ref_lock *lock_ref_sha1(const char *ref, const unsigned char *old_sha1)
if (check_ref_format(ref))
return NULL;
strcpy(refpath, mkpath("refs/%s", ref));
- return lock_ref_sha1_basic(refpath, old_sha1, NULL);
+ return lock_ref_sha1_basic(refpath, old_sha1, 0, NULL);
}
-struct ref_lock *lock_any_ref_for_update(const char *ref, const unsigned char *old_sha1)
+struct ref_lock *lock_any_ref_for_update(const char *ref, const unsigned char *old_sha1, int flags)
{
if (check_ref_format(ref) == -1)
return NULL;
- return lock_ref_sha1_basic(ref, old_sha1, NULL);
+ return lock_ref_sha1_basic(ref, old_sha1, flags, NULL);
}
static struct lock_file packlock;
@@ -858,7 +877,7 @@ int delete_ref(const char *refname, const unsigned char *sha1)
struct ref_lock *lock;
int err, i, ret = 0, flag = 0;
- lock = lock_ref_sha1_basic(refname, sha1, &flag);
+ lock = lock_ref_sha1_basic(refname, sha1, 0, &flag);
if (!lock)
return 1;
if (!(flag & REF_ISPACKED)) {
@@ -909,7 +928,7 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)
if (!is_refname_available(newref, oldref, get_loose_refs(), 0))
return 1;
- lock = lock_ref_sha1_basic(renamed_ref, NULL, NULL);
+ lock = lock_ref_sha1_basic(renamed_ref, NULL, 0, NULL);
if (!lock)
return error("unable to lock %s", renamed_ref);
lock->force_write = 1;
@@ -963,7 +982,7 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)
}
logmoved = log;
- lock = lock_ref_sha1_basic(newref, NULL, NULL);
+ lock = lock_ref_sha1_basic(newref, NULL, 0, NULL);
if (!lock) {
error("unable to lock %s for update", newref);
goto rollback;
@@ -979,7 +998,7 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)
return 0;
rollback:
- lock = lock_ref_sha1_basic(oldref, NULL, NULL);
+ lock = lock_ref_sha1_basic(oldref, NULL, 0, NULL);
if (!lock) {
error("unable to lock %s for rollback", oldref);
goto rollbacklog;
diff --git a/refs.h b/refs.h
index f61f6d9..f234eb7 100644
--- a/refs.h
+++ b/refs.h
@@ -33,7 +33,8 @@ extern int get_ref_sha1(const char *ref, unsigned char *sha1);
extern struct ref_lock *lock_ref_sha1(const char *ref, const unsigned char *old_sha1);
/** Locks any ref (for 'HEAD' type refs). */
-extern struct ref_lock *lock_any_ref_for_update(const char *ref, const unsigned char *old_sha1);
+#define REF_NODEREF 0x01
+extern struct ref_lock *lock_any_ref_for_update(const char *ref, const unsigned char *old_sha1, int flags);
/** Release any lock taken but not written. **/
extern void unlock_ref(struct ref_lock *lock);
diff --git a/remote.c b/remote.c
new file mode 100644
index 0000000..33c8e50
--- /dev/null
+++ b/remote.c
@@ -0,0 +1,568 @@
+#include "cache.h"
+#include "remote.h"
+#include "refs.h"
+
+static struct remote **remotes;
+static int allocated_remotes;
+
+#define BUF_SIZE (2048)
+static char buffer[BUF_SIZE];
+
+static void add_push_refspec(struct remote *remote, const char *ref)
+{
+ int nr = remote->push_refspec_nr + 1;
+ remote->push_refspec =
+ xrealloc(remote->push_refspec, nr * sizeof(char *));
+ remote->push_refspec[nr-1] = ref;
+ remote->push_refspec_nr = nr;
+}
+
+static void add_fetch_refspec(struct remote *remote, const char *ref)
+{
+ int nr = remote->fetch_refspec_nr + 1;
+ remote->fetch_refspec =
+ xrealloc(remote->fetch_refspec, nr * sizeof(char *));
+ remote->fetch_refspec[nr-1] = ref;
+ remote->fetch_refspec_nr = nr;
+}
+
+static void add_uri(struct remote *remote, const char *uri)
+{
+ int nr = remote->uri_nr + 1;
+ remote->uri =
+ xrealloc(remote->uri, nr * sizeof(char *));
+ remote->uri[nr-1] = uri;
+ remote->uri_nr = nr;
+}
+
+static struct remote *make_remote(const char *name, int len)
+{
+ int i, empty = -1;
+
+ for (i = 0; i < allocated_remotes; i++) {
+ if (!remotes[i]) {
+ if (empty < 0)
+ empty = i;
+ } else {
+ if (len ? (!strncmp(name, remotes[i]->name, len) &&
+ !remotes[i]->name[len]) :
+ !strcmp(name, remotes[i]->name))
+ return remotes[i];
+ }
+ }
+
+ if (empty < 0) {
+ empty = allocated_remotes;
+ allocated_remotes += allocated_remotes ? allocated_remotes : 1;
+ remotes = xrealloc(remotes,
+ sizeof(*remotes) * allocated_remotes);
+ memset(remotes + empty, 0,
+ (allocated_remotes - empty) * sizeof(*remotes));
+ }
+ remotes[empty] = xcalloc(1, sizeof(struct remote));
+ if (len)
+ remotes[empty]->name = xstrndup(name, len);
+ else
+ remotes[empty]->name = xstrdup(name);
+ return remotes[empty];
+}
+
+static void read_remotes_file(struct remote *remote)
+{
+ FILE *f = fopen(git_path("remotes/%s", remote->name), "r");
+
+ if (!f)
+ return;
+ while (fgets(buffer, BUF_SIZE, f)) {
+ int value_list;
+ char *s, *p;
+
+ if (!prefixcmp(buffer, "URL:")) {
+ value_list = 0;
+ s = buffer + 4;
+ } else if (!prefixcmp(buffer, "Push:")) {
+ value_list = 1;
+ s = buffer + 5;
+ } else if (!prefixcmp(buffer, "Pull:")) {
+ value_list = 2;
+ s = buffer + 5;
+ } else
+ continue;
+
+ while (isspace(*s))
+ s++;
+ if (!*s)
+ continue;
+
+ p = s + strlen(s);
+ while (isspace(p[-1]))
+ *--p = 0;
+
+ switch (value_list) {
+ case 0:
+ add_uri(remote, xstrdup(s));
+ break;
+ case 1:
+ add_push_refspec(remote, xstrdup(s));
+ break;
+ case 2:
+ add_fetch_refspec(remote, xstrdup(s));
+ break;
+ }
+ }
+ fclose(f);
+}
+
+static void read_branches_file(struct remote *remote)
+{
+ const char *slash = strchr(remote->name, '/');
+ int n = slash ? slash - remote->name : 1000;
+ FILE *f = fopen(git_path("branches/%.*s", n, remote->name), "r");
+ char *s, *p;
+ int len;
+
+ if (!f)
+ return;
+ s = fgets(buffer, BUF_SIZE, f);
+ fclose(f);
+ if (!s)
+ return;
+ while (isspace(*s))
+ s++;
+ if (!*s)
+ return;
+ 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);
+ add_uri(remote, p);
+}
+
+static char *default_remote_name = NULL;
+static const char *current_branch = NULL;
+static int current_branch_len = 0;
+
+static int handle_config(const char *key, const char *value)
+{
+ const char *name;
+ const char *subkey;
+ struct remote *remote;
+ if (!prefixcmp(key, "branch.") && current_branch &&
+ !strncmp(key + 7, current_branch, current_branch_len) &&
+ !strcmp(key + 7 + current_branch_len, ".remote")) {
+ free(default_remote_name);
+ default_remote_name = xstrdup(value);
+ }
+ if (prefixcmp(key, "remote."))
+ return 0;
+ name = key + 7;
+ subkey = strrchr(name, '.');
+ if (!subkey)
+ return error("Config with no key for remote %s", name);
+ if (*subkey == '/') {
+ warning("Config remote shorthand cannot begin with '/': %s", name);
+ return 0;
+ }
+ remote = make_remote(name, subkey - name);
+ if (!value) {
+ /* if we ever have a boolean variable, e.g. "remote.*.disabled"
+ * [remote "frotz"]
+ * disabled
+ * is a valid way to set it to true; we get NULL in value so
+ * we need to handle it here.
+ *
+ * if (!strcmp(subkey, ".disabled")) {
+ * val = git_config_bool(key, value);
+ * return 0;
+ * } else
+ *
+ */
+ return 0; /* ignore unknown booleans */
+ }
+ if (!strcmp(subkey, ".url")) {
+ add_uri(remote, xstrdup(value));
+ } else if (!strcmp(subkey, ".push")) {
+ add_push_refspec(remote, xstrdup(value));
+ } else if (!strcmp(subkey, ".fetch")) {
+ add_fetch_refspec(remote, xstrdup(value));
+ } else if (!strcmp(subkey, ".receivepack")) {
+ if (!remote->receivepack)
+ remote->receivepack = xstrdup(value);
+ else
+ error("more than one receivepack given, using the first");
+ }
+ return 0;
+}
+
+static void read_config(void)
+{
+ unsigned char sha1[20];
+ const char *head_ref;
+ int flag;
+ if (default_remote_name) // did this already
+ return;
+ default_remote_name = xstrdup("origin");
+ current_branch = NULL;
+ head_ref = resolve_ref("HEAD", sha1, 0, &flag);
+ if (head_ref && (flag & REF_ISSYMREF) &&
+ !prefixcmp(head_ref, "refs/heads/")) {
+ current_branch = head_ref + strlen("refs/heads/");
+ current_branch_len = strlen(current_branch);
+ }
+ git_config(handle_config);
+}
+
+static struct refspec *parse_ref_spec(int nr_refspec, const char **refspec)
+{
+ int i;
+ struct refspec *rs = xcalloc(sizeof(*rs), nr_refspec);
+ for (i = 0; i < nr_refspec; i++) {
+ const char *sp, *ep, *gp;
+ sp = refspec[i];
+ if (*sp == '+') {
+ rs[i].force = 1;
+ sp++;
+ }
+ gp = strchr(sp, '*');
+ ep = strchr(sp, ':');
+ if (gp && ep && gp > ep)
+ gp = NULL;
+ if (ep) {
+ if (ep[1]) {
+ const char *glob = strchr(ep + 1, '*');
+ if (!glob)
+ gp = NULL;
+ if (gp)
+ rs[i].dst = xstrndup(ep + 1,
+ glob - ep - 1);
+ else
+ rs[i].dst = xstrdup(ep + 1);
+ }
+ } else {
+ ep = sp + strlen(sp);
+ }
+ if (gp) {
+ rs[i].pattern = 1;
+ ep = gp;
+ }
+ rs[i].src = xstrndup(sp, ep - sp);
+ }
+ return rs;
+}
+
+struct remote *remote_get(const char *name)
+{
+ struct remote *ret;
+
+ read_config();
+ if (!name)
+ name = default_remote_name;
+ ret = make_remote(name, 0);
+ if (name[0] != '/') {
+ if (!ret->uri)
+ read_remotes_file(ret);
+ if (!ret->uri)
+ read_branches_file(ret);
+ }
+ if (!ret->uri)
+ add_uri(ret, name);
+ if (!ret->uri)
+ return NULL;
+ ret->fetch = parse_ref_spec(ret->fetch_refspec_nr, ret->fetch_refspec);
+ ret->push = parse_ref_spec(ret->push_refspec_nr, ret->push_refspec);
+ return ret;
+}
+
+int remote_has_uri(struct remote *remote, const char *uri)
+{
+ int i;
+ for (i = 0; i < remote->uri_nr; i++) {
+ if (!strcmp(remote->uri[i], uri))
+ return 1;
+ }
+ return 0;
+}
+
+int remote_find_tracking(struct remote *remote, struct refspec *refspec)
+{
+ int i;
+ for (i = 0; i < remote->fetch_refspec_nr; i++) {
+ struct refspec *fetch = &remote->fetch[i];
+ if (!fetch->dst)
+ continue;
+ if (fetch->pattern) {
+ if (!prefixcmp(refspec->src, fetch->src)) {
+ refspec->dst =
+ xmalloc(strlen(fetch->dst) +
+ strlen(refspec->src) -
+ strlen(fetch->src) + 1);
+ strcpy(refspec->dst, fetch->dst);
+ strcpy(refspec->dst + strlen(fetch->dst),
+ refspec->src + strlen(fetch->src));
+ refspec->force = fetch->force;
+ return 0;
+ }
+ } else {
+ if (!strcmp(refspec->src, fetch->src)) {
+ refspec->dst = xstrdup(fetch->dst);
+ refspec->force = fetch->force;
+ return 0;
+ }
+ }
+ }
+ refspec->dst = NULL;
+ return -1;
+}
+
+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 rs_nr)
+{
+ int i, errs;
+ for (i = errs = 0; i < rs_nr; i++) {
+ struct ref *matched_src, *matched_dst;
+
+ const char *dst_value = rs[i].dst;
+
+ if (rs[i].pattern)
+ continue;
+
+ if (dst_value == NULL)
+ dst_value = rs[i].src;
+
+ 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(dst_value, dst, &matched_dst)) {
+ case 1:
+ break;
+ case 0:
+ if (!memcmp(dst_value, "refs/", 5)) {
+ int len = strlen(dst_value) + 1;
+ matched_dst = xcalloc(1, sizeof(*dst) + len);
+ memcpy(matched_dst->name, dst_value, len);
+ link_dst_tail(matched_dst, dst_tail);
+ }
+ else if (!strcmp(rs[i].src, dst_value) &&
+ 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/.", dst_value);
+ }
+ break;
+ default:
+ errs = 1;
+ error("dst refspec %s matches more than one.",
+ dst_value);
+ 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;
+}
+
+static const struct refspec *check_pattern_match(const struct refspec *rs,
+ int rs_nr,
+ const struct ref *src)
+{
+ int i;
+ for (i = 0; i < rs_nr; i++) {
+ if (rs[i].pattern && !prefixcmp(src->name, rs[i].src))
+ return rs + i;
+ }
+ 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, (const char **) refspec);
+
+ if (match_explicit_refs(src, dst, dst_tail, rs, nr_refspec))
+ return -1;
+
+ /* pick the remainder */
+ for ( ; src; src = src->next) {
+ struct ref *dst_peer;
+ const struct refspec *pat = NULL;
+ char *dst_name;
+ if (src->peer_ref)
+ continue;
+ if (nr_refspec) {
+ pat = check_pattern_match(rs, nr_refspec, src);
+ if (!pat)
+ continue;
+ }
+
+ if (pat) {
+ dst_name = xmalloc(strlen(pat->dst) +
+ strlen(src->name) -
+ strlen(pat->src) + 2);
+ strcpy(dst_name, pat->dst);
+ strcat(dst_name, src->name + strlen(pat->src));
+ } else
+ dst_name = strdup(src->name);
+ dst_peer = find_ref_by_name(dst, dst_name);
+ if (dst_peer && dst_peer->peer_ref)
+ /* We're already sending something to this ref. */
+ goto free_name;
+ if (!dst_peer && !nr_refspec && !all)
+ /* Remote doesn't have it, and we have no
+ * explicit pattern, and we don't have
+ * --all. */
+ goto free_name;
+ if (!dst_peer) {
+ /* Create a new one and link it */
+ int len = strlen(dst_name) + 1;
+ dst_peer = xcalloc(1, sizeof(*dst_peer) + len);
+ memcpy(dst_peer->name, dst_name, len);
+ hashcpy(dst_peer->new_sha1, src->new_sha1);
+ link_dst_tail(dst_peer, dst_tail);
+ }
+ dst_peer->peer_ref = src;
+ free_name:
+ free(dst_name);
+ }
+ return 0;
+}
diff --git a/remote.h b/remote.h
new file mode 100644
index 0000000..01dbcef
--- /dev/null
+++ b/remote.h
@@ -0,0 +1,41 @@
+#ifndef REMOTE_H
+#define REMOTE_H
+
+struct remote {
+ const char *name;
+
+ const char **uri;
+ int uri_nr;
+
+ const char **push_refspec;
+ struct refspec *push;
+ int push_refspec_nr;
+
+ const char **fetch_refspec;
+ struct refspec *fetch;
+ int fetch_refspec_nr;
+
+ const char *receivepack;
+};
+
+struct remote *remote_get(const char *name);
+
+int remote_has_uri(struct remote *remote, const char *uri);
+
+struct refspec {
+ unsigned force : 1;
+ unsigned pattern : 1;
+
+ const char *src;
+ char *dst;
+};
+
+int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
+ int nr_refspec, char **refspec, int all);
+
+/*
+ * For the given remote, reads the refspec's src and sets the other fields.
+ */
+int remote_find_tracking(struct remote *remote, struct refspec *refspec);
+
+#endif
diff --git a/revision.c b/revision.c
index 0125d41..b12c25e 100644
--- a/revision.c
+++ b/revision.c
@@ -114,12 +114,7 @@ void mark_parents_uninteresting(struct commit *commit)
}
}
-void add_pending_object(struct rev_info *revs, struct object *obj, const char *name)
-{
- add_pending_object_with_mode(revs, obj, name, S_IFINVALID);
-}
-
-void add_pending_object_with_mode(struct rev_info *revs, struct object *obj, const char *name, unsigned mode)
+static void add_pending_object_with_mode(struct rev_info *revs, struct object *obj, const char *name, unsigned mode)
{
if (revs->no_walk && (obj->flags & UNINTERESTING))
die("object ranges do not make sense when not walking revisions");
@@ -129,6 +124,11 @@ void add_pending_object_with_mode(struct rev_info *revs, struct object *obj, con
(struct commit *)obj, name);
}
+void add_pending_object(struct rev_info *revs, struct object *obj, const char *name)
+{
+ add_pending_object_with_mode(revs, obj, name, S_IFINVALID);
+}
+
static struct object *get_reference(struct rev_info *revs, const char *name, const unsigned char *sha1, unsigned int flags)
{
struct object *object;
@@ -262,7 +262,7 @@ static void file_change(struct diff_options *options,
options->has_changes = 1;
}
-int rev_compare_tree(struct rev_info *revs, struct tree *t1, struct tree *t2)
+static int rev_compare_tree(struct rev_info *revs, struct tree *t1, struct tree *t2)
{
if (!t1)
return REV_TREE_NEW;
@@ -276,7 +276,7 @@ int rev_compare_tree(struct rev_info *revs, struct tree *t1, struct tree *t2)
return tree_difference;
}
-int rev_same_tree_as_empty(struct rev_info *revs, struct tree *t1)
+static int rev_same_tree_as_empty(struct rev_info *revs, struct tree *t1)
{
int retval;
void *tree;
@@ -881,6 +881,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
const char **unrecognized = argv + 1;
int left = 1;
int all_match = 0;
+ int regflags = 0;
/* First, search for "--" */
seen_dashdash = 0;
@@ -1152,6 +1153,14 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
add_message_grep(revs, arg+7);
continue;
}
+ if (!prefixcmp(arg, "--extended-regexp")) {
+ regflags |= REG_EXTENDED;
+ continue;
+ }
+ if (!prefixcmp(arg, "--regexp-ignore-case")) {
+ regflags |= REG_ICASE;
+ continue;
+ }
if (!strcmp(arg, "--all-match")) {
all_match = 1;
continue;
@@ -1200,6 +1209,9 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
}
}
+ if (revs->grep_filter)
+ revs->grep_filter->regflags |= regflags;
+
if (show_merge)
prepare_show_merge(revs);
if (def && !revs->pending.nr) {
diff --git a/revision.h b/revision.h
index 2845167..f46b4d5 100644
--- a/revision.h
+++ b/revision.h
@@ -106,8 +106,6 @@ struct rev_info {
#define REV_TREE_DIFFERENT 2
/* revision.c */
-extern int rev_same_tree_as_empty(struct rev_info *, struct tree *t1);
-extern int rev_compare_tree(struct rev_info *, struct tree *t1, struct tree *t2);
extern void init_revisions(struct rev_info *revs, const char *prefix);
extern int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def);
@@ -131,6 +129,5 @@ extern void add_object(struct object *obj,
const char *name);
extern void add_pending_object(struct rev_info *revs, struct object *obj, const char *name);
-extern void add_pending_object_with_mode(struct rev_info *revs, struct object *obj, const char *name, unsigned mode);
#endif
diff --git a/rsh.h b/rsh.h
index 3b41942..ee2f499 100644
--- a/rsh.h
+++ b/rsh.h
@@ -1,7 +1,7 @@
#ifndef RSH_H
#define RSH_H
-int setup_connection(int *fd_in, int *fd_out, const char *remote_prog,
+int setup_connection(int *fd_in, int *fd_out, const char *remote_prog,
char *url, int rmt_argc, char **rmt_argv);
#endif
diff --git a/run-command.c b/run-command.c
index eff523e..7e779d3 100644
--- a/run-command.c
+++ b/run-command.c
@@ -73,6 +73,17 @@ int start_command(struct child_process *cmd)
close(cmd->out);
}
+ if (cmd->dir && chdir(cmd->dir))
+ die("exec %s: cd to %s failed (%s)", cmd->argv[0],
+ cmd->dir, strerror(errno));
+ if (cmd->env) {
+ for (; *cmd->env; cmd->env++) {
+ if (strchr(*cmd->env, '='))
+ putenv((char*)*cmd->env);
+ else
+ unsetenv(*cmd->env);
+ }
+ }
if (cmd->git_cmd) {
execv_git_cmd(cmd->argv);
} else {
@@ -133,13 +144,37 @@ int run_command(struct child_process *cmd)
return finish_command(cmd);
}
+static void prepare_run_command_v_opt(struct child_process *cmd,
+ const char **argv,
+ int opt)
+{
+ memset(cmd, 0, sizeof(*cmd));
+ cmd->argv = argv;
+ cmd->no_stdin = opt & RUN_COMMAND_NO_STDIN ? 1 : 0;
+ cmd->git_cmd = opt & RUN_GIT_CMD ? 1 : 0;
+ cmd->stdout_to_stderr = opt & RUN_COMMAND_STDOUT_TO_STDERR ? 1 : 0;
+}
+
int run_command_v_opt(const char **argv, int opt)
{
struct child_process cmd;
- memset(&cmd, 0, sizeof(cmd));
- cmd.argv = argv;
- cmd.no_stdin = opt & RUN_COMMAND_NO_STDIN ? 1 : 0;
- cmd.git_cmd = opt & RUN_GIT_CMD ? 1 : 0;
- cmd.stdout_to_stderr = opt & RUN_COMMAND_STDOUT_TO_STDERR ? 1 : 0;
+ prepare_run_command_v_opt(&cmd, argv, opt);
+ return run_command(&cmd);
+}
+
+int run_command_v_opt_cd(const char **argv, int opt, const char *dir)
+{
+ struct child_process cmd;
+ prepare_run_command_v_opt(&cmd, argv, opt);
+ cmd.dir = dir;
+ return run_command(&cmd);
+}
+
+int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const char *const *env)
+{
+ struct child_process cmd;
+ prepare_run_command_v_opt(&cmd, argv, opt);
+ cmd.dir = dir;
+ cmd.env = env;
return run_command(&cmd);
}
diff --git a/run-command.h b/run-command.h
index 3680ef9..7958eb1 100644
--- a/run-command.h
+++ b/run-command.h
@@ -16,6 +16,8 @@ struct child_process {
pid_t pid;
int in;
int out;
+ const char *dir;
+ const char *const *env;
unsigned close_in:1;
unsigned close_out:1;
unsigned no_stdin:1;
@@ -32,5 +34,12 @@ int run_command(struct child_process *);
#define RUN_GIT_CMD 2 /*If this is to be git sub-command */
#define RUN_COMMAND_STDOUT_TO_STDERR 4
int run_command_v_opt(const char **argv, int opt);
+int run_command_v_opt_cd(const char **argv, int opt, const char *dir);
+
+/*
+ * env (the environment) is to be formatted like environ: "VAR=VALUE".
+ * To unset an environment variable use just "VAR".
+ */
+int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const char *const *env);
#endif
diff --git a/send-pack.c b/send-pack.c
index d5b5162..fecbda9 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -4,6 +4,7 @@
#include "refs.h"
#include "pkt-line.h"
#include "run-command.h"
+#include "remote.h"
static const char send_pack_usage[] =
"git-send-pack [--all] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [<host>:]<directory> [<ref>...]\n"
@@ -176,7 +177,7 @@ static int receive_status(int in)
return ret;
}
-static int send_pack(int in, int out, int nr_refspec, char **refspec)
+static int send_pack(int in, int out, struct remote *remote, int nr_refspec, char **refspec)
{
struct ref *ref;
int new_refs;
@@ -213,18 +214,19 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
new_refs = 0;
for (ref = remote_refs; ref; ref = ref->next) {
char old_hex[60], *new_hex;
- int delete_ref;
+ int will_delete_ref;
if (!ref->peer_ref)
continue;
- delete_ref = is_null_sha1(ref->peer_ref->new_sha1);
- if (delete_ref && !allow_deleting_refs) {
+
+ will_delete_ref = is_null_sha1(ref->peer_ref->new_sha1);
+ if (will_delete_ref && !allow_deleting_refs) {
error("remote does not support deleting refs");
ret = -2;
continue;
}
- if (!delete_ref &&
+ if (!will_delete_ref &&
!hashcmp(ref->old_sha1, ref->peer_ref->new_sha1)) {
if (verbose)
fprintf(stderr, "'%s': up-to-date\n", ref->name);
@@ -251,7 +253,7 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
*/
if (!force_update &&
- !delete_ref &&
+ !will_delete_ref &&
!is_null_sha1(ref->old_sha1) &&
!ref->force) {
if (!has_sha1_file(ref->old_sha1) ||
@@ -275,7 +277,7 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
}
}
hashcpy(ref->new_sha1, ref->peer_ref->new_sha1);
- if (!delete_ref)
+ if (!will_delete_ref)
new_refs++;
strcpy(old_hex, sha1_to_hex(ref->old_sha1));
new_hex = sha1_to_hex(ref->new_sha1);
@@ -290,7 +292,7 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
else
packet_write(out, "%s %s %s",
old_hex, new_hex, ref->name);
- if (delete_ref)
+ if (will_delete_ref)
fprintf(stderr, "deleting '%s'\n", ref->name);
else {
fprintf(stderr, "updating '%s'", ref->name);
@@ -300,6 +302,28 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
fprintf(stderr, "\n from %s\n to %s\n",
old_hex, new_hex);
}
+ if (remote) {
+ struct refspec rs;
+ rs.src = ref->name;
+ remote_find_tracking(remote, &rs);
+ if (rs.dst) {
+ struct ref_lock *lock;
+ fprintf(stderr, " Also local %s\n", rs.dst);
+ if (will_delete_ref) {
+ if (delete_ref(rs.dst, NULL)) {
+ error("Failed to delete");
+ }
+ } else {
+ lock = lock_any_ref_for_update(rs.dst, NULL, 0);
+ if (!lock)
+ error("Failed to lock");
+ else
+ write_ref_sha1(lock, ref->new_sha1,
+ "update by push");
+ }
+ free(rs.dst);
+ }
+ }
}
packet_flush(out);
@@ -330,6 +354,7 @@ static void verify_remote_names(int nr_heads, char **heads)
case -2: /* ok but a single level -- that is fine for
* a match pattern.
*/
+ case -3: /* ok but ends with a pattern-match character */
continue;
}
die("remote part of refspec is not a valid name in %s",
@@ -344,6 +369,8 @@ int main(int argc, char **argv)
char **heads = NULL;
int fd[2], ret;
pid_t pid;
+ char *remote_name = NULL;
+ struct remote *remote = NULL;
setup_git_directory();
git_config(git_default_config);
@@ -361,6 +388,10 @@ int main(int argc, char **argv)
receivepack = arg + 7;
continue;
}
+ if (!prefixcmp(arg, "--remote=")) {
+ remote_name = arg + 9;
+ continue;
+ }
if (!strcmp(arg, "--all")) {
send_all = 1;
continue;
@@ -393,10 +424,18 @@ int main(int argc, char **argv)
usage(send_pack_usage);
verify_remote_names(nr_heads, heads);
- pid = git_connect(fd, dest, receivepack);
+ if (remote_name) {
+ remote = remote_get(remote_name);
+ if (!remote_has_uri(remote, dest)) {
+ die("Destination %s is not a uri for %s",
+ dest, remote_name);
+ }
+ }
+
+ pid = git_connect(fd, dest, receivepack, verbose ? CONNECT_VERBOSE : 0);
if (pid < 0)
return 1;
- ret = send_pack(fd[0], fd[1], nr_heads, heads);
+ ret = send_pack(fd[0], fd[1], remote, nr_heads, heads);
close(fd[0]);
close(fd[1]);
ret |= finish_connect(pid);
diff --git a/setup.c b/setup.c
index a45ea83..14f62c4 100644
--- a/setup.c
+++ b/setup.c
@@ -39,7 +39,7 @@ const char *prefix_path(const char *prefix, int len, const char *path)
if (len) {
int speclen = strlen(path);
char *n = xmalloc(speclen + len + 1);
-
+
memcpy(n, prefix, len);
memcpy(n + len, path, speclen+1);
path = n;
@@ -47,7 +47,7 @@ const char *prefix_path(const char *prefix, int len, const char *path)
return path;
}
-/*
+/*
* Unlike prefix_path, this should be used if the named file does
* not have to interact with index entry; i.e. name of a random file
* on the filesystem.
diff --git a/sha1_file.c b/sha1_file.c
index c2f807f..2b86086 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -193,7 +193,7 @@ char *sha1_pack_name(const unsigned char *sha1)
*buf++ = hex[val >> 4];
*buf++ = hex[val & 0xf];
}
-
+
return base;
}
@@ -218,7 +218,7 @@ char *sha1_pack_index_name(const unsigned char *sha1)
*buf++ = hex[val >> 4];
*buf++ = hex[val & 0xf];
}
-
+
return base;
}
@@ -376,11 +376,12 @@ void prepare_alt_odb(void)
{
const char *alt;
+ if (alt_odb_tail)
+ return;
+
alt = getenv(ALTERNATE_DB_ENVIRONMENT);
if (!alt) alt = "";
- if (alt_odb_tail)
- return;
alt_odb_tail = &alt_odb_list;
link_alt_odb_entries(alt, alt + strlen(alt), ':', NULL, 0);
@@ -530,6 +531,21 @@ static int check_packed_git_idx(const char *path, struct packed_git *p)
return 0;
}
+int open_pack_index(struct packed_git *p)
+{
+ char *idx_name;
+ int ret;
+
+ if (p->index_data)
+ return 0;
+
+ idx_name = xstrdup(p->pack_name);
+ strcpy(idx_name + strlen(idx_name) - strlen(".pack"), ".idx");
+ ret = check_packed_git_idx(idx_name, p);
+ free(idx_name);
+ return ret;
+}
+
static void scan_windows(struct packed_git *p,
struct packed_git **lru_p,
struct pack_window **lru_w,
@@ -605,6 +621,9 @@ static int open_packed_git_1(struct packed_git *p)
unsigned char *idx_sha1;
long fd_flag;
+ if (!p->index_data && open_pack_index(p))
+ return error("packfile %s index unavailable", p->pack_name);
+
p->pack_fd = open(p->pack_name, O_RDONLY);
if (p->pack_fd < 0 || fstat(p->pack_fd, &st))
return -1;
@@ -757,8 +776,7 @@ struct packed_git *add_packed_git(const char *path, int path_len, int local)
return NULL;
memcpy(p->pack_name, path, path_len);
strcpy(p->pack_name + path_len, ".pack");
- if (stat(p->pack_name, &st) || !S_ISREG(st.st_mode) ||
- check_packed_git_idx(path, p)) {
+ if (stat(p->pack_name, &st) || !S_ISREG(st.st_mode)) {
free(p);
return NULL;
}
@@ -766,6 +784,10 @@ struct packed_git *add_packed_git(const char *path, int path_len, int local)
/* ok, it looks sane as far as we can check without
* actually mapping the pack file.
*/
+ p->index_version = 0;
+ p->index_data = NULL;
+ p->index_size = 0;
+ p->num_objects = 0;
p->pack_size = st.st_size;
p->next = NULL;
p->windows = NULL;
@@ -972,7 +994,7 @@ void *map_sha1_file(const unsigned char *sha1, unsigned long *size)
return map;
}
-int legacy_loose_object(unsigned char *map)
+static int legacy_loose_object(unsigned char *map)
{
unsigned int word;
@@ -1034,6 +1056,14 @@ static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned lon
return inflate(stream, 0);
}
+
+ /*
+ * There used to be a second loose object header format which
+ * was meant to mimic the in-pack format, allowing for direct
+ * copy of the object data. This format turned up not to be
+ * really worth it and we don't write it any longer. But we
+ * can still read it.
+ */
used = unpack_object_header_gently(map, mapsize, &type, &size);
if (!used || !valid_loose_object_type[type])
return -1;
@@ -1109,7 +1139,7 @@ static int parse_sha1_header(const char *hdr, unsigned long *sizep)
unsigned long size;
/*
- * The type can be at most ten bytes (including the
+ * The type can be at most ten bytes (including the
* terminating '\0' that we add), and is followed by
* a space.
*/
@@ -1564,10 +1594,15 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset,
return data;
}
-const unsigned char *nth_packed_object_sha1(const struct packed_git *p,
+const unsigned char *nth_packed_object_sha1(struct packed_git *p,
uint32_t n)
{
const unsigned char *index = p->index_data;
+ if (!index) {
+ if (open_pack_index(p))
+ return NULL;
+ index = p->index_data;
+ }
if (n >= p->num_objects)
return NULL;
index += 4 * 256;
@@ -1604,6 +1639,12 @@ off_t find_pack_entry_one(const unsigned char *sha1,
const unsigned char *index = p->index_data;
unsigned hi, lo;
+ if (!index) {
+ if (open_pack_index(p))
+ return 0;
+ level1_ofs = p->index_data;
+ index = p->index_data;
+ }
if (p->index_version > 1) {
level1_ofs += 2;
index += 8;
@@ -1646,20 +1687,25 @@ static int matches_pack_name(struct packed_git *p, const char *ig)
static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e, const char **ignore_packed)
{
+ static struct packed_git *last_found = (void *)1;
struct packed_git *p;
off_t offset;
prepare_packed_git();
+ if (!packed_git)
+ return 0;
+ p = (last_found == (void *)1) ? packed_git : last_found;
- for (p = packed_git; p; p = p->next) {
+ do {
if (ignore_packed) {
const char **ig;
for (ig = ignore_packed; *ig; ig++)
if (!matches_pack_name(p, *ig))
break;
if (*ig)
- continue;
+ goto next;
}
+
offset = find_pack_entry_one(sha1, p);
if (offset) {
/*
@@ -1672,18 +1718,27 @@ static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e, cons
*/
if (p->pack_fd == -1 && open_packed_git(p)) {
error("packfile %s cannot be accessed", p->pack_name);
- continue;
+ goto next;
}
e->offset = offset;
e->p = p;
hashcpy(e->sha1, sha1);
+ last_found = p;
return 1;
}
- }
+
+ next:
+ if (p == last_found)
+ p = packed_git;
+ else
+ p = p->next;
+ if (p == last_found)
+ p = p->next;
+ } while (p);
return 0;
}
-struct packed_git *find_sha1_pack(const unsigned char *sha1,
+struct packed_git *find_sha1_pack(const unsigned char *sha1,
struct packed_git *packs)
{
struct packed_git *p;
@@ -1962,40 +2017,6 @@ static int write_buffer(int fd, const void *buf, size_t len)
return 0;
}
-static int write_binary_header(unsigned char *hdr, enum object_type type, unsigned long len)
-{
- int hdr_len;
- unsigned char c;
-
- c = (type << 4) | (len & 15);
- len >>= 4;
- hdr_len = 1;
- while (len) {
- *hdr++ = c | 0x80;
- hdr_len++;
- c = (len & 0x7f);
- len >>= 7;
- }
- *hdr = c;
- return hdr_len;
-}
-
-static void setup_object_header(z_stream *stream, const char *type, unsigned long len)
-{
- int obj_type, hdrlen;
-
- if (use_legacy_headers) {
- while (deflate(stream, 0) == Z_OK)
- /* nothing */;
- return;
- }
- obj_type = type_from_string(type);
- hdrlen = write_binary_header(stream->next_out, obj_type, len);
- stream->total_out = hdrlen;
- stream->next_out += hdrlen;
- stream->avail_out -= hdrlen;
-}
-
int hash_sha1_file(const void *buf, unsigned long len, const char *type,
unsigned char *sha1)
{
@@ -2062,7 +2083,8 @@ int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned cha
/* First header.. */
stream.next_in = (unsigned char *)hdr;
stream.avail_in = hdrlen;
- setup_object_header(&stream, type, len);
+ while (deflate(&stream, 0) == Z_OK)
+ /* nothing */;
/* Then the data itself.. */
stream.next_in = buf;
diff --git a/sha1_name.c b/sha1_name.c
index 55f25a2..858f08c 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -76,8 +76,11 @@ static int find_short_packed_object(int len, const unsigned char *match, unsigne
prepare_packed_git();
for (p = packed_git; p && found < 2; p = p->next) {
- uint32_t num = p->num_objects;
- uint32_t first = 0, last = num;
+ uint32_t num, last;
+ uint32_t first = 0;
+ open_pack_index(p);
+ num = p->num_objects;
+ last = num;
while (first < last) {
uint32_t mid = (first + last) / 2;
const unsigned char *now;
@@ -133,6 +136,7 @@ static int find_unique_short_object(int len, char *canonical,
int has_unpacked, has_packed;
unsigned char unpacked_sha1[20], packed_sha1[20];
+ prepare_alt_odb();
has_unpacked = find_short_object_filename(len, canonical, unpacked_sha1);
has_packed = find_short_packed_object(len, res, packed_sha1);
if (!has_unpacked && !has_packed)
@@ -654,7 +658,6 @@ int get_sha1_with_mode(const char *name, unsigned char *sha1, unsigned *mode)
const char *cp;
*mode = S_IFINVALID;
- prepare_alt_odb();
ret = get_sha1_1(name, namelen, sha1);
if (!ret)
return ret;
@@ -679,8 +682,6 @@ int get_sha1_with_mode(const char *name, unsigned char *sha1, unsigned *mode)
namelen = namelen - (cp - name);
if (!active_cache)
read_cache();
- if (active_nr < 0)
- return -1;
pos = cache_name_pos(cp, namelen);
if (pos < 0)
pos = -pos - 1;
diff --git a/shallow.c b/shallow.c
index d178689..dbd9f5a 100644
--- a/shallow.c
+++ b/shallow.c
@@ -101,4 +101,3 @@ struct commit_list *get_shallow_commits(struct object_array *heads, int depth,
return result;
}
-
diff --git a/ssh-upload.c b/ssh-upload.c
index 498d41e..20c35f0 100644
--- a/ssh-upload.c
+++ b/ssh-upload.c
@@ -29,24 +29,24 @@ static int serve_object(int fd_in, int fd_out) {
}
if (!size)
return -1;
-
+
if (verbose)
fprintf(stderr, "Serving %s\n", sha1_to_hex(sha1));
remote = 0;
-
+
if (!has_sha1_file(sha1)) {
fprintf(stderr, "git-ssh-upload: could not find %s\n",
sha1_to_hex(sha1));
remote = -1;
}
-
+
if (write_in_full(fd_out, &remote, 1) != 1)
return 0;
-
+
if (remote < 0)
return 0;
-
+
return write_sha1_to_fd(fd_out, sha1);
}
diff --git a/strbuf.c b/strbuf.c
index 7f14b0f..e33d06b 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -39,4 +39,3 @@ void read_line(struct strbuf *sb, FILE *fp, int term) {
sb->eof = 1;
strbuf_end(sb);
}
-
diff --git a/t/Makefile b/t/Makefile
index 19e3850..b25caca 100644
--- a/t/Makefile
+++ b/t/Makefile
@@ -28,4 +28,3 @@ full-svn-test:
.PHONY: $(T) clean
.NOTPARALLEL:
-
diff --git a/t/lib-read-tree-m-3way.sh b/t/lib-read-tree-m-3way.sh
index d195603..586df21 100644
--- a/t/lib-read-tree-m-3way.sh
+++ b/t/lib-read-tree-m-3way.sh
@@ -87,7 +87,7 @@ test_expect_success \
test_expect_success \
'recording branch A tree' \
'tree_A=$(git-write-tree)'
-
+
################################################################
# Branch B
# Start from O
diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh
index 186de70..8bfe832 100755
--- a/t/t0000-basic.sh
+++ b/t/t0000-basic.sh
@@ -37,7 +37,7 @@ fi
find .git/objects -type f -print >should-be-empty
test_expect_success \
'.git/objects should be empty after git-init in an empty repo.' \
- 'cmp -s /dev/null should-be-empty'
+ 'cmp -s /dev/null should-be-empty'
# also it should have 2 subdirectories; no fan-out anymore, pack, and info.
# 3 is counting "objects" itself
diff --git a/t/t1200-tutorial.sh b/t/t1200-tutorial.sh
index ca2c30f..d3f8358 100755
--- a/t/t1200-tutorial.sh
+++ b/t/t1200-tutorial.sh
@@ -159,4 +159,3 @@ test_expect_success 'git prune-packed' 'git prune-packed'
test_expect_failure '-> only packed objects' 'find -type f .git/objects/[0-9a-f][0-9a-f]'
test_done
-
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index 3f3fd2d..7731fa7 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -514,4 +514,3 @@ git config --list > result
test_expect_success 'value continued on next line' 'cmp result expect'
test_done
-
diff --git a/t/t2000-checkout-cache-clash.sh b/t/t2000-checkout-cache-clash.sh
index 03ea4de..d556b41 100755
--- a/t/t2000-checkout-cache-clash.sh
+++ b/t/t2000-checkout-cache-clash.sh
@@ -49,5 +49,3 @@ test_expect_success \
'test -f path0 && test -d path1 && test -f path1/file1'
test_done
-
-
diff --git a/t/t2001-checkout-cache-clash.sh b/t/t2001-checkout-cache-clash.sh
index 0dcab8f..b895a0f 100755
--- a/t/t2001-checkout-cache-clash.sh
+++ b/t/t2001-checkout-cache-clash.sh
@@ -84,4 +84,3 @@ test_expect_success \
test ! -h path1/file1 && test -f path1/file1'
test_done
-
diff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh
index 86ee2b0..607f57f 100755
--- a/t/t3030-merge-recursive.sh
+++ b/t/t3030-merge-recursive.sh
@@ -525,4 +525,3 @@ test_expect_success 'reset and bind merge' '
'
test_done
-
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index 828d553..6f6d884 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -136,8 +136,8 @@ test_expect_success 'test tracking setup (non-wildcard, not matching)' \
git-config remote.local.fetch refs/heads/s:refs/remotes/local/s &&
(git-show-ref -q refs/remotes/local/master || git-fetch local) &&
git-branch --track my5 local/master &&
- ! test $(git-config branch.my5.remote) = local &&
- ! test $(git-config branch.my5.merge) = refs/heads/master'
+ ! test "$(git-config branch.my5.remote)" = local &&
+ ! test "$(git-config branch.my5.merge)" = refs/heads/master'
test_expect_success 'test tracking setup via config' \
'git-config branch.autosetupmerge true &&
@@ -155,14 +155,22 @@ test_expect_success 'test overriding tracking setup via --no-track' \
(git-show-ref -q refs/remotes/local/master || git-fetch local) &&
git-branch --no-track my2 local/master &&
git-config branch.autosetupmerge false &&
- ! test $(git-config branch.my2.remote) = local &&
- ! test $(git-config branch.my2.merge) = refs/heads/master'
+ ! test "$(git-config branch.my2.remote)" = local &&
+ ! test "$(git-config branch.my2.merge)" = refs/heads/master'
test_expect_success 'test local tracking setup' \
'git branch --track my6 s &&
test $(git-config branch.my6.remote) = . &&
test $(git-config branch.my6.merge) = refs/heads/s'
+test_expect_success 'test tracking setup via --track but deeper' \
+ 'git-config remote.local.url . &&
+ git-config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ (git-show-ref -q refs/remotes/local/o/o || git-fetch local) &&
+ git-branch --track my7 local/o/o &&
+ test "$(git-config branch.my7.remote)" = local &&
+ test "$(git-config branch.my7.merge)" = refs/heads/o/o'
+
# Keep this test last, as it changes the current branch
cat >expect <<EOF
0000000000000000000000000000000000000000 $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 branch: Created from master
diff --git a/t/t3403-rebase-skip.sh b/t/t3403-rebase-skip.sh
index 977c498..9e11ed2 100755
--- a/t/t3403-rebase-skip.sh
+++ b/t/t3403-rebase-skip.sh
@@ -54,4 +54,3 @@ test_expect_success 'merge and reference trees equal' \
test_debug 'gitk --all & sleep 1'
test_done
-
diff --git a/t/t4006-diff-mode.sh b/t/t4006-diff-mode.sh
index e72c6fd..b8acca1 100755
--- a/t/t4006-diff-mode.sh
+++ b/t/t4006-diff-mode.sh
@@ -41,4 +41,3 @@ test_expect_success \
'git diff expected check'
test_done
-
diff --git a/t/t4100-apply-stat.sh b/t/t4100-apply-stat.sh
index 7b81c32..c23341f 100755
--- a/t/t4100-apply-stat.sh
+++ b/t/t4100-apply-stat.sh
@@ -44,4 +44,3 @@ test_expect_success \
git diff ../t4100/t-apply-7.expect current'
test_done
-
diff --git a/t/t4110-apply-scan.sh b/t/t4110-apply-scan.sh
index 005f744..9faef0d 100755
--- a/t/t4110-apply-scan.sh
+++ b/t/t4110-apply-scan.sh
@@ -98,4 +98,3 @@ test_expect_success "S = cmp" \
'cmp apply.txt patch.txt'
test_done
-
diff --git a/t/t4112-apply-renames.sh b/t/t4112-apply-renames.sh
index 69e9603..9baf810 100755
--- a/t/t4112-apply-renames.sh
+++ b/t/t4112-apply-renames.sh
@@ -49,10 +49,10 @@ copy to include/arch/cris/klibc/archsetjmp.h
- * arch/x86_64/include/klibc/archsetjmp.h
+ * arch/cris/include/klibc/archsetjmp.h
*/
-
+
#ifndef _KLIBC_ARCHSETJMP_H
#define _KLIBC_ARCHSETJMP_H
-
+
struct __jmp_buf {
- unsigned long __rbx;
- unsigned long __rsp;
@@ -74,9 +74,9 @@ copy to include/arch/cris/klibc/archsetjmp.h
+ unsigned long __sp;
+ unsigned long __srp;
};
-
+
typedef struct __jmp_buf jmp_buf[1];
-
+
-#endif /* _SETJMP_H */
+#endif /* _KLIBC_ARCHSETJMP_H */
diff --git a/klibc/arch/x86_64/include/klibc/archsetjmp.h b/include/arch/m32r/klibc/archsetjmp.h
@@ -90,10 +90,10 @@ rename to include/arch/m32r/klibc/archsetjmp.h
- * arch/x86_64/include/klibc/archsetjmp.h
+ * arch/m32r/include/klibc/archsetjmp.h
*/
-
+
#ifndef _KLIBC_ARCHSETJMP_H
#define _KLIBC_ARCHSETJMP_H
-
+
struct __jmp_buf {
- unsigned long __rbx;
- unsigned long __rsp;
@@ -108,9 +108,9 @@ rename to include/arch/m32r/klibc/archsetjmp.h
unsigned long __r15;
- unsigned long __rip;
};
-
+
typedef struct __jmp_buf jmp_buf[1];
-
+
-#endif /* _SETJMP_H */
+#endif /* _KLIBC_ARCHSETJMP_H */
EOF
diff --git a/t/t4118-apply-empty-context.sh b/t/t4118-apply-empty-context.sh
index 27cc6f2..dd88e81 100755
--- a/t/t4118-apply-empty-context.sh
+++ b/t/t4118-apply-empty-context.sh
@@ -53,4 +53,3 @@ test_expect_success 'apply --apply' '
'
test_done
-
diff --git a/t/t4119-apply-config.sh b/t/t4119-apply-config.sh
index 620a920..edae705 100755
--- a/t/t4119-apply-config.sh
+++ b/t/t4119-apply-config.sh
@@ -24,7 +24,7 @@ cat >gpatch.file <<\EOF &&
+++ file1+ 2007-02-21 01:07:44.000000000 -0800
@@ -1 +1 @@
-A
-+B
++B
EOF
sed -e 's|file1|sub/&|' gpatch.file >gpatch-sub.file &&
diff --git a/t/t4121-apply-diffs.sh b/t/t4121-apply-diffs.sh
index 2b2f1ed..b95b89c 100755
--- a/t/t4121-apply-diffs.sh
+++ b/t/t4121-apply-diffs.sh
@@ -30,4 +30,3 @@ test_expect_success \
'( git diff test~2 test~1; git diff test~1 test~0 )| git apply'
test_done
-
diff --git a/t/t4122-apply-symlink-inside.sh b/t/t4122-apply-symlink-inside.sh
index 3ddfe64..841773f 100755
--- a/t/t4122-apply-symlink-inside.sh
+++ b/t/t4122-apply-symlink-inside.sh
@@ -53,4 +53,3 @@ test_expect_success 'check result' '
'
test_done
-
diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh
index c64ebbb..a46d7f7 100755
--- a/t/t4200-rerere.sh
+++ b/t/t4200-rerere.sh
@@ -148,5 +148,3 @@ test_expect_success 'old records rest in peace' \
"test ! -f $rr/preimage && test ! -f $rr2/preimage"
test_done
-
-
diff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh
index e223c07..a6c5bf6 100755
--- a/t/t5000-tar-tree.sh
+++ b/t/t5000-tar-tree.sh
@@ -108,6 +108,13 @@ test_expect_success \
'git-archive --format=zip' \
'git-archive --format=zip HEAD >d.zip'
+$UNZIP -v >/dev/null 2>&1
+if [ $? -eq 127 ]; then
+ echo "Skipping ZIP tests, because unzip was not found"
+ test_done
+ exit
+fi
+
test_expect_success \
'extract ZIP archive' \
'(mkdir d && cd d && $UNZIP ../d.zip)'
diff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh
index 477b267..4eaea8f 100755
--- a/t/t5400-send-pack.sh
+++ b/t/t5400-send-pack.sh
@@ -66,7 +66,7 @@ test_expect_success 'pack the destination repository' '
'
test_expect_success \
- 'pushing rewound head should not barf but require --force' '
+ 'pushing rewound head should not barf but require --force' '
# should not fail but refuse to update.
if git-send-pack ./victim/.git/ master
then
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
new file mode 100755
index 0000000..dba018f
--- /dev/null
+++ b/t/t5516-fetch-push.sh
@@ -0,0 +1,82 @@
+#!/bin/sh
+
+test_description='fetching and pushing, with or without wildcard'
+
+. ./test-lib.sh
+
+D=`pwd`
+
+mk_empty () {
+ rm -fr testrepo &&
+ mkdir testrepo &&
+ (
+ cd testrepo &&
+ git init
+ )
+}
+
+test_expect_success setup '
+
+ : >path1 &&
+ git add path1 &&
+ test_tick &&
+ git commit -a -m repo &&
+ the_commit=$(git show-ref -s --verify refs/heads/master)
+
+'
+
+test_expect_success 'fetch without wildcard' '
+ mk_empty &&
+ (
+ cd testrepo &&
+ git fetch .. refs/heads/master:refs/remotes/origin/master &&
+
+ r=$(git show-ref -s --verify refs/remotes/origin/master) &&
+ test "z$r" = "z$the_commit" &&
+
+ test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
+ )
+'
+
+test_expect_success 'fetch with wildcard' '
+ mk_empty &&
+ (
+ cd testrepo &&
+ git config remote.up.url .. &&
+ git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" &&
+ git fetch up &&
+
+ r=$(git show-ref -s --verify refs/remotes/origin/master) &&
+ test "z$r" = "z$the_commit" &&
+
+ test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
+ )
+'
+
+test_expect_success 'push without wildcard' '
+ mk_empty &&
+
+ git push testrepo refs/heads/master:refs/remotes/origin/master &&
+ (
+ cd testrepo &&
+ r=$(git show-ref -s --verify refs/remotes/origin/master) &&
+ test "z$r" = "z$the_commit" &&
+
+ test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
+ )
+'
+
+test_expect_success 'push with wildcard' '
+ mk_empty &&
+
+ git push testrepo "refs/heads/*:refs/remotes/origin/*" &&
+ (
+ cd testrepo &&
+ r=$(git show-ref -s --verify refs/remotes/origin/master) &&
+ test "z$r" = "z$the_commit" &&
+
+ test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
+ )
+'
+
+test_done
diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh
index 243212d..93eaf2c 100755
--- a/t/t5520-pull.sh
+++ b/t/t5520-pull.sh
@@ -54,4 +54,3 @@ test_expect_success 'the default remote . should not break explicit pull' '
'
test_done
-
diff --git a/t/t5701-clone-local.sh b/t/t5701-clone-local.sh
new file mode 100755
index 0000000..b093327
--- /dev/null
+++ b/t/t5701-clone-local.sh
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+test_description='test local clone'
+. ./test-lib.sh
+
+D=`pwd`
+
+test_expect_success 'preparing origin repository' '
+ : >file && git add . && git commit -m1 &&
+ git clone --bare . a.git &&
+ git clone --bare . x
+'
+
+test_expect_success 'local clone without .git suffix' '
+ cd "$D" &&
+ git clone -l -s a b &&
+ cd b &&
+ git fetch
+'
+
+test_expect_success 'local clone with .git suffix' '
+ cd "$D" &&
+ git clone -l -s a.git c &&
+ cd c &&
+ git fetch
+'
+
+test_expect_success 'local clone from x' '
+ cd "$D" &&
+ git clone -l -s x y &&
+ cd y &&
+ git fetch
+'
+
+test_expect_success 'local clone from x.git that does not exist' '
+ cd "$D" &&
+ if git clone -l -s x.git z
+ then
+ echo "Oops, should have failed"
+ false
+ else
+ echo happy
+ fi
+'
+
+test_done
diff --git a/t/t5710-info-alternate.sh b/t/t5710-info-alternate.sh
index 2f8e97c..699df6e 100755
--- a/t/t5710-info-alternate.sh
+++ b/t/t5710-info-alternate.sh
@@ -104,4 +104,3 @@ test_valid_repo'
cd "$base_dir"
test_done
-
diff --git a/t/t6000lib.sh b/t/t6000lib.sh
index d402621..d548bf8 100755
--- a/t/t6000lib.sh
+++ b/t/t6000lib.sh
@@ -17,17 +17,17 @@ unique_commit()
_text=$1
_tree=$2
shift 2
- echo $_text | git-commit-tree $(tag $_tree) "$@"
+ echo $_text | git-commit-tree $(tag $_tree) "$@"
}
# Save the output of a command into the tag specified. Prepend
# a substitution script for the tag onto the front of sed.script
save_tag()
{
- _tag=$1
+ _tag=$1
[ -n "$_tag" ] || error "usage: save_tag tag commit-args ..."
shift 1
- "$@" >.git/refs/tags/$_tag
+ "$@" >.git/refs/tags/$_tag
echo "s/$(tag $_tag)/$_tag/g" > sed.script.tmp
cat sed.script >> sed.script.tmp
@@ -35,7 +35,7 @@ save_tag()
mv sed.script.tmp sed.script
}
-# Replace unhelpful sha1 hashses with their symbolic equivalents
+# Replace unhelpful sha1 hashses with their symbolic equivalents
entag()
{
sed -f sed.script
@@ -62,7 +62,7 @@ as_author()
commit_date()
{
_commit=$1
- git-cat-file commit $_commit | sed -n "s/^committer .*> \([0-9]*\) .*/\1/p"
+ git-cat-file commit $_commit | sed -n "s/^committer .*> \([0-9]*\) .*/\1/p"
}
on_committer_date()
@@ -103,14 +103,14 @@ name_from_description()
# Execute the test described by the first argument, by eval'ing
# command line specified in the 2nd argument. Check the status code
-# is zero and that the output matches the stream read from
+# is zero and that the output matches the stream read from
# stdin.
test_output_expect_success()
-{
+{
_description=$1
_test=$2
[ $# -eq 2 ] || error "usage: test_output_expect_success description test <<EOF ... EOF"
_name=$(echo $_description | name_from_description)
cat > $_name.expected
- test_expect_success "$_description" "check_output $_name \"$_test\""
+ test_expect_success "$_description" "check_output $_name \"$_test\""
}
diff --git a/t/t6002-rev-list-bisect.sh b/t/t6002-rev-list-bisect.sh
index fcb3302..71cbb72 100755
--- a/t/t6002-rev-list-bisect.sh
+++ b/t/t6002-rev-list-bisect.sh
@@ -26,7 +26,7 @@ test_bisection_diff()
# Test if bisection size is close to half of list size within
# tolerance.
- #
+ #
_bisect_err=`expr $_list_size - $_bisection_size \* 2`
test "$_bisect_err" -lt 0 && _bisect_err=`expr 0 - $_bisect_err`
_bisect_err=`expr $_bisect_err / 2` ; # floor
@@ -116,8 +116,8 @@ on_committer_date "1971-08-16 00:00:06" save_tag V unique_commit V tree -p u1 -p
test_sequence()
{
- _bisect_option=$1
-
+ _bisect_option=$1
+
test_bisection_diff 0 $_bisect_option l0 ^root
test_bisection_diff 0 $_bisect_option l1 ^root
test_bisection_diff 0 $_bisect_option l2 ^root
@@ -152,7 +152,7 @@ test_sequence()
test_bisection_diff 0 $_bisect_option u3 ^U
test_bisection_diff 0 $_bisect_option u4 ^U
test_bisection_diff 0 $_bisect_option u5 ^U
-
+
#
# the following illustrates Linus' binary bug blatt idea.
#
diff --git a/t/t6021-merge-criss-cross.sh b/t/t6021-merge-criss-cross.sh
index 499cafb..0ab14a6 100755
--- a/t/t6021-merge-criss-cross.sh
+++ b/t/t6021-merge-criss-cross.sh
@@ -20,7 +20,7 @@ test_expect_success 'prepare repository' \
7
8
9" > file &&
-git add file &&
+git add file &&
git commit -m "Initial commit" file &&
git branch A &&
git branch B &&
diff --git a/t/t6023-merge-file.sh b/t/t6023-merge-file.sh
index c76fccf..ecc11c1 100755
--- a/t/t6023-merge-file.sh
+++ b/t/t6023-merge-file.sh
@@ -134,5 +134,9 @@ EOF
test_expect_success "expected conflict markers" "git diff expect out"
-test_done
+test_expect_success 'binary files cannot be merged' '
+ ! git merge-file -p orig.txt ../test4012.png new1.txt 2> merge.err &&
+ grep "Cannot merge binary files" merge.err
+'
+test_done
diff --git a/t/t6024-recursive-merge.sh b/t/t6024-recursive-merge.sh
index a398556..058db9c 100755
--- a/t/t6024-recursive-merge.sh
+++ b/t/t6024-recursive-merge.sh
@@ -81,4 +81,18 @@ EOF
test_expect_success "virtual trees were processed" "git diff expect out"
+git reset --hard
+test_expect_success 'refuse to merge binary files' '
+ printf "\0" > binary-file &&
+ git add binary-file &&
+ git commit -m binary &&
+ git checkout G &&
+ printf "\0\0" > binary-file &&
+ git add binary-file &&
+ git commit -m binary2 &&
+ ! git merge F > merge.out 2> merge.err &&
+ grep "Cannot merge binary files: HEAD:binary-file vs. F:binary-file" \
+ merge.err
+'
+
test_done
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index 30f6ade..03cdba5 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -102,4 +102,3 @@ test_expect_success \
#
#
test_done
-
diff --git a/t/t6101-rev-parse-parents.sh b/t/t6101-rev-parse-parents.sh
index 7d354a1..dd6cc3a 100755
--- a/t/t6101-rev-parse-parents.sh
+++ b/t/t6101-rev-parse-parents.sh
@@ -29,5 +29,14 @@ test_expect_success 'final^1^3 not valid' "if git-rev-parse --verify final^1^3;
test_expect_failure '--verify start2^1' 'git-rev-parse --verify start2^1'
test_expect_success '--verify start2^0' 'git-rev-parse --verify start2^0'
-test_done
+test_expect_success 'repack for next test' 'git repack -a -d'
+test_expect_success 'short SHA-1 works' '
+ start=`git rev-parse --verify start` &&
+ echo $start &&
+ abbrv=`echo $start | sed s/.\$//` &&
+ echo $abbrv &&
+ abbrv=`git rev-parse --verify $abbrv` &&
+ echo $abbrv &&
+ test $start = $abbrv'
+test_done
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
new file mode 100755
index 0000000..6274729
--- /dev/null
+++ b/t/t7400-submodule-basic.sh
@@ -0,0 +1,143 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Lars Hjemli
+#
+
+test_description='Basic porcelain support for submodules
+
+This test tries to verify basic sanity of the init, update and status
+subcommands of git-submodule.
+'
+
+. ./test-lib.sh
+
+#
+# Test setup:
+# -create a repository in directory lib
+# -add a couple of files
+# -add directory lib to 'superproject', this creates a DIRLINK entry
+# -add a couple of regular files to enable testing of submodule filtering
+# -mv lib subrepo
+# -add an entry to .gitmodules for path 'lib'
+#
+test_expect_success 'Prepare submodule testing' '
+ mkdir lib &&
+ cd lib &&
+ git-init &&
+ echo a >a &&
+ git-add a &&
+ git-commit -m "submodule commit 1" &&
+ git-tag -a -m "rev-1" rev-1 &&
+ rev1=$(git-rev-parse HEAD) &&
+ if test -z "$rev1"
+ then
+ echo "[OOPS] submodule git-rev-parse returned nothing"
+ false
+ fi &&
+ cd .. &&
+ echo a >a &&
+ echo z >z &&
+ git-add a lib z &&
+ git-commit -m "super commit 1" &&
+ mv lib .subrepo &&
+ GIT_CONFIG=.gitmodules git-config module.lib.url ./.subrepo
+'
+
+test_expect_success 'status should only print one line' '
+ lines=$(git-submodule status | wc -l) &&
+ test $lines = 1
+'
+
+test_expect_success 'status should initially be "missing"' '
+ git-submodule status | grep "^-$rev1"
+'
+
+test_expect_success 'init should fail when path is used by a file' '
+ echo "hello" >lib &&
+ if git-submodule init
+ then
+ echo "[OOPS] init should have failed"
+ false
+ elif test -f lib && test "$(cat lib)" != "hello"
+ then
+ echo "[OOPS] init failed but lib file was molested"
+ false
+ else
+ rm lib
+ fi
+'
+
+test_expect_success 'init should fail when path is used by a nonempty directory' '
+ mkdir lib &&
+ echo "hello" >lib/a &&
+ if git-submodule init
+ then
+ echo "[OOPS] init should have failed"
+ false
+ elif test "$(cat lib/a)" != "hello"
+ then
+ echo "[OOPS] init failed but lib/a was molested"
+ false
+ else
+ rm lib/a
+ fi
+'
+
+test_expect_success 'init should work when path is an empty dir' '
+ rm -rf lib &&
+ mkdir lib &&
+ git-submodule init &&
+ head=$(cd lib && git-rev-parse HEAD) &&
+ if test -z "$head"
+ then
+ echo "[OOPS] Failed to obtain submodule head"
+ false
+ elif test "$head" != "$rev1"
+ then
+ echo "[OOPS] Submodule head is $head but should have been $rev1"
+ false
+ fi
+'
+
+test_expect_success 'status should be "up-to-date" after init' '
+ git-submodule status | grep "^ $rev1"
+'
+
+test_expect_success 'status should be "modified" after submodule commit' '
+ cd lib &&
+ echo b >b &&
+ git-add b &&
+ git-commit -m "submodule commit 2" &&
+ rev2=$(git-rev-parse HEAD) &&
+ cd .. &&
+ if test -z "$rev2"
+ then
+ echo "[OOPS] submodule git-rev-parse returned nothing"
+ false
+ fi &&
+ git-submodule status | grep "^+$rev2"
+'
+
+test_expect_success 'the --cached sha1 should be rev1' '
+ git-submodule --cached status | grep "^+$rev1"
+'
+
+test_expect_success 'update should checkout rev1' '
+ git-submodule update &&
+ head=$(cd lib && git-rev-parse HEAD) &&
+ if test -z "$head"
+ then
+ echo "[OOPS] submodule git-rev-parse returned nothing"
+ false
+ elif test "$head" != "$rev1"
+ then
+ echo "[OOPS] init did not checkout correct head"
+ false
+ fi
+'
+
+test_expect_success 'status should be "up-to-date" after update' '
+ git-submodule status | grep "^ $rev1"
+'
+
+test_done
diff --git a/t/t9107-git-svn-migrate.sh b/t/t9107-git-svn-migrate.sh
index dc2afda..d549665 100755
--- a/t/t9107-git-svn-migrate.sh
+++ b/t/t9107-git-svn-migrate.sh
@@ -109,4 +109,3 @@ test_expect_success ".rev_db auto-converted to .rev_db.UUID" "
"
test_done
-
diff --git a/t/t9111/svnsync.dump b/t/t9111/svnsync.dump
index a9a46ee..499fa95 100644
--- a/t/t9111/svnsync.dump
+++ b/t/t9111/svnsync.dump
@@ -558,5 +558,3 @@ Text-content-md5: 7abb78de7f2756ca8b511cbc879fd5e7
Content-length: 4
cba
-
-
diff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh
index d406a88..41dcf64 100755
--- a/t/t9400-git-cvsserver-server.sh
+++ b/t/t9400-git-cvsserver-server.sh
@@ -47,6 +47,172 @@ test_expect_success 'basic checkout' \
'GIT_CONFIG="$git_config" cvs -Q co -d cvswork master &&
test "$(echo $(grep -v ^D cvswork/CVS/Entries|cut -d/ -f2,3,5))" = "empty/1.1/"'
+#------------------------
+# PSERVER AUTHENTICATION
+#------------------------
+
+cat >request-anonymous <<EOF
+BEGIN AUTH REQUEST
+$SERVERDIR
+anonymous
+
+END AUTH REQUEST
+EOF
+
+cat >request-git <<EOF
+BEGIN AUTH REQUEST
+$SERVERDIR
+git
+
+END AUTH REQUEST
+EOF
+
+cat >login-anonymous <<EOF
+BEGIN VERIFICATION REQUEST
+$SERVERDIR
+anonymous
+
+END VERIFICATION REQUEST
+EOF
+
+cat >login-git <<EOF
+BEGIN VERIFICATION REQUEST
+$SERVERDIR
+git
+
+END VERIFICATION REQUEST
+EOF
+
+test_expect_success 'pserver authentication' \
+ 'cat request-anonymous | git-cvsserver pserver >log 2>&1 &&
+ tail -n1 log | grep -q "^I LOVE YOU$"'
+
+test_expect_success 'pserver authentication failure (non-anonymous user)' \
+ 'if cat request-git | git-cvsserver pserver >log 2>&1
+ then
+ false
+ else
+ true
+ fi &&
+ tail -n1 log | grep -q "^I HATE YOU$"'
+
+test_expect_success 'pserver authentication (login)' \
+ 'cat login-anonymous | git-cvsserver pserver >log 2>&1 &&
+ tail -n1 log | grep -q "^I LOVE YOU$"'
+
+test_expect_success 'pserver authentication failure (login/non-anonymous user)' \
+ 'if cat login-git | git-cvsserver pserver >log 2>&1
+ then
+ false
+ else
+ true
+ fi &&
+ tail -n1 log | grep -q "^I HATE YOU$"'
+
+
+# misuse pserver authentication for testing of req_Root
+
+cat >request-relative <<EOF
+BEGIN AUTH REQUEST
+gitcvs.git
+anonymous
+
+END AUTH REQUEST
+EOF
+
+cat >request-conflict <<EOF
+BEGIN AUTH REQUEST
+$SERVERDIR
+anonymous
+
+END AUTH REQUEST
+Root $WORKDIR
+EOF
+
+test_expect_success 'req_Root failure (relative pathname)' \
+ 'if cat request-relative | git-cvsserver pserver >log 2>&1
+ then
+ echo unexpected success
+ false
+ else
+ true
+ fi &&
+ tail log | grep -q "^error 1 Root must be an absolute pathname$"'
+
+test_expect_success 'req_Root failure (conflicting roots)' \
+ 'cat request-conflict | git-cvsserver pserver >log 2>&1 &&
+ tail log | grep -q "^error 1 Conflicting roots specified$"'
+
+
+#--------------
+# CONFIG TESTS
+#--------------
+
+test_expect_success 'gitcvs.enabled = false' \
+ 'GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled false &&
+ if GIT_CONFIG="$git_config" cvs -Q co -d cvswork2 master >cvs.log 2>&1
+ then
+ echo unexpected cvs success
+ false
+ else
+ true
+ fi &&
+ cat cvs.log | grep -q "GITCVS emulation disabled" &&
+ test ! -d cvswork2'
+
+rm -fr cvswork2
+test_expect_success 'gitcvs.ext.enabled = true' \
+ 'GIT_DIR="$SERVERDIR" git config --bool gitcvs.ext.enabled true &&
+ GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled false &&
+ GIT_CONFIG="$git_config" cvs -Q co -d cvswork2 master >cvs.log 2>&1 &&
+ diff -q cvswork cvswork2'
+
+rm -fr cvswork2
+test_expect_success 'gitcvs.ext.enabled = false' \
+ 'GIT_DIR="$SERVERDIR" git config --bool gitcvs.ext.enabled false &&
+ GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled true &&
+ if GIT_CONFIG="$git_config" cvs -Q co -d cvswork2 master >cvs.log 2>&1
+ then
+ echo unexpected cvs success
+ false
+ else
+ true
+ fi &&
+ cat cvs.log | grep -q "GITCVS emulation disabled" &&
+ test ! -d cvswork2'
+
+rm -fr cvswork2
+test_expect_success 'gitcvs.dbname' \
+ 'GIT_DIR="$SERVERDIR" git config --bool gitcvs.ext.enabled true &&
+ GIT_DIR="$SERVERDIR" git config gitcvs.dbname %Ggitcvs.%a.%m.sqlite &&
+ GIT_CONFIG="$git_config" cvs -Q co -d cvswork2 master >cvs.log 2>&1 &&
+ diff -q cvswork cvswork2 &&
+ test -f "$SERVERDIR/gitcvs.ext.master.sqlite" &&
+ cmp "$SERVERDIR/gitcvs.master.sqlite" "$SERVERDIR/gitcvs.ext.master.sqlite"'
+
+rm -fr cvswork2
+test_expect_success 'gitcvs.ext.dbname' \
+ 'GIT_DIR="$SERVERDIR" git config --bool gitcvs.ext.enabled true &&
+ GIT_DIR="$SERVERDIR" git config gitcvs.ext.dbname %Ggitcvs1.%a.%m.sqlite &&
+ GIT_DIR="$SERVERDIR" git config gitcvs.dbname %Ggitcvs2.%a.%m.sqlite &&
+ GIT_CONFIG="$git_config" cvs -Q co -d cvswork2 master >cvs.log 2>&1 &&
+ diff -q cvswork cvswork2 &&
+ test -f "$SERVERDIR/gitcvs1.ext.master.sqlite" &&
+ test ! -f "$SERVERDIR/gitcvs2.ext.master.sqlite" &&
+ cmp "$SERVERDIR/gitcvs.master.sqlite" "$SERVERDIR/gitcvs1.ext.master.sqlite"'
+
+
+#------------
+# CVS UPDATE
+#------------
+
+rm -fr "$SERVERDIR"
+cd "$WORKDIR" &&
+git clone -q --local --bare "$WORKDIR/.git" "$SERVERDIR" >/dev/null 2>&1 &&
+GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled true &&
+GIT_DIR="$SERVERDIR" git config --bool gitcvs.logfile "$SERVERDIR/gitcvs.log" ||
+exit 1
+
test_expect_success 'cvs update (create new file)' \
'echo testfile1 >testfile1 &&
git add testfile1 &&
@@ -123,4 +289,75 @@ test_expect_success 'cvs update (re-add deleted file)' \
test "$(echo $(grep testfile1 CVS/Entries|cut -d/ -f2,3,5))" = "testfile1/1.4/" &&
diff -q testfile1 ../testfile1'
+cd "$WORKDIR"
+test_expect_success 'cvs update (merge)' \
+ 'echo Line 0 >expected &&
+ for i in 1 2 3 4 5 6 7
+ do
+ echo Line $i >>merge
+ echo Line $i >>expected
+ done &&
+ echo Line 8 >>expected &&
+ git add merge &&
+ git commit -q -m "Merge test (pre-merge)" &&
+ git push gitcvs.git >/dev/null &&
+ cd cvswork &&
+ GIT_CONFIG="$git_config" cvs -Q update &&
+ test "$(echo $(grep merge CVS/Entries|cut -d/ -f2,3,5))" = "merge/1.1/" &&
+ diff -q merge ../merge &&
+ ( echo Line 0; cat merge ) >merge.tmp &&
+ mv merge.tmp merge &&
+ cd "$WORKDIR" &&
+ echo Line 8 >>merge &&
+ git add merge &&
+ git commit -q -m "Merge test (merge)" &&
+ git push gitcvs.git >/dev/null &&
+ cd cvswork &&
+ sleep 1 && touch merge &&
+ GIT_CONFIG="$git_config" cvs -Q update &&
+ diff -q merge ../expected'
+
+cd "$WORKDIR"
+
+cat >expected.C <<EOF
+<<<<<<< merge.mine
+Line 0
+=======
+LINE 0
+>>>>>>> merge.3
+EOF
+
+for i in 1 2 3 4 5 6 7 8
+do
+ echo Line $i >>expected.C
+done
+
+test_expect_success 'cvs update (conflict merge)' \
+ '( echo LINE 0; cat merge ) >merge.tmp &&
+ mv merge.tmp merge &&
+ git add merge &&
+ git commit -q -m "Merge test (conflict)" &&
+ git push gitcvs.git >/dev/null &&
+ cd cvswork &&
+ GIT_CONFIG="$git_config" cvs -Q update &&
+ diff -q merge ../expected.C'
+
+cd "$WORKDIR"
+test_expect_success 'cvs update (-C)' \
+ 'cd cvswork &&
+ GIT_CONFIG="$git_config" cvs -Q update -C &&
+ diff -q merge ../merge'
+
+cd "$WORKDIR"
+test_expect_success 'cvs update (merge no-op)' \
+ 'echo Line 9 >>merge &&
+ cp merge cvswork/merge &&
+ git add merge &&
+ git commit -q -m "Merge test (no-op)" &&
+ git push gitcvs.git >/dev/null &&
+ cd cvswork &&
+ sleep 1 && touch merge &&
+ GIT_CONFIG="$git_config" cvs -Q update &&
+ diff -q merge ../merge'
+
test_done
diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh
new file mode 100755
index 0000000..44ae503
--- /dev/null
+++ b/t/t9500-gitweb-standalone-no-errors.sh
@@ -0,0 +1,518 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Jakub Narebski
+#
+
+test_description='gitweb as standalone script (basic tests).
+
+This test runs gitweb (git web interface) as CGI script from
+commandline, and checks that it would not write any errors
+or warnings to log.'
+
+gitweb_init () {
+ cat >gitweb_config.perl <<EOF
+#!/usr/bin/perl
+
+# gitweb configuration for tests
+
+our \$version = "current";
+our \$GIT = "git";
+our \$projectroot = "$(pwd)";
+our \$home_link_str = "projects";
+our \$site_name = "[localhost]";
+our \$site_header = "";
+our \$site_footer = "";
+our \$home_text = "indextext.html";
+our @stylesheets = ("file:///$(pwd)/../../gitweb/gitweb.css");
+our \$logo = "file:///$(pwd)/../../gitweb/git-logo.png";
+our \$favicon = "file:///$(pwd)/../../gitweb/git-favicon.png";
+our \$projects_list = "";
+our \$export_ok = "";
+our \$strict_export = "";
+
+CGI::Carp::set_programname("gitweb/gitweb.cgi");
+EOF
+
+ cat >.git/description <<EOF
+$0 test repository
+EOF
+}
+
+gitweb_run () {
+ export GATEWAY_INTERFACE="CGI/1.1"
+ export HTTP_ACCEPT="*/*"
+ export REQUEST_METHOD="GET"
+ export QUERY_STRING=""$1""
+ export PATH_INFO=""$2""
+
+ export GITWEB_CONFIG=$(pwd)/gitweb_config.perl
+
+ # some of git commands write to STDERR on error, but this is not
+ # written to web server logs, so we are not interested in that:
+ # we are interested only in properly formatted errors/warnings
+ rm -f gitweb.log &&
+ perl -- $(pwd)/../../gitweb/gitweb.perl \
+ >/dev/null 2>gitweb.log &&
+ if grep -q -s "^[[]" gitweb.log >/dev/null; then false; else true; fi
+
+ # gitweb.log is left for debugging
+}
+
+. ./test-lib.sh
+
+gitweb_init
+
+# ----------------------------------------------------------------------
+# no commits (empty, just initialized repository)
+
+test_expect_success \
+ 'no commits: projects_list (implicit)' \
+ 'gitweb_run'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'no commits: projects_index' \
+ 'gitweb_run "a=project_index"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'no commits: .git summary (implicit)' \
+ 'gitweb_run "p=.git"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'no commits: .git commit (implicit HEAD)' \
+ 'gitweb_run "p=.git;a=commit"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'no commits: .git commitdiff (implicit HEAD)' \
+ 'gitweb_run "p=.git;a=commitdiff"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'no commits: .git tree (implicit HEAD)' \
+ 'gitweb_run "p=.git;a=tree"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'no commits: .git heads' \
+ 'gitweb_run "p=.git;a=heads"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'no commits: .git tags' \
+ 'gitweb_run "p=.git;a=tags"'
+test_debug 'cat gitweb.log'
+
+
+# ----------------------------------------------------------------------
+# initial commit
+
+test_expect_success \
+ 'Make initial commit' \
+ 'echo "Not an empty file." > file &&
+ git add file &&
+ git commit -a -m "Initial commit." &&
+ git branch b'
+
+test_expect_success \
+ 'projects_list (implicit)' \
+ 'gitweb_run'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'projects_index' \
+ 'gitweb_run "a=project_index"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ '.git summary (implicit)' \
+ 'gitweb_run "p=.git"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ '.git commit (implicit HEAD)' \
+ 'gitweb_run "p=.git;a=commit"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ '.git commitdiff (implicit HEAD, root commit)' \
+ 'gitweb_run "p=.git;a=commitdiff"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ '.git commitdiff_plain (implicit HEAD, root commit)' \
+ 'gitweb_run "p=.git;a=commitdiff_plain"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ '.git commit (HEAD)' \
+ 'gitweb_run "p=.git;a=commit;h=HEAD"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ '.git tree (implicit HEAD)' \
+ 'gitweb_run "p=.git;a=tree"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ '.git blob (file)' \
+ 'gitweb_run "p=.git;a=blob;f=file"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ '.git blob_plain (file)' \
+ 'gitweb_run "p=.git;a=blob_plain;f=file"'
+test_debug 'cat gitweb.log'
+
+# ----------------------------------------------------------------------
+# nonexistent objects
+
+test_expect_success \
+ '.git commit (non-existent)' \
+ 'gitweb_run "p=.git;a=commit;h=non-existent"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ '.git commitdiff (non-existent)' \
+ 'gitweb_run "p=.git;a=commitdiff;h=non-existent"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ '.git commitdiff (non-existent vs HEAD)' \
+ 'gitweb_run "p=.git;a=commitdiff;hp=non-existent;h=HEAD"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ '.git tree (0000000000000000000000000000000000000000)' \
+ 'gitweb_run "p=.git;a=tree;h=0000000000000000000000000000000000000000"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ '.git tag (0000000000000000000000000000000000000000)' \
+ 'gitweb_run "p=.git;a=tag;h=0000000000000000000000000000000000000000"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ '.git blob (non-existent)' \
+ 'gitweb_run "p=.git;a=blob;f=non-existent"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ '.git blob_plain (non-existent)' \
+ 'gitweb_run "p=.git;a=blob_plain;f=non-existent"'
+test_debug 'cat gitweb.log'
+
+
+# ----------------------------------------------------------------------
+# commitdiff testing (implicit, one implicit tree-ish)
+
+test_expect_success \
+ 'commitdiff(0): root' \
+ 'gitweb_run "p=.git;a=commitdiff"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'commitdiff(0): file added' \
+ 'echo "New file" > new_file &&
+ git add new_file &&
+ git commit -a -m "File added." &&
+ gitweb_run "p=.git;a=commitdiff"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'commitdiff(0): mode change' \
+ 'chmod a+x new_file &&
+ git commit -a -m "Mode changed." &&
+ gitweb_run "p=.git;a=commitdiff"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'commitdiff(0): file renamed' \
+ 'git mv new_file renamed_file &&
+ git commit -a -m "File renamed." &&
+ gitweb_run "p=.git;a=commitdiff"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'commitdiff(0): file to symlink' \
+ 'rm renamed_file &&
+ ln -s file renamed_file &&
+ git commit -a -m "File to symlink." &&
+ gitweb_run "p=.git;a=commitdiff"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'commitdiff(0): file deleted' \
+ 'git rm renamed_file &&
+ rm -f renamed_file &&
+ git commit -a -m "File removed." &&
+ gitweb_run "p=.git;a=commitdiff"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'commitdiff(0): file copied / new file' \
+ 'cp file file2 &&
+ git add file2 &&
+ git commit -a -m "File copied." &&
+ gitweb_run "p=.git;a=commitdiff"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'commitdiff(0): mode change and modified' \
+ 'echo "New line" >> file2 &&
+ chmod a+x file2 &&
+ git commit -a -m "Mode change and modification." &&
+ gitweb_run "p=.git;a=commitdiff"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'commitdiff(0): renamed and modified' \
+ 'cat >file2<<EOF &&
+Dominus regit me,
+et nihil mihi deerit.
+In loco pascuae ibi me collocavit,
+super aquam refectionis educavit me;
+animam meam convertit,
+deduxit me super semitas jusitiae,
+propter nomen suum.
+EOF
+ git commit -a -m "File added." &&
+ git mv file2 file3 &&
+ echo "Propter nomen suum." >> file3 &&
+ git commit -a -m "File rename and modification." &&
+ gitweb_run "p=.git;a=commitdiff"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'commitdiff(0): renamed, mode change and modified' \
+ 'git mv file3 file2 &&
+ echo "Propter nomen suum." >> file2 &&
+ chmod a+x file2 &&
+ git commit -a -m "File rename, mode change and modification." &&
+ gitweb_run "p=.git;a=commitdiff"'
+test_debug 'cat gitweb.log'
+
+# ----------------------------------------------------------------------
+# commitdiff testing (taken from t4114-apply-typechange.sh)
+
+test_expect_success 'setup typechange commits' '
+ echo "hello world" > foo &&
+ echo "hi planet" > bar &&
+ git update-index --add foo bar &&
+ git commit -m initial &&
+ git branch initial &&
+ rm -f foo &&
+ ln -s bar foo &&
+ git update-index foo &&
+ git commit -m "foo symlinked to bar" &&
+ git branch foo-symlinked-to-bar &&
+ rm -f foo &&
+ echo "how far is the sun?" > foo &&
+ git update-index foo &&
+ git commit -m "foo back to file" &&
+ git branch foo-back-to-file &&
+ rm -f foo &&
+ git update-index --remove foo &&
+ mkdir foo &&
+ echo "if only I knew" > foo/baz &&
+ git update-index --add foo/baz &&
+ git commit -m "foo becomes a directory" &&
+ git branch "foo-becomes-a-directory" &&
+ echo "hello world" > foo/baz &&
+ git update-index foo/baz &&
+ git commit -m "foo/baz is the original foo" &&
+ git branch foo-baz-renamed-from-foo
+ '
+
+test_expect_success \
+ 'commitdiff(2): file renamed from foo to foo/baz' \
+ 'gitweb_run "p=.git;a=commitdiff;hp=initial;h=foo-baz-renamed-from-foo"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'commitdiff(2): file renamed from foo/baz to foo' \
+ 'gitweb_run "p=.git;a=commitdiff;hp=foo-baz-renamed-from-foo;h=initial"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'commitdiff(2): directory becomes file' \
+ 'gitweb_run "p=.git;a=commitdiff;hp=foo-becomes-a-directory;h=initial"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'commitdiff(2): file becomes directory' \
+ 'gitweb_run "p=.git;a=commitdiff;hp=initial;h=foo-becomes-a-directory"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'commitdiff(2): file becomes symlink' \
+ 'gitweb_run "p=.git;a=commitdiff;hp=initial;h=foo-symlinked-to-bar"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'commitdiff(2): symlink becomes file' \
+ 'gitweb_run "p=.git;a=commitdiff;hp=foo-symlinked-to-bar;h=foo-back-to-file"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'commitdiff(2): symlink becomes directory' \
+ 'gitweb_run "p=.git;a=commitdiff;hp=foo-symlinked-to-bar;h=foo-becomes-a-directory"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'commitdiff(2): directory becomes symlink' \
+ 'gitweb_run "p=.git;a=commitdiff;hp=foo-becomes-a-directory;h=foo-symlinked-to-bar"'
+test_debug 'cat gitweb.log'
+
+# ----------------------------------------------------------------------
+# commit, commitdiff: merge, large
+test_expect_success \
+ 'Create a merge' \
+ 'git checkout b &&
+ echo "Branch" >> b &&
+ git add b &&
+ git commit -a -m "On branch" &&
+ git checkout master &&
+ git pull . b'
+
+test_expect_success \
+ 'commit(0): merge commit' \
+ 'gitweb_run "p=.git;a=commit"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'commitdiff(0): merge commit' \
+ 'gitweb_run "p=.git;a=commitdiff"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'Prepare large commit' \
+ 'git checkout b &&
+ echo "To be changed" > 01-change &&
+ echo "To be renamed" > 02-pure-rename-from &&
+ echo "To be deleted" > 03-delete &&
+ echo "To be renamed and changed" > 04-rename-from &&
+ echo "To have mode changed" > 05-mode-change &&
+ echo "File to symlink" > 06-file-or-symlink &&
+ echo "To be changed and have mode changed" > 07-change-mode-change &&
+ git add 0* &&
+ git commit -a -m "Prepare large commit" &&
+ echo "Changed" > 01-change &&
+ git mv 02-pure-rename-from 02-pure-rename-to &&
+ git rm 03-delete && rm -f 03-delete &&
+ echo "A new file" > 03-new &&
+ git add 03-new &&
+ git mv 04-rename-from 04-rename-to &&
+ echo "Changed" >> 04-rename-to &&
+ chmod a+x 05-mode-change &&
+ rm -f 06-file-or-symlink && ln -s 01-change 06-file-or-symlink &&
+ echo "Changed and have mode changed" > 07-change-mode-change &&
+ chmod a+x 07-change-mode-change &&
+ git commit -a -m "Large commit" &&
+ git checkout master'
+
+test_expect_success \
+ 'commit(1): large commit' \
+ 'gitweb_run "p=.git;a=commit;h=b"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'commitdiff(1): large commit' \
+ 'gitweb_run "p=.git;a=commitdiff;h=b"'
+test_debug 'cat gitweb.log'
+
+# ----------------------------------------------------------------------
+# tags testing
+
+test_expect_success \
+ 'tags: list of different types of tags' \
+ 'git checkout master &&
+ git tag -a -m "Tag commit object" tag-commit HEAD &&
+ git tag -a -m "" tag-commit-nomessage HEAD &&
+ git tag -a -m "Tag tag object" tag-tag tag-commit &&
+ git tag -a -m "Tag tree object" tag-tree HEAD^{tree} &&
+ git tag -a -m "Tag blob object" tag-blob HEAD:file &&
+ git tag lightweight/tag-commit HEAD &&
+ git tag lightweight/tag-tag tag-commit &&
+ git tag lightweight/tag-tree HEAD^{tree} &&
+ git tag lightweight/tag-blob HEAD:file &&
+ gitweb_run "p=.git;a=tags"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'tag: Tag to commit object' \
+ 'gitweb_run "p=.git;a=tag;h=tag-commit"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'tag: on lightweight tag (invalid)' \
+ 'gitweb_run "p=.git;a=tag;h=lightweight/tag-commit"'
+test_debug 'cat gitweb.log'
+
+# ----------------------------------------------------------------------
+# logs
+
+test_expect_success \
+ 'logs: log (implicit HEAD)' \
+ 'gitweb_run "p=.git;a=log"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'logs: shortlog (implicit HEAD)' \
+ 'gitweb_run "p=.git;a=shortlog"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'logs: history (implicit HEAD, file)' \
+ 'gitweb_run "p=.git;a=history;f=file"'
+test_debug 'cat gitweb.log'
+
+# ----------------------------------------------------------------------
+# feed generation
+
+test_expect_success \
+ 'feeds: OPML' \
+ 'gitweb_run "a=opml"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'feed: RSS' \
+ 'gitweb_run "p=.git;a=rss"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'feed: Atom' \
+ 'gitweb_run "p=.git;a=atom"'
+test_debug 'cat gitweb.log'
+
+# ----------------------------------------------------------------------
+# encoding/decoding
+
+test_expect_success \
+ 'encode(commit): utf8' \
+ '. ../t3901-utf8.txt &&
+ echo "UTF-8" >> file &&
+ git add file &&
+ git commit -F ../t3900/1-UTF-8.txt &&
+ gitweb_run "p=.git;a=commit"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'encode(commit): iso-8859-1' \
+ '. ../t3901-8859-1.txt &&
+ echo "ISO-8859-1" >> file &&
+ git add file &&
+ git config i18n.commitencoding ISO-8859-1 &&
+ git commit -F ../t3900/ISO-8859-1.txt &&
+ git config --unset i18n.commitencoding &&
+ gitweb_run "p=.git;a=commit"'
+test_debug 'cat gitweb.log'
+
+test_expect_success \
+ 'encode(log): utf-8 and iso-8859-1' \
+ 'gitweb_run "p=.git;a=log"'
+test_debug 'cat gitweb.log'
+
+test_done
diff --git a/t/test-lib.sh b/t/test-lib.sh
index dee3ad7..8bf4cf4 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -232,7 +232,7 @@ test_create_repo () {
mv .git/hooks .git/hooks-disabled
cd "$owd"
}
-
+
test_done () {
trap - exit
case "$test_failure" in
diff --git a/templates/hooks--commit-msg b/templates/hooks--commit-msg
index 9b04f2d..c5cdb9d 100644
--- a/templates/hooks--commit-msg
+++ b/templates/hooks--commit-msg
@@ -19,4 +19,3 @@ test "" = "$(grep '^Signed-off-by: ' "$1" |
echo >&2 Duplicate Signed-off-by lines.
exit 1
}
-
diff --git a/templates/hooks--post-receive b/templates/hooks--post-receive
index 190de26..b70c8fd 100644
--- a/templates/hooks--post-receive
+++ b/templates/hooks--post-receive
@@ -14,4 +14,3 @@
#. /usr/share/doc/git-core/contrib/hooks/post-receive-email
-
diff --git a/templates/hooks--pre-applypatch b/templates/hooks--pre-applypatch
index 5f56ce8..eeccc93 100644
--- a/templates/hooks--pre-applypatch
+++ b/templates/hooks--pre-applypatch
@@ -12,4 +12,3 @@
test -x "$GIT_DIR/hooks/pre-commit" &&
exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"}
:
-
diff --git a/templates/hooks--pre-commit b/templates/hooks--pre-commit
index 723a9ef..18b8730 100644
--- a/templates/hooks--pre-commit
+++ b/templates/hooks--pre-commit
@@ -68,4 +68,3 @@ perl -e '
}
exit($found_bad);
'
-
diff --git a/tree-walk.c b/tree-walk.c
index cbb24eb..8d4b673 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -206,4 +206,3 @@ int get_tree_entry(const unsigned char *tree_sha1, const char *name, unsigned ch
free(tree);
return retval;
}
-
diff --git a/tree.c b/tree.c
index e4a39aa..04fe653 100644
--- a/tree.c
+++ b/tree.c
@@ -157,7 +157,7 @@ static void track_tree_refs(struct tree *item)
/* Count how many entries there are.. */
init_tree_desc(&desc, item->buffer, item->size);
while (tree_entry(&desc, &entry)) {
- if (S_ISDIRLNK(entry.mode))
+ if (S_ISGITLINK(entry.mode))
continue;
n_refs++;
}
@@ -169,12 +169,17 @@ static void track_tree_refs(struct tree *item)
while (tree_entry(&desc, &entry)) {
struct object *obj;
- if (S_ISDIRLNK(entry.mode))
+ if (S_ISGITLINK(entry.mode))
continue;
if (S_ISDIR(entry.mode))
obj = &lookup_tree(entry.sha1)->object;
- else
+ else if (S_ISREG(entry.mode) || S_ISLNK(entry.mode))
obj = &lookup_blob(entry.sha1)->object;
+ else {
+ warning("in tree %s: entry %s has bad mode %.6o\n",
+ sha1_to_hex(item->object.sha1), entry.path, entry.mode);
+ obj = lookup_unknown_object(entry.sha1);
+ }
refs->ref[i++] = obj;
}
set_object_refs(&item->object, refs);
diff --git a/upload-pack.c b/upload-pack.c
index d3a09e7..fe96ef1 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -62,7 +62,7 @@ static ssize_t send_client_data(int fd, const char *data, ssize_t sz)
return safe_write(fd, data, sz);
}
-FILE *pack_pipe = NULL;
+static FILE *pack_pipe = NULL;
static void show_commit(struct commit *commit)
{
if (commit->object.flags & BOUNDARY)
@@ -678,7 +678,7 @@ int main(int argc, char **argv)
break;
}
}
-
+
if (i != argc-1)
usage(upload_pack_usage);
dir = argv[i];
diff --git a/var.c b/var.c
index e585e59..4127031 100644
--- a/var.c
+++ b/var.c
@@ -67,8 +67,8 @@ int main(int argc, char **argv)
val = read_var(argv[1]);
if (!val)
usage(var_usage);
-
+
printf("%s\n", val);
-
+
return 0;
}
diff --git a/wt-status.c b/wt-status.c
index 4bfe8f1..5205420 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -198,7 +198,7 @@ static void wt_read_cache(struct wt_status *s)
read_cache();
}
-void wt_status_print_initial(struct wt_status *s)
+static void wt_status_print_initial(struct wt_status *s)
{
int i;
char buf[PATH_MAX];
diff --git a/xdiff-interface.c b/xdiff-interface.c
index 10816e9..e407cf1 100644
--- a/xdiff-interface.c
+++ b/xdiff-interface.c
@@ -122,4 +122,10 @@ int read_mmfile(mmfile_t *ptr, const char *filename)
return 0;
}
-
+#define FIRST_FEW_BYTES 8000
+int buffer_is_binary(const char *ptr, unsigned long size)
+{
+ if (FIRST_FEW_BYTES < size)
+ size = FIRST_FEW_BYTES;
+ return !!memchr(ptr, 0, size);
+}
diff --git a/xdiff-interface.h b/xdiff-interface.h
index 1918808..536f4e4 100644
--- a/xdiff-interface.h
+++ b/xdiff-interface.h
@@ -18,5 +18,6 @@ int parse_hunk_header(char *line, int len,
int *ob, int *on,
int *nb, int *nn);
int read_mmfile(mmfile_t *ptr, const char *filename);
+int buffer_is_binary(const char *ptr, unsigned long size);
#endif
diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h
index e874a7c..9402bb0 100644
--- a/xdiff/xdiff.h
+++ b/xdiff/xdiff.h
@@ -103,4 +103,3 @@ int xdl_merge(mmfile_t *orig, mmfile_t *mf1, const char *name1,
#endif /* #ifdef __cplusplus */
#endif /* #if !defined(XDIFF_H) */
-
diff --git a/xdiff/xdiffi.c b/xdiff/xdiffi.c
index 9aeebc4..5cb7171 100644
--- a/xdiff/xdiffi.c
+++ b/xdiff/xdiffi.c
@@ -565,4 +565,3 @@ int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
return 0;
}
-
diff --git a/xdiff/xdiffi.h b/xdiff/xdiffi.h
index 472aeae..3e099dc 100644
--- a/xdiff/xdiffi.h
+++ b/xdiff/xdiffi.h
@@ -57,4 +57,3 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
xdemitconf_t const *xecfg);
#endif /* #if !defined(XDIFFI_H) */
-
diff --git a/xdiff/xemit.c b/xdiff/xemit.c
index e291dc7..4b6e639 100644
--- a/xdiff/xemit.c
+++ b/xdiff/xemit.c
@@ -99,8 +99,8 @@ static void xdl_find_func(xdfile_t *xf, long i, char *buf, long sz, long *ll) {
}
-int xdl_emit_common(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
- xdemitconf_t const *xecfg) {
+static int xdl_emit_common(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
+ xdemitconf_t const *xecfg) {
xdfile_t *xdf = &xe->xdf1;
const char *rchg = xdf->rchg;
long ix;
@@ -194,4 +194,3 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
return 0;
}
-
diff --git a/xdiff/xemit.h b/xdiff/xemit.h
index e629417..440a739 100644
--- a/xdiff/xemit.h
+++ b/xdiff/xemit.h
@@ -31,4 +31,3 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
#endif /* #if !defined(XEMIT_H) */
-
diff --git a/xdiff/xinclude.h b/xdiff/xinclude.h
index 04a9da8..526ccb3 100644
--- a/xdiff/xinclude.h
+++ b/xdiff/xinclude.h
@@ -40,4 +40,3 @@
#endif /* #if !defined(XINCLUDE_H) */
-
diff --git a/xdiff/xmacros.h b/xdiff/xmacros.h
index e2cd202..8ef232c 100644
--- a/xdiff/xmacros.h
+++ b/xdiff/xmacros.h
@@ -51,4 +51,3 @@ do { \
#endif /* #if !defined(XMACROS_H) */
-
diff --git a/xdiff/xprepare.c b/xdiff/xprepare.c
index 1be7b31..e87ab57 100644
--- a/xdiff/xprepare.c
+++ b/xdiff/xprepare.c
@@ -466,4 +466,3 @@ static int xdl_optimize_ctxs(xdfile_t *xdf1, xdfile_t *xdf2) {
return 0;
}
-
diff --git a/xdiff/xprepare.h b/xdiff/xprepare.h
index 344c569..8fb06a5 100644
--- a/xdiff/xprepare.h
+++ b/xdiff/xprepare.h
@@ -32,4 +32,3 @@ void xdl_free_env(xdfenv_t *xe);
#endif /* #if !defined(XPREPARE_H) */
-
diff --git a/xdiff/xtypes.h b/xdiff/xtypes.h
index 3593a66..2511aef 100644
--- a/xdiff/xtypes.h
+++ b/xdiff/xtypes.h
@@ -65,4 +65,3 @@ typedef struct s_xdfenv {
#endif /* #if !defined(XTYPES_H) */
-
diff --git a/xdiff/xutils.c b/xdiff/xutils.c
index bf91c0f..2ade97b 100644
--- a/xdiff/xutils.c
+++ b/xdiff/xutils.c
@@ -380,4 +380,3 @@ int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2,
return 0;
}
-
diff --git a/xdiff/xutils.h b/xdiff/xutils.h
index 70d8b98..d5de829 100644
--- a/xdiff/xutils.h
+++ b/xdiff/xutils.h
@@ -45,4 +45,3 @@ int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2,
#endif /* #if !defined(XUTILS_H) */
-