Merge branch 'jk/ref-array-push'
authorJunio C Hamano <gitster@pobox.com>
Wed, 25 Apr 2018 04:28:59 +0000 (13:28 +0900)
committerJunio C Hamano <gitster@pobox.com>
Wed, 25 Apr 2018 04:28:59 +0000 (13:28 +0900)
API clean-up aournd ref-filter code.

* jk/ref-array-push:
ref-filter: factor ref_array pushing into its own function
ref-filter: make ref_array_item allocation more consistent
ref-filter: use "struct object_id" consistently

364 files changed:
Documentation/RelNotes/2.18.0.txt [new file with mode: 0644]
Documentation/config.txt
Documentation/diff-options.txt
Documentation/git-bisect.txt
Documentation/git-fetch-pack.txt
Documentation/git-filter-branch.txt
Documentation/git-for-each-ref.txt
Documentation/git-gc.txt
Documentation/git-mktree.txt
Documentation/git-rebase.txt
Documentation/git-send-email.txt
Documentation/git-shortlog.txt
Documentation/git-status.txt
Documentation/git-svn.txt
Documentation/gitrepository-layout.txt
Documentation/howto/recover-corrupted-object-harder.txt
Documentation/technical/api-directory-listing.txt
Documentation/technical/hash-function-transition.txt
GIT-VERSION-GEN
Makefile
RelNotes
apply.c
archive-tar.c
archive-zip.c
archive.c
archive.h
bisect.c
blame.c
builtin/am.c
builtin/blame.c
builtin/branch.c
builtin/cat-file.c
builtin/checkout.c
builtin/clone.c
builtin/commit-tree.c
builtin/commit.c
builtin/count-objects.c
builtin/describe.c
builtin/difftool.c
builtin/fast-export.c
builtin/fetch.c
builtin/fmt-merge-msg.c
builtin/fsck.c
builtin/gc.c
builtin/grep.c
builtin/index-pack.c
builtin/log.c
builtin/ls-files.c
builtin/ls-tree.c
builtin/merge-tree.c
builtin/merge.c
builtin/mktag.c
builtin/mktree.c
builtin/name-rev.c
builtin/notes.c
builtin/pack-objects.c
builtin/pack-redundant.c
builtin/prune.c
builtin/receive-pack.c
builtin/reflog.c
builtin/replace.c
builtin/reset.c
builtin/rev-list.c
builtin/rev-parse.c
builtin/rm.c
builtin/shortlog.c
builtin/show-branch.c
builtin/show-ref.c
builtin/submodule--helper.c
builtin/tag.c
builtin/unpack-file.c
builtin/unpack-objects.c
builtin/update-index.c
builtin/verify-commit.c
builtin/worktree.c
builtin/write-tree.c
bulk-checkin.c
bulk-checkin.h
bundle.c
cache-tree.c
cache-tree.h
cache.h
chdir-notify.c [new file with mode: 0644]
chdir-notify.h [new file with mode: 0644]
combine-diff.c
commit.c
common-main.c
config.c
configure.ac
contrib/completion/git-completion.bash
contrib/diff-highlight/DiffHighlight.pm
contrib/diff-highlight/t/t9400-diff-highlight.sh
contrib/examples/README
contrib/examples/builtin-fetch--tool.c [deleted file]
contrib/examples/git-am.sh [deleted file]
contrib/examples/git-checkout.sh [deleted file]
contrib/examples/git-clean.sh [deleted file]
contrib/examples/git-clone.sh [deleted file]
contrib/examples/git-commit.sh [deleted file]
contrib/examples/git-difftool.perl [deleted file]
contrib/examples/git-fetch.sh [deleted file]
contrib/examples/git-gc.sh [deleted file]
contrib/examples/git-log.sh [deleted file]
contrib/examples/git-ls-remote.sh [deleted file]
contrib/examples/git-merge-ours.sh [deleted file]
contrib/examples/git-merge.sh [deleted file]
contrib/examples/git-notes.sh [deleted file]
contrib/examples/git-pull.sh [deleted file]
contrib/examples/git-remote.perl [deleted file]
contrib/examples/git-repack.sh [deleted file]
contrib/examples/git-rerere.perl [deleted file]
contrib/examples/git-reset.sh [deleted file]
contrib/examples/git-resolve.sh [deleted file]
contrib/examples/git-revert.sh [deleted file]
contrib/examples/git-svnimport.perl [deleted file]
contrib/examples/git-svnimport.txt [deleted file]
contrib/examples/git-tag.sh [deleted file]
contrib/examples/git-verify-tag.sh [deleted file]
contrib/examples/git-whatchanged.sh [deleted file]
convert.c
convert.h
credential.c
daemon.c
diff.c
dir.c
entry.c
environment.c
fast-import.c
fetch-pack.c
fsck.c
git-filter-branch.sh
git-gui/git-gui.sh
git-gui/lib/sshkey.tcl
git-gui/lib/themed.tcl
git-rebase--am.sh
git-rebase--interactive.sh
git-rebase--merge.sh
git-rebase.sh
git-stash.sh
git-svn.perl
git.c
grep.c
http-backend.c
http-push.c
http-walker.c
http.c
line-log.c
list-objects-filter.c
log-tree.c
mailmap.c
match-trees.c
merge-blobs.c
merge-recursive.c
mergetools/guiffy [new file with mode: 0644]
notes-cache.c
notes-merge.c
notes.c
object-store.h [new file with mode: 0644]
object.c
pack-bitmap-write.c
pack-bitmap.c
pack-check.c
pack-revindex.c
packfile.c
packfile.h
parse-options.c
parse-options.h
path.c
perl/Git/SVN.pm
pretty.c
reachable.c
read-cache.c
ref-filter.c
refs.c
refs/files-backend.c
refs/packed-backend.c
remote-testsvn.c
remote.c
replace_object.c
repository.c
repository.h
rerere.c
resolve-undo.c
resolve-undo.h
run-command.c
send-pack.c
sequencer.c
server-info.c
setup.c
sha1_file.c
sha1_name.c
strbuf.c
strbuf.h
streaming.c
streaming.h
submodule-config.c
submodule.c
t/helper/test-chmtime.c
t/helper/test-config.c
t/helper/test-ctype.c
t/helper/test-date.c
t/helper/test-delta.c
t/helper/test-drop-caches.c
t/helper/test-dump-cache-tree.c
t/helper/test-dump-split-index.c
t/helper/test-example-decorate.c
t/helper/test-genrandom.c
t/helper/test-hashmap.c
t/helper/test-index-version.c
t/helper/test-lazy-init-name-hash.c
t/helper/test-match-trees.c
t/helper/test-mergesort.c
t/helper/test-mktemp.c
t/helper/test-online-cpus.c
t/helper/test-path-utils.c
t/helper/test-prio-queue.c
t/helper/test-read-cache.c
t/helper/test-ref-store.c
t/helper/test-regex.c
t/helper/test-revision-walking.c
t/helper/test-run-command.c
t/helper/test-scrap-cache-tree.c
t/helper/test-sha1-array.c
t/helper/test-sha1.c
t/helper/test-sha1.sh
t/helper/test-sigchain.c
t/helper/test-strcmp-offset.c
t/helper/test-string-list.c
t/helper/test-submodule-config.c
t/helper/test-subprocess.c
t/helper/test-tool.c [new file with mode: 0644]
t/helper/test-tool.h [new file with mode: 0644]
t/helper/test-urlmatch-normalization.c
t/helper/test-wildmatch.c
t/helper/test-write-cache.c
t/lib-git-p4.sh
t/lib-git-svn.sh
t/lib-pack.sh
t/perf/aggregate.perl
t/perf/p0002-read-cache.sh
t/perf/p0004-lazy-init-name-hash.sh
t/perf/p0007-write-cache.sh
t/perf/p0071-sort.sh
t/perf/p7519-fsmonitor.sh
t/t0005-signals.sh
t/t0006-date.sh
t/t0009-prio-queue.sh
t/t0011-hashmap.sh
t/t0013-sha1dc.sh
t/t0021-conversion.sh
t/t0040-parse-options.sh
t/t0041-usage.sh [new file with mode: 0755]
t/t0060-path-utils.sh
t/t0061-run-command.sh
t/t0062-revision-walking.sh
t/t0063-string-list.sh
t/t0064-sha1-array.sh
t/t0065-strcmp-offset.sh
t/t0070-fundamental.sh
t/t0090-cache-tree.sh
t/t0110-urlmatch-normalization.sh
t/t1006-cat-file.sh
t/t1011-read-tree-sparse-checkout.sh
t/t1050-large.sh
t/t1300-repo-config.sh
t/t1304-default-acl.sh
t/t1305-config-include.sh
t/t1308-config-set.sh
t/t1309-early-config.sh
t/t1405-main-ref-store.sh
t/t1406-submodule-ref-store.sh
t/t1407-worktree-ref-store.sh
t/t1411-reflog-show.sh
t/t1501-work-tree.sh
t/t1507-rev-parse-upstream.sh
t/t1600-index.sh
t/t1700-split-index.sh
t/t2020-checkout-detach.sh
t/t2022-checkout-paths.sh
t/t2026-worktree-prune.sh
t/t2028-worktree-move.sh
t/t2101-update-index-reupdate.sh
t/t2104-update-index-skip-worktree.sh
t/t2107-update-index-basic.sh
t/t3008-ls-files-lazy-init-name-hash.sh
t/t3070-wildmatch.sh
t/t3200-branch.sh
t/t3306-notes-prune.sh
t/t3404-rebase-interactive.sh
t/t3418-rebase-continue.sh
t/t3421-rebase-topology-linear.sh
t/t3428-rebase-signoff.sh
t/t3501-revert-cherry-pick.sh
t/t3510-cherry-pick-sequence.sh
t/t3600-rm.sh
t/t3700-add.sh
t/t3905-stash-include-untracked.sh
t/t4011-diff-symlink.sh
t/t4013-diff-various.sh
t/t4035-diff-quiet.sh
t/t4151-am-abort.sh
t/t4200-rerere.sh
t/t4201-shortlog.sh
t/t5000-tar-tree.sh
t/t5300-pack-object.sh
t/t5301-sliding-window.sh
t/t5302-pack-index.sh
t/t5303-pack-corruption-resilience.sh
t/t5304-prune.sh
t/t5310-pack-bitmaps.sh
t/t5313-pack-bounds-checks.sh
t/t5314-pack-cycle-detection.sh
t/t5316-pack-delta-depth.sh
t/t5400-send-pack.sh
t/t5510-fetch.sh
t/t5516-fetch-push.sh
t/t5546-receive-limits.sh
t/t5547-push-quarantine.sh
t/t5561-http-backend.sh
t/t5608-clone-2gb.sh
t/t6022-merge-rename.sh
t/t6500-gc.sh
t/t6501-freshen-objects.sh
t/t7001-mv.sh
t/t7003-filter-branch.sh
t/t7400-submodule-basic.sh
t/t7411-submodule-config.sh
t/t7501-commit.sh
t/t7508-status.sh
t/t7701-repack-unpack-unreachable.sh
t/t7812-grep-icase-non-ascii.sh
t/t9004-example.sh
t/t9100-git-svn-basic.sh
t/t9104-git-svn-follow-parent.sh
t/t9108-git-svn-glob.sh
t/t9109-git-svn-multi-glob.sh
t/t9110-git-svn-use-svm-props.sh
t/t9111-git-svn-use-svnsync-props.sh
t/t9114-git-svn-dcommit-merge.sh
t/t9130-git-svn-authors-file.sh
t/t9138-git-svn-authors-prog.sh
t/t9153-git-svn-rewrite-uuid.sh
t/t9168-git-svn-partially-globbed-names.sh
t/t9300-fast-import.sh
t/t9350-fast-export.sh
t/t9802-git-p4-filetype.sh
t/t9803-git-p4-shell-metachars.sh
t/t9813-git-p4-preserve-users.sh
t/t9820-git-p4-editor-handling.sh
t/t9902-completion.sh
t/test-lib-functions.sh
t/test-lib.sh
tag.c
tmp-objdir.c
trace.c
trace.h
transport.c
tree-walk.c
tree-walk.h
tree.c
tree.h
wt-status.c
wt-status.h
xdiff-interface.c
diff --git a/Documentation/RelNotes/2.18.0.txt b/Documentation/RelNotes/2.18.0.txt
new file mode 100644 (file)
index 0000000..5f16516
--- /dev/null
@@ -0,0 +1,122 @@
+Git 2.18 Release Notes
+======================
+
+Updates since v2.17
+-------------------
+
+UI, Workflows & Features
+
+ * Rename detection logic in "diff" family that is used in "merge" has
+   learned to guess when all of x/a, x/b and x/c have moved to z/a,
+   z/b and z/c, it is likely that x/d added in the meantime would also
+   want to move to z/d by taking the hint that the entire directory
+   'x' moved to 'z'.  A bug causing dirty files involved in a rename
+   to be overwritten during merge has also been fixed as part of this
+   work.
+
+ * "git filter-branch" learned to use a different exit code to allow
+   the callers to tell the case where there was no new commits to
+   rewrite from other error cases.
+
+ * When built with more recent cURL, GIT_SSL_VERSION can now specify
+   "tlsv1.3" as its value.
+
+
+Performance, Internal Implementation, Development Support etc.
+
+ * A "git fetch" from a repository with insane number of refs into a
+   repository that is already up-to-date still wasted too many cycles
+   making many lstat(2) calls to see if these objects at the tips
+   exist as loose objects locally.  These lstat(2) calls are optimized
+   away by enumerating all loose objects beforehand.
+   It is unknown if the new strategy negatively affects existing use
+   cases, fetching into a repository with many loose objects from a
+   repository with small number of refs.
+
+ * Git can be built to use either v1 or v2 of the PCRE library, and so
+   far, the build-time configuration USE_LIBPCRE=YesPlease instructed
+   the build procedure to use v1, but now it means v2.  USE_LIBPCRE1
+   and USE_LIBPCRE2 can be used to explicitly choose which version to
+   use, as before.
+
+ * The build procedure learned to optionally use symbolic links
+   (instead of hardlinks and copies) to install "git-foo" for built-in
+   commands, whose binaries are all identical.
+
+ * Conversion from uchar[20] to struct object_id continues.
+
+ * The way "git worktree prune" worked internally has been simplified,
+   by assuming how "git worktree move" moves an existing worktree to a
+   different place.
+
+ * Code clean-up for the "repository" abstraction.
+   (merge 00a3da2a13 nd/remove-ignore-env-field later to maint).
+
+ * Code to find the length to uniquely abbreviate object names based
+   on packfile content, which is a relatively recent addtion, has been
+   optimized to use the same fan-out table.
+
+ * The mechanism to use parse-options API to automate the command line
+   completion continues to get extended and polished.
+
+ * Copies of old scripted Porcelain commands in contrib/examples/ have
+   been removed.
+
+ * Some tests that rely on the exact hardcoded values of object names
+   have been updated in preparation for hash function migration.
+
+ * Perf-test update.
+
+ * Test helper update.
+
+ * The effort continues to refactor the internal global data structure
+   to make it possible to open multiple repositories, work with and
+   then close them,
+
+ * Small test-helper programs have been consolidated into a single
+   binary.
+
+Also contains various documentation updates and code clean-ups.
+
+
+Fixes since v2.17
+-----------------
+
+ * "git shortlog cruft" aborted with a BUG message when run outside a
+   Git repository.  The command has been taught to complain about
+   extra and unwanted arguments on its command line instead in such a
+   case.
+   (merge 4aa0161e83 ma/shortlog-revparse later to maint).
+
+ * "git stash push -u -- <pathspec>" gave an unnecessary and confusing
+   error message when there was no tracked files that match the
+   <pathspec>, which has been fixed.
+   (merge 353278687e tg/stash-untracked-with-pathspec-fix later to maint).
+
+ * "git tag --contains no-such-commit" gave a full list of options
+   after giving an error message.
+   (merge 3bb0923f06 ps/contains-id-error-message later to maint).
+
+ * "diff-highlight" filter (in contrib/) learned to undertand "git log
+   --graph" output better.
+   (merge 4551fbba14 jk/diff-highlight-graph-fix later to maint).
+
+ * when refs that do not point at committish are given, "git
+   filter-branch" gave a misleading error messages.  This has been
+   corrected.
+   (merge f78ab355e7 yk/filter-branch-non-committish-refs later to maint).
+
+ * "git submodule status" misbehaved on a submodule that has been
+   removed from the working tree.
+   (merge 74b6bda32f rs/status-with-removed-submodule later to maint).
+
+ * When credential helper exits very quickly without reading its
+   input, it used to cause Git to die with SIGPIPE, which has been
+   fixed.
+   (merge a0d51e8d0e eb/cred-helper-ignore-sigpipe later to maint).
+
+ * Other minor doc, test and build updates and code cleanups.
+   (merge 248f66ed8e nd/trace-with-env later to maint).
+   (merge 14ced5562c ys/bisect-object-id-missing-conversion-fix later to maint).
+   (merge 5988eb631a ab/doc-hash-brokenness later to maint).
+   (merge a4d4e32a70 pk/test-avoid-pipe-hiding-exit-status later to maint).
index 4e0cff87f62f5d5c320e3dcea03f646416604bca..2659153cb377554bc5cf6fc4199233b2bab498a2 100644 (file)
@@ -1957,6 +1957,7 @@ http.sslVersion::
        - tlsv1.0
        - tlsv1.1
        - tlsv1.2
+       - tlsv1.3
 
 +
 Can be overridden by the `GIT_SSL_VERSION` environment variable.
index e3a44f03cdcee92098287bfccc9801fde042ef2b..f466600972f86df57648eaab6dccf52289febda9 100644 (file)
@@ -568,7 +568,7 @@ the normal order.
 --
 +
 Patterns have the same syntax and semantics as patterns used for
-fnmantch(3) without the FNM_PATHNAME flag, except a pathname also
+fnmatch(3) without the FNM_PATHNAME flag, except a pathname also
 matches a pattern if removing any number of the final pathname
 components matches the pattern.  For example, the pattern "`foo*bar`"
 matches "`fooasdfbar`" and "`foo/bar/baz/asdf`" but not "`foobarx`".
@@ -592,7 +592,7 @@ endif::git-format-patch[]
        Treat all files as text.
 
 --ignore-cr-at-eol::
-       Ignore carrige-return at the end of line when doing a comparison.
+       Ignore carriage-return at the end of line when doing a comparison.
 
 --ignore-space-at-eol::
        Ignore changes in whitespace at EOL.
index 4a1417bdcd7826d444dbfd4cbc438ec9ec2edf1b..4b45d837a7e7c590fe3aa5f575009c43342b833c 100644 (file)
@@ -165,8 +165,8 @@ To get a reminder of the currently used terms, use
 git bisect terms
 ------------------------------------------------
 
-You can get just the old (respectively new) term with `git bisect term
---term-old` or `git bisect term --term-good`.
+You can get just the old (respectively new) term with `git bisect terms
+--term-old` or `git bisect terms --term-good`.
 
 If you would like to use your own terms instead of "bad"/"good" or
 "new"/"old", you can choose any names you like (except existing bisect
index f7ebe36a7b2c203e0b2f320309a5ce6250b12471..c9758847937e7db9fb3c4c3a498f5074e9e1f5d9 100644 (file)
@@ -88,7 +88,7 @@ be in a separate packet, and the list must end with a flush packet.
        infinite even if there is an ancestor-chain that long.
 
 --shallow-since=<date>::
-       Deepen or shorten the history of a shallow'repository to
+       Deepen or shorten the history of a shallow repository to
        include all reachable commits after <date>.
 
 --shallow-exclude=<revision>::
index 3a52e4dce39eeaf6eba896ccbf9e0505cebb3ec9..b634043183b453a89b3f56e0544503b06ccdbdec 100644 (file)
@@ -222,6 +222,14 @@ this purpose, they are instead rewritten to point at the nearest ancestor that
 was not excluded.
 
 
+EXIT STATUS
+-----------
+
+On success, the exit status is `0`.  If the filter can't find any commits to
+rewrite, the exit status is `2`.  On any other error, the exit status may be
+any other non-zero value.
+
+
 Examples
 --------
 
index dffa14a7950e074bbff73ec79defdbbdcc9702be..085d177d976546a0b21891884e490c9ce7530913 100644 (file)
@@ -121,7 +121,7 @@ refname::
        stripping with positive <N>, or it becomes the full refname if
        stripping with negative <N>.  Neither is an error.
 +
-`strip` can be used as a synomym to `lstrip`.
+`strip` can be used as a synonym to `lstrip`.
 
 objecttype::
        The type of the object (`blob`, `tree`, `commit`, `tag`).
index 571b5a7e3c9dbc11aafc194b6e08dbbed5b2f7d3..3126e0dd002eca7ac420932bb9d1ace63752e8dc 100644 (file)
@@ -15,8 +15,9 @@ DESCRIPTION
 -----------
 Runs a number of housekeeping tasks within the current repository,
 such as compressing file revisions (to reduce disk space and increase
-performance) and removing unreachable objects which may have been
-created from prior invocations of 'git add'.
+performance), removing unreachable objects which may have been
+created from prior invocations of 'git add', packing refs, pruning
+reflog, rerere metadata or stale working trees.
 
 Users are encouraged to run this task on a regular basis within
 each repository to maintain good disk space utilization and good
@@ -45,20 +46,25 @@ OPTIONS
        With this option, 'git gc' checks whether any housekeeping is
        required; if not, it exits without performing any work.
        Some git commands run `git gc --auto` after performing
-       operations that could create many loose objects.
+       operations that could create many loose objects. Housekeeping
+       is required if there are too many loose objects or too many
+       packs in the repository.
 +
-Housekeeping is required if there are too many loose objects or
-too many packs in the repository. If the number of loose objects
-exceeds the value of the `gc.auto` configuration variable, then
-all loose objects are combined into a single pack using
-`git repack -d -l`.  Setting the value of `gc.auto` to 0
-disables automatic packing of loose objects.
+If the number of loose objects exceeds the value of the `gc.auto`
+configuration variable, then all loose objects are combined into a
+single pack using `git repack -d -l`.  Setting the value of `gc.auto`
+to 0 disables automatic packing of loose objects.
 +
 If the number of packs exceeds the value of `gc.autoPackLimit`,
 then existing packs (except those marked with a `.keep` file)
 are consolidated into a single pack by using the `-A` option of
 'git repack'. Setting `gc.autoPackLimit` to 0 disables
 automatic consolidation of packs.
++
+If houskeeping is required due to many loose objects or packs, all
+other housekeeping tasks (e.g. rerere, working trees, reflog...) will
+be performed as well.
+
 
 --prune=<date>::
        Prune loose objects older than date (default is 2 weeks ago,
@@ -133,6 +139,10 @@ The optional configuration variable `gc.pruneExpire` controls how old
 the unreferenced loose objects have to be before they are pruned.  The
 default is "2 weeks ago".
 
+Optional configuration variable `gc.worktreePruneExpire` controls how
+old a stale working tree should be before `git worktree prune` deletes
+it. Default is "3 months ago".
+
 
 Notes
 -----
index c3616e7711aef80ee7e2bd3bb90ea5cee7dd1d4b..27fe2b32e10b2f0c92315483ac4a5e8a9722d3db 100644 (file)
@@ -14,7 +14,7 @@ SYNOPSIS
 DESCRIPTION
 -----------
 Reads standard input in non-recursive `ls-tree` output format, and creates
-a tree object.  The order of the tree entries is normalised by mktree so
+a tree object.  The order of the tree entries is normalized by mktree so
 pre-sorting the input is not required.  The object name of the tree object
 built is written to the standard output.
 
index 3277ca143273e01f5f4973ed351c8a5cb4b8e0fa..dd852068b1d06f8f40566da65579564144fef718 100644 (file)
@@ -364,9 +364,10 @@ default is `--no-fork-point`, otherwise the default is `--fork-point`.
        Incompatible with the --interactive option.
 
 --signoff::
-       This flag is passed to 'git am' to sign off all the rebased
-       commits (see linkgit:git-am[1]). Incompatible with the
-       --interactive option.
+       Add a Signed-off-by: trailer to all the rebased commits. Note
+       that if `--interactive` is given then only commits marked to be
+       picked, edited or reworded will have the trailer added. Incompatible
+       with the `--preserve-merges` option.
 
 -i::
 --interactive::
index 71ef97ba9b22aad996049bd0c1500a835a433350..60cf96f4c1405e956f6cbbe9ca35959710a46d70 100644 (file)
@@ -255,7 +255,7 @@ must be used for each option.
 
 --batch-size=<num>::
        Some email servers (e.g. smtp.163.com) limit the number emails to be
-       sent per session (connection) and this will lead to a faliure when
+       sent per session (connection) and this will lead to a failure when
        sending many messages.  With this option, send-email will disconnect after
        sending $<num> messages and wait for a few seconds (see --relogin-delay)
        and reconnect, to work around such a limit.  You may want to
@@ -473,16 +473,7 @@ edit ~/.gitconfig to specify your account settings:
 
 If you have multifactor authentication setup on your gmail account, you will
 need to generate an app-specific password for use with 'git send-email'. Visit
-https://security.google.com/settings/security/apppasswords to setup an
-app-specific password.  Once setup, you can store it with the credentials
-helper:
-
-       $ git credential fill
-       protocol=smtp
-       host=smtp.gmail.com
-       username=youname@gmail.com
-       password=app-password
-
+https://security.google.com/settings/security/apppasswords to create it.
 
 Once your commits are ready to be sent to the mailing list, run the
 following commands:
@@ -491,6 +482,11 @@ following commands:
        $ edit outgoing/0000-*
        $ git send-email outgoing/*
 
+The first time you run it, you will be prompted for your credentials.  Enter the
+app-specific or your regular password as appropriate.  If you have credential
+helper configured (see linkgit:git-credential[1]), the password will be saved in
+the credential store so you won't have to type it the next time.
+
 Note: the following perl modules are required
       Net::SMTP::SSL, MIME::Base64 and Authen::SASL
 
index ee6c5476c1d2bf3b2a708e6152ebaba5882cc4f7..5e35ea18acd790469735400644358af9843b6c99 100644 (file)
@@ -8,8 +8,8 @@ git-shortlog - Summarize 'git log' output
 SYNOPSIS
 --------
 [verse]
-git log --pretty=short | 'git shortlog' [<options>]
 'git shortlog' [<options>] [<revision range>] [[\--] <path>...]
+git log --pretty=short | 'git shortlog' [<options>]
 
 DESCRIPTION
 -----------
index 6c230c0c7200412b988d233352e3411a9fb813a8..c16e27e63d4cf6522d29c9d0ff099e06cfcd38a4 100644 (file)
@@ -113,7 +113,7 @@ The possible options are:
        - 'matching'    - Shows ignored files and directories matching an
                          ignore pattern.
 +
-When 'matching' mode is specified, paths that explicity match an
+When 'matching' mode is specified, paths that explicitly match an
 ignored pattern are shown. If a directory matches an ignore pattern,
 then it is shown, but not paths contained in the ignored directory. If
 a directory does not match an ignore pattern, but all contents are
index 636e09048e8846b813166737ef58eef96eb3a3c4..d59379ee2344690926f5e0bee282c81445d3061d 100644 (file)
@@ -635,7 +635,8 @@ config key: svn.findcopiesharder
 
 -A<filename>::
 --authors-file=<filename>::
-       Syntax is compatible with the file used by 'git cvsimport':
+       Syntax is compatible with the file used by 'git cvsimport' but
+       an empty email address can be supplied with '<>':
 +
 ------------------------------------------------------------------------
        loginname = Joe User <user@example.com>
@@ -654,8 +655,14 @@ config key: svn.authorsfile
        If this option is specified, for each SVN committer name that
        does not exist in the authors file, the given file is executed
        with the committer name as the first argument.  The program is
-       expected to return a single line of the form "Name <email>",
-       which will be treated as if included in the authors file.
+       expected to return a single line of the form "Name <email>" or
+       "Name <>", which will be treated as if included in the authors
+       file.
++
+Due to historical reasons a relative 'filename' is first searched
+relative to the current directory for 'init' and 'clone' and relative
+to the root of the working tree for 'fetch'. If 'filename' is
+not found, it is searched like any other command in '$PATH'.
 +
 [verse]
 config key: svn.authorsProg
index c60bcad44aa581b2449a7a638b6487c1c73e8c23..e85148f05eb79a968ad84bac6ce7a88289270c49 100644 (file)
@@ -275,11 +275,6 @@ worktrees/<id>/locked::
        or manually by `git worktree prune`. The file may contain a string
        explaining why the repository is locked.
 
-worktrees/<id>/link::
-       If this file exists, it is a hard link to the linked .git
-       file. It is used to detect if the linked repository is
-       manually removed.
-
 SEE ALSO
 --------
 linkgit:git-init[1],
index 9c4cd0915fe3f3e14879184f3a474e559130bdef..8994e2559eac0c5746ca898b0bad1946a7b83298 100644 (file)
@@ -80,7 +80,7 @@ valid pack like:
     # now add our object data
     cat object >>tmp.pack
     # and then append the pack trailer
-    /path/to/git.git/test-sha1 -b <tmp.pack >trailer
+    /path/to/git.git/t/helper/test-tool sha1 -b <tmp.pack >trailer
     cat trailer >>tmp.pack
 ------------
 
index 7fae00f44fe1798da82bfdbb902479a03d583843..4f44ca24f6457e6acf208d7068dfcd02039cf41b 100644 (file)
@@ -53,7 +53,7 @@ The notable options are:
        not be returned even if all of its contents are ignored. In
        this case, the contents are returned as individual entries.
 +
-If this is set, files and directories that explicity match an ignore
+If this is set, files and directories that explicitly match an ignore
 pattern are reported. Implicity ignored directories (directories that
 do not match an ignore pattern, but whose contents are all ignored)
 are not reported, instead all of the contents are reported.
index 417ba491d0f3fa06b60a47623a5f756919adcbd6..4ab6cd1012abae711acf02e6a76ee93eae86a1ad 100644 (file)
@@ -28,11 +28,30 @@ advantages:
   address stored content.
 
 Over time some flaws in SHA-1 have been discovered by security
-researchers. https://shattered.io demonstrated a practical SHA-1 hash
-collision. As a result, SHA-1 cannot be considered cryptographically
-secure any more. This impacts the communication of hash values because
-we cannot trust that a given hash value represents the known good
-version of content that the speaker intended.
+researchers. On 23 February 2017 the SHAttered attack
+(https://shattered.io) demonstrated a practical SHA-1 hash collision.
+
+Git v2.13.0 and later subsequently moved to a hardened SHA-1
+implementation by default, which isn't vulnerable to the SHAttered
+attack.
+
+Thus Git has in effect already migrated to a new hash that isn't SHA-1
+and doesn't share its vulnerabilities, its new hash function just
+happens to produce exactly the same output for all known inputs,
+except two PDFs published by the SHAttered researchers, and the new
+implementation (written by those researchers) claims to detect future
+cryptanalytic collision attacks.
+
+Regardless, it's considered prudent to move past any variant of SHA-1
+to a new hash. There's no guarantee that future attacks on SHA-1 won't
+be published in the future, and those attacks may not have viable
+mitigations.
+
+If SHA-1 and its variants were to be truly broken, Git's hash function
+could not be considered cryptographically secure any more. This would
+impact the communication of hash values because we could not trust
+that a given hash value represented the known good version of content
+that the speaker intended.
 
 SHA-1 still possesses the other properties such as fast object lookup
 and safe error checking, but other hash functions are equally suitable
@@ -116,10 +135,15 @@ Documentation/technical/repository-version.txt) with extensions
                objectFormat = newhash
                compatObjectFormat = sha1
 
-Specifying a repository format extension ensures that versions of Git
-not aware of NewHash do not try to operate on these repositories,
-instead producing an error message:
+The combination of setting `core.repositoryFormatVersion=1` and
+populating `extensions.*` ensures that all versions of Git later than
+`v0.99.9l` will die instead of trying to operate on the NewHash
+repository, instead producing an error message.
 
+       # Between v0.99.9l and v2.7.0
+       $ git status
+       fatal: Expected git repo version <= 0, found 1
+       # After v2.7.0
        $ git status
        fatal: unknown repository extensions found:
                objectformat
index 1b4624c876dae8f38f7c9e13f82d11b6ead39c9b..12ff59c2c78565a1ad9c491147d2b8e0615aa1e5 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v2.17.0
+DEF_VER=v2.17.GIT
 
 LF='
 '
index a1d8775adb4b38a0340cd7d04184915f0ee65d28..2e198c41dcebc7efbae92678f4de63b228f0622b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -29,10 +29,10 @@ all::
 # Perl-compatible regular expressions instead of standard or extended
 # POSIX regular expressions.
 #
-# Currently USE_LIBPCRE is a synonym for USE_LIBPCRE1, define
-# USE_LIBPCRE2 instead if you'd like to use version 2 of the PCRE
-# library. The USE_LIBPCRE flag will likely be changed to mean v2 by
-# default in future releases.
+# USE_LIBPCRE is a synonym for USE_LIBPCRE2, define USE_LIBPCRE1
+# instead if you'd like to use the legacy version 1 of the PCRE
+# library. Support for version 1 will likely be removed in some future
+# release of Git, as upstream has all but abandoned it.
 #
 # When using USE_LIBPCRE1, define NO_LIBPCRE1_JIT if the PCRE v1
 # library is compiled without --enable-jit. We will auto-detect
@@ -335,6 +335,13 @@ all::
 # when hardlinking a file to another name and unlinking the original file right
 # away (some NTFS drivers seem to zero the contents in that scenario).
 #
+# Define INSTALL_SYMLINKS if you prefer to have everything that can be
+# symlinked between bin/ and libexec/ to use relative symlinks between
+# the two. This option overrides NO_CROSS_DIRECTORY_HARDLINKS and
+# NO_INSTALL_HARDLINKS which will also use symlinking by indirection
+# within the same directory in some cases, INSTALL_SYMLINKS will
+# always symlink to the final target directly.
+#
 # Define NO_CROSS_DIRECTORY_HARDLINKS if you plan to distribute the installed
 # programs as a tar, where bin/ and libexec/ might be on different file systems.
 #
@@ -474,8 +481,7 @@ ARFLAGS = rcs
 # This can help installing the suite in a relocatable way.
 
 prefix = $(HOME)
-bindir_relative = bin
-bindir = $(prefix)/$(bindir_relative)
+bindir = $(prefix)/bin
 mandir = $(prefix)/share/man
 infodir = $(prefix)/share/info
 gitexecdir = libexec/git-core
@@ -492,8 +498,10 @@ lib = lib
 # DESTDIR =
 pathsep = :
 
+bindir_relative = $(patsubst $(prefix)/%,%,$(bindir))
 mandir_relative = $(patsubst $(prefix)/%,%,$(mandir))
 infodir_relative = $(patsubst $(prefix)/%,%,$(infodir))
+gitexecdir_relative = $(patsubst $(prefix)/%,%,$(gitexecdir))
 htmldir_relative = $(patsubst $(prefix)/%,%,$(htmldir))
 
 export prefix bindir sharedir sysconfdir gitwebdir perllibdir localedir
@@ -546,6 +554,7 @@ SCRIPT_PERL =
 SCRIPT_PYTHON =
 SCRIPT_SH =
 SCRIPT_LIB =
+TEST_BUILTINS_OBJS =
 TEST_PROGRAMS_NEED_X =
 
 # Having this variable in your environment would break pipelines because
@@ -651,47 +660,49 @@ X =
 
 PROGRAMS += $(patsubst %.o,git-%$X,$(PROGRAM_OBJS))
 
-TEST_PROGRAMS_NEED_X += test-chmtime
-TEST_PROGRAMS_NEED_X += test-ctype
-TEST_PROGRAMS_NEED_X += test-config
-TEST_PROGRAMS_NEED_X += test-date
-TEST_PROGRAMS_NEED_X += test-delta
-TEST_PROGRAMS_NEED_X += test-drop-caches
-TEST_PROGRAMS_NEED_X += test-dump-cache-tree
+TEST_BUILTINS_OBJS += test-chmtime.o
+TEST_BUILTINS_OBJS += test-config.o
+TEST_BUILTINS_OBJS += test-ctype.o
+TEST_BUILTINS_OBJS += test-date.o
+TEST_BUILTINS_OBJS += test-delta.o
+TEST_BUILTINS_OBJS += test-drop-caches.o
+TEST_BUILTINS_OBJS += test-dump-cache-tree.o
+TEST_BUILTINS_OBJS += test-dump-split-index.o
+TEST_BUILTINS_OBJS += test-example-decorate.o
+TEST_BUILTINS_OBJS += test-genrandom.o
+TEST_BUILTINS_OBJS += test-hashmap.o
+TEST_BUILTINS_OBJS += test-index-version.o
+TEST_BUILTINS_OBJS += test-lazy-init-name-hash.o
+TEST_BUILTINS_OBJS += test-match-trees.o
+TEST_BUILTINS_OBJS += test-mergesort.o
+TEST_BUILTINS_OBJS += test-mktemp.o
+TEST_BUILTINS_OBJS += test-online-cpus.o
+TEST_BUILTINS_OBJS += test-path-utils.o
+TEST_BUILTINS_OBJS += test-prio-queue.o
+TEST_BUILTINS_OBJS += test-read-cache.o
+TEST_BUILTINS_OBJS += test-ref-store.o
+TEST_BUILTINS_OBJS += test-regex.o
+TEST_BUILTINS_OBJS += test-revision-walking.o
+TEST_BUILTINS_OBJS += test-run-command.o
+TEST_BUILTINS_OBJS += test-scrap-cache-tree.o
+TEST_BUILTINS_OBJS += test-sha1-array.o
+TEST_BUILTINS_OBJS += test-sha1.o
+TEST_BUILTINS_OBJS += test-sigchain.o
+TEST_BUILTINS_OBJS += test-strcmp-offset.o
+TEST_BUILTINS_OBJS += test-string-list.o
+TEST_BUILTINS_OBJS += test-submodule-config.o
+TEST_BUILTINS_OBJS += test-subprocess.o
+TEST_BUILTINS_OBJS += test-urlmatch-normalization.o
+TEST_BUILTINS_OBJS += test-wildmatch.o
+TEST_BUILTINS_OBJS += test-write-cache.o
+
 TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
-TEST_PROGRAMS_NEED_X += test-dump-split-index
 TEST_PROGRAMS_NEED_X += test-dump-untracked-cache
-TEST_PROGRAMS_NEED_X += test-example-decorate
 TEST_PROGRAMS_NEED_X += test-fake-ssh
-TEST_PROGRAMS_NEED_X += test-genrandom
-TEST_PROGRAMS_NEED_X += test-hashmap
-TEST_PROGRAMS_NEED_X += test-index-version
-TEST_PROGRAMS_NEED_X += test-lazy-init-name-hash
 TEST_PROGRAMS_NEED_X += test-line-buffer
-TEST_PROGRAMS_NEED_X += test-match-trees
-TEST_PROGRAMS_NEED_X += test-mergesort
-TEST_PROGRAMS_NEED_X += test-mktemp
-TEST_PROGRAMS_NEED_X += test-online-cpus
 TEST_PROGRAMS_NEED_X += test-parse-options
-TEST_PROGRAMS_NEED_X += test-path-utils
-TEST_PROGRAMS_NEED_X += test-prio-queue
-TEST_PROGRAMS_NEED_X += test-read-cache
-TEST_PROGRAMS_NEED_X += test-write-cache
-TEST_PROGRAMS_NEED_X += test-ref-store
-TEST_PROGRAMS_NEED_X += test-regex
-TEST_PROGRAMS_NEED_X += test-revision-walking
-TEST_PROGRAMS_NEED_X += test-run-command
-TEST_PROGRAMS_NEED_X += test-scrap-cache-tree
-TEST_PROGRAMS_NEED_X += test-sha1
-TEST_PROGRAMS_NEED_X += test-sha1-array
-TEST_PROGRAMS_NEED_X += test-sigchain
-TEST_PROGRAMS_NEED_X += test-strcmp-offset
-TEST_PROGRAMS_NEED_X += test-string-list
-TEST_PROGRAMS_NEED_X += test-submodule-config
-TEST_PROGRAMS_NEED_X += test-subprocess
 TEST_PROGRAMS_NEED_X += test-svn-fe
-TEST_PROGRAMS_NEED_X += test-urlmatch-normalization
-TEST_PROGRAMS_NEED_X += test-wildmatch
+TEST_PROGRAMS_NEED_X += test-tool
 
 TEST_PROGRAMS = $(patsubst %,t/helper/%$X,$(TEST_PROGRAMS_NEED_X))
 
@@ -772,6 +783,7 @@ LIB_OBJS += branch.o
 LIB_OBJS += bulk-checkin.o
 LIB_OBJS += bundle.o
 LIB_OBJS += cache-tree.o
+LIB_OBJS += chdir-notify.o
 LIB_OBJS += checkout.o
 LIB_OBJS += color.o
 LIB_OBJS += column.o
@@ -1170,13 +1182,18 @@ ifdef NO_LIBGEN_H
        COMPAT_OBJS += compat/basename.o
 endif
 
-USE_LIBPCRE1 ?= $(USE_LIBPCRE)
+USE_LIBPCRE2 ?= $(USE_LIBPCRE)
 
-ifneq (,$(USE_LIBPCRE1))
-       ifdef USE_LIBPCRE2
-$(error Only set USE_LIBPCRE1 (or its alias USE_LIBPCRE) or USE_LIBPCRE2, not both!)
+ifneq (,$(USE_LIBPCRE2))
+       ifdef USE_LIBPCRE1
+$(error Only set USE_LIBPCRE2 (or its alias USE_LIBPCRE) or USE_LIBPCRE1, not both!)
        endif
 
+       BASIC_CFLAGS += -DUSE_LIBPCRE2
+       EXTLIBS += -lpcre2-8
+endif
+
+ifdef USE_LIBPCRE1
        BASIC_CFLAGS += -DUSE_LIBPCRE1
        EXTLIBS += -lpcre
 
@@ -1185,11 +1202,6 @@ ifdef NO_LIBPCRE1_JIT
 endif
 endif
 
-ifdef USE_LIBPCRE2
-       BASIC_CFLAGS += -DUSE_LIBPCRE2
-       EXTLIBS += -lpcre2-8
-endif
-
 ifdef LIBPCREDIR
        BASIC_CFLAGS += -I$(LIBPCREDIR)/include
        EXTLIBS += -L$(LIBPCREDIR)/$(lib) $(CC_LD_DYNPATH)$(LIBPCREDIR)/$(lib)
@@ -1741,6 +1753,7 @@ infodir_relative_SQ = $(subst ','\'',$(infodir_relative))
 perllibdir_SQ = $(subst ','\'',$(perllibdir))
 localedir_SQ = $(subst ','\'',$(localedir))
 gitexecdir_SQ = $(subst ','\'',$(gitexecdir))
+gitexecdir_relative_SQ = $(subst ','\'',$(gitexecdir_relative))
 template_dir_SQ = $(subst ','\'',$(template_dir))
 htmldir_relative_SQ = $(subst ','\'',$(htmldir_relative))
 prefix_SQ = $(subst ','\'',$(prefix))
@@ -2083,7 +2096,7 @@ VCSSVN_OBJS += vcs-svn/fast_export.o
 VCSSVN_OBJS += vcs-svn/svndiff.o
 VCSSVN_OBJS += vcs-svn/svndump.o
 
-TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS))
+TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS)) $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS))
 OBJECTS := $(LIB_OBJS) $(BUILTIN_OBJS) $(PROGRAM_OBJS) $(TEST_OBJS) \
        $(XDIFF_OBJS) \
        $(VCSSVN_OBJS) \
@@ -2494,10 +2507,12 @@ t/helper/test-svn-fe$X: $(VCSSVN_LIB)
 
 .PRECIOUS: $(TEST_OBJS)
 
+t/helper/test-tool$X: $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS))
+
 t/helper/test-%$X: t/helper/test-%.o GIT-LDFLAGS $(GITLIBS)
        $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(filter %.a,$^) $(LIBS)
 
-check-sha1:: t/helper/test-sha1$X
+check-sha1:: t/helper/test-tool$X
        t/helper/test-sha1.sh
 
 SP_OBJ = $(patsubst %.o,%.sp,$(C_OBJ))
@@ -2606,35 +2621,44 @@ endif
 
        bindir=$$(cd '$(DESTDIR_SQ)$(bindir_SQ)' && pwd) && \
        execdir=$$(cd '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' && pwd) && \
+       destdir_from_execdir_SQ=$$(echo '$(gitexecdir_relative_SQ)' | sed -e 's|[^/][^/]*|..|g') && \
        { test "$$bindir/" = "$$execdir/" || \
          for p in git$X $(filter $(install_bindir_programs),$(ALL_PROGRAMS)); do \
                $(RM) "$$execdir/$$p" && \
-               test -z "$(NO_INSTALL_HARDLINKS)$(NO_CROSS_DIRECTORY_HARDLINKS)" && \
-               ln "$$bindir/$$p" "$$execdir/$$p" 2>/dev/null || \
-               cp "$$bindir/$$p" "$$execdir/$$p" || exit; \
+               test -n "$(INSTALL_SYMLINKS)" && \
+               ln -s "$$destdir_from_execdir_SQ/$(bindir_relative_SQ)/$$p" "$$execdir/$$p" || \
+               { test -z "$(NO_INSTALL_HARDLINKS)$(NO_CROSS_DIRECTORY_HARDLINKS)" && \
+                 ln "$$bindir/$$p" "$$execdir/$$p" 2>/dev/null || \
+                 cp "$$bindir/$$p" "$$execdir/$$p" || exit; } \
          done; \
        } && \
        for p in $(filter $(install_bindir_programs),$(BUILT_INS)); do \
                $(RM) "$$bindir/$$p" && \
-               test -z "$(NO_INSTALL_HARDLINKS)" && \
-               ln "$$bindir/git$X" "$$bindir/$$p" 2>/dev/null || \
-               ln -s "git$X" "$$bindir/$$p" 2>/dev/null || \
-               cp "$$bindir/git$X" "$$bindir/$$p" || exit; \
+               test -n "$(INSTALL_SYMLINKS)" && \
+               ln -s "git$X" "$$bindir/$$p" || \
+               { test -z "$(NO_INSTALL_HARDLINKS)" && \
+                 ln "$$bindir/git$X" "$$bindir/$$p" 2>/dev/null || \
+                 ln -s "git$X" "$$bindir/$$p" 2>/dev/null || \
+                 cp "$$bindir/git$X" "$$bindir/$$p" || exit; } \
        done && \
        for p in $(BUILT_INS); do \
                $(RM) "$$execdir/$$p" && \
-               test -z "$(NO_INSTALL_HARDLINKS)" && \
-               ln "$$execdir/git$X" "$$execdir/$$p" 2>/dev/null || \
-               ln -s "git$X" "$$execdir/$$p" 2>/dev/null || \
-               cp "$$execdir/git$X" "$$execdir/$$p" || exit; \
+               test -n "$(INSTALL_SYMLINKS)" && \
+               ln -s "$$destdir_from_execdir_SQ/$(bindir_relative_SQ)/git$X" "$$execdir/$$p" || \
+               { test -z "$(NO_INSTALL_HARDLINKS)" && \
+                 ln "$$execdir/git$X" "$$execdir/$$p" 2>/dev/null || \
+                 ln -s "git$X" "$$execdir/$$p" 2>/dev/null || \
+                 cp "$$execdir/git$X" "$$execdir/$$p" || exit; } \
        done && \
        remote_curl_aliases="$(REMOTE_CURL_ALIASES)" && \
        for p in $$remote_curl_aliases; do \
                $(RM) "$$execdir/$$p" && \
-               test -z "$(NO_INSTALL_HARDLINKS)" && \
-               ln "$$execdir/git-remote-http$X" "$$execdir/$$p" 2>/dev/null || \
-               ln -s "git-remote-http$X" "$$execdir/$$p" 2>/dev/null || \
-               cp "$$execdir/git-remote-http$X" "$$execdir/$$p" || exit; \
+               test -n "$(INSTALL_SYMLINKS)" && \
+               ln -s "git-remote-http$X" "$$execdir/$$p" || \
+               { test -z "$(NO_INSTALL_HARDLINKS)" && \
+                 ln "$$execdir/git-remote-http$X" "$$execdir/$$p" 2>/dev/null || \
+                 ln -s "git-remote-http$X" "$$execdir/$$p" 2>/dev/null || \
+                 cp "$$execdir/git-remote-http$X" "$$execdir/$$p" || exit; } \
        done && \
        ./check_bindir "z$$bindir" "z$$execdir" "$$bindir/git-add$X"
 
index 7a6dc0603be1af20219ec41b4df926a9861d3644..f6c58b347fd8338482625ea11ec1802baa6ea068 120000 (symlink)
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/2.17.0.txt
\ No newline at end of file
+Documentation/RelNotes/2.18.0.txt
\ No newline at end of file
diff --git a/apply.c b/apply.c
index 134dc7ba78cddd99406b78a97898bd8a32393b4c..7e5792c996f430952b1b768f8267de851156ce83 100644 (file)
--- a/apply.c
+++ b/apply.c
@@ -3180,7 +3180,7 @@ static int apply_binary(struct apply_state *state,
                unsigned long size;
                char *result;
 
-               result = read_sha1_file(oid.hash, &type, &size);
+               result = read_object_file(&oid, &type, &size);
                if (!result)
                        return error(_("the necessary postimage %s for "
                                       "'%s' cannot be read"),
@@ -3242,7 +3242,7 @@ static int read_blob_object(struct strbuf *buf, const struct object_id *oid, uns
                unsigned long sz;
                char *result;
 
-               result = read_sha1_file(oid->hash, &type, &sz);
+               result = read_object_file(oid, &type, &sz);
                if (!result)
                        return -1;
                /* XXX read_sha1_file NUL-terminates */
index c6ed96ee74ec10f5c9ffb6f520193326d4704b6b..3563bcb9f263f7782a77c679bf9be32af6bd13df 100644 (file)
@@ -111,7 +111,7 @@ static void write_trailer(void)
  * queues up writes, so that all our write(2) calls write exactly one
  * full block; pads writes to RECORDSIZE
  */
-static int stream_blocked(const unsigned char *sha1)
+static int stream_blocked(const struct object_id *oid)
 {
        struct git_istream *st;
        enum object_type type;
@@ -119,9 +119,9 @@ static int stream_blocked(const unsigned char *sha1)
        char buf[BLOCKSIZE];
        ssize_t readlen;
 
-       st = open_istream(sha1, &type, &sz, NULL);
+       st = open_istream(oid, &type, &sz, NULL);
        if (!st)
-               return error("cannot stream blob %s", sha1_to_hex(sha1));
+               return error("cannot stream blob %s", oid_to_hex(oid));
        for (;;) {
                readlen = read_istream(st, buf, sizeof(buf));
                if (readlen <= 0)
@@ -218,7 +218,7 @@ static void prepare_header(struct archiver_args *args,
 }
 
 static void write_extended_header(struct archiver_args *args,
-                                 const unsigned char *sha1,
+                                 const struct object_id *oid,
                                  const void *buffer, unsigned long size)
 {
        struct ustar_header header;
@@ -226,14 +226,14 @@ static void write_extended_header(struct archiver_args *args,
        memset(&header, 0, sizeof(header));
        *header.typeflag = TYPEFLAG_EXT_HEADER;
        mode = 0100666;
-       xsnprintf(header.name, sizeof(header.name), "%s.paxheader", sha1_to_hex(sha1));
+       xsnprintf(header.name, sizeof(header.name), "%s.paxheader", oid_to_hex(oid));
        prepare_header(args, &header, mode, size);
        write_blocked(&header, sizeof(header));
        write_blocked(buffer, size);
 }
 
 static int write_tar_entry(struct archiver_args *args,
-                          const unsigned char *sha1,
+                          const struct object_id *oid,
                           const char *path, size_t pathlen,
                           unsigned int mode)
 {
@@ -257,7 +257,7 @@ static int write_tar_entry(struct archiver_args *args,
                mode = (mode | ((mode & 0100) ? 0777 : 0666)) & ~tar_umask;
        } else {
                return error("unsupported file mode: 0%o (SHA1: %s)",
-                            mode, sha1_to_hex(sha1));
+                            mode, oid_to_hex(oid));
        }
        if (pathlen > sizeof(header.name)) {
                size_t plen = get_path_prefix(path, pathlen,
@@ -268,7 +268,7 @@ static int write_tar_entry(struct archiver_args *args,
                        memcpy(header.name, path + plen + 1, rest);
                } else {
                        xsnprintf(header.name, sizeof(header.name), "%s.data",
-                                 sha1_to_hex(sha1));
+                                 oid_to_hex(oid));
                        strbuf_append_ext_header(&ext_header, "path",
                                                 path, pathlen);
                }
@@ -276,14 +276,14 @@ static int write_tar_entry(struct archiver_args *args,
                memcpy(header.name, path, pathlen);
 
        if (S_ISREG(mode) && !args->convert &&
-           sha1_object_info(sha1, &size) == OBJ_BLOB &&
+           oid_object_info(oid, &size) == OBJ_BLOB &&
            size > big_file_threshold)
                buffer = NULL;
        else if (S_ISLNK(mode) || S_ISREG(mode)) {
                enum object_type type;
-               buffer = sha1_file_to_archive(args, path, sha1, old_mode, &type, &size);
+               buffer = object_file_to_archive(args, path, oid, old_mode, &type, &size);
                if (!buffer)
-                       return error("cannot read %s", sha1_to_hex(sha1));
+                       return error("cannot read %s", oid_to_hex(oid));
        } else {
                buffer = NULL;
                size = 0;
@@ -292,7 +292,7 @@ static int write_tar_entry(struct archiver_args *args,
        if (S_ISLNK(mode)) {
                if (size > sizeof(header.linkname)) {
                        xsnprintf(header.linkname, sizeof(header.linkname),
-                                 "see %s.paxheader", sha1_to_hex(sha1));
+                                 "see %s.paxheader", oid_to_hex(oid));
                        strbuf_append_ext_header(&ext_header, "linkpath",
                                                 buffer, size);
                } else
@@ -308,7 +308,7 @@ static int write_tar_entry(struct archiver_args *args,
        prepare_header(args, &header, mode, size_in_header);
 
        if (ext_header.len > 0) {
-               write_extended_header(args, sha1, ext_header.buf,
+               write_extended_header(args, oid, ext_header.buf,
                                      ext_header.len);
        }
        strbuf_release(&ext_header);
@@ -317,7 +317,7 @@ static int write_tar_entry(struct archiver_args *args,
                if (buffer)
                        write_blocked(buffer, size);
                else
-                       err = stream_blocked(sha1);
+                       err = stream_blocked(oid);
        }
        free(buffer);
        return err;
index e8913e5a26c6e97216c4b79ad96b5e3ddf906c45..6b20bce4d1cd78563037c8658dd8bd8f7690c47b 100644 (file)
@@ -276,7 +276,7 @@ static int entry_is_binary(const char *path, const void *buffer, size_t size)
 #define STREAM_BUFFER_SIZE (1024 * 16)
 
 static int write_zip_entry(struct archiver_args *args,
-                          const unsigned char *sha1,
+                          const struct object_id *oid,
                           const char *path, size_t pathlen,
                           unsigned int mode)
 {
@@ -314,7 +314,7 @@ static int write_zip_entry(struct archiver_args *args,
 
        if (pathlen > 0xffff) {
                return error("path too long (%d chars, SHA1: %s): %s",
-                               (int)pathlen, sha1_to_hex(sha1), path);
+                               (int)pathlen, oid_to_hex(oid), path);
        }
 
        if (S_ISDIR(mode) || S_ISGITLINK(mode)) {
@@ -325,7 +325,7 @@ static int write_zip_entry(struct archiver_args *args,
                compressed_size = 0;
                buffer = NULL;
        } else if (S_ISREG(mode) || S_ISLNK(mode)) {
-               enum object_type type = sha1_object_info(sha1, &size);
+               enum object_type type = oid_object_info(oid, &size);
 
                method = 0;
                attr2 = S_ISLNK(mode) ? ((mode | 0777) << 16) :
@@ -337,18 +337,18 @@ static int write_zip_entry(struct archiver_args *args,
 
                if (S_ISREG(mode) && type == OBJ_BLOB && !args->convert &&
                    size > big_file_threshold) {
-                       stream = open_istream(sha1, &type, &size, NULL);
+                       stream = open_istream(oid, &type, &size, NULL);
                        if (!stream)
                                return error("cannot stream blob %s",
-                                            sha1_to_hex(sha1));
+                                            oid_to_hex(oid));
                        flags |= ZIP_STREAM;
                        out = buffer = NULL;
                } else {
-                       buffer = sha1_file_to_archive(args, path, sha1, mode,
-                                                     &type, &size);
+                       buffer = object_file_to_archive(args, path, oid, mode,
+                                                       &type, &size);
                        if (!buffer)
                                return error("cannot read %s",
-                                            sha1_to_hex(sha1));
+                                            oid_to_hex(oid));
                        crc = crc32(crc, buffer, size);
                        is_binary = entry_is_binary(path_without_prefix,
                                                    buffer, size);
@@ -357,7 +357,7 @@ static int write_zip_entry(struct archiver_args *args,
                compressed_size = (method == 0) ? size : 0;
        } else {
                return error("unsupported file mode: 0%o (SHA1: %s)", mode,
-                               sha1_to_hex(sha1));
+                               oid_to_hex(oid));
        }
 
        if (creator_version > max_creator_version)
index 0b7b62af0c3ecee10a26e9bd2d274690604ffcad..93ab175b0b4055bcfbd9334c7ccb36475c33e549 100644 (file)
--- a/archive.c
+++ b/archive.c
@@ -63,16 +63,16 @@ static void format_subst(const struct commit *commit,
        free(to_free);
 }
 
-void *sha1_file_to_archive(const struct archiver_args *args,
-                          const char *path, const unsigned char *sha1,
-                          unsigned int mode, enum object_type *type,
-                          unsigned long *sizep)
+void *object_file_to_archive(const struct archiver_args *args,
+                            const char *path, const struct object_id *oid,
+                            unsigned int mode, enum object_type *type,
+                            unsigned long *sizep)
 {
        void *buffer;
        const struct commit *commit = args->convert ? args->commit : NULL;
 
        path += args->baselen;
-       buffer = read_sha1_file(sha1, type, sizep);
+       buffer = read_object_file(oid, type, sizep);
        if (buffer && S_ISREG(mode)) {
                struct strbuf buf = STRBUF_INIT;
                size_t size = 0;
@@ -121,7 +121,7 @@ static int check_attr_export_subst(const struct attr_check *check)
        return check && ATTR_TRUE(check->items[1].value);
 }
 
-static int write_archive_entry(const unsigned char *sha1, const char *base,
+static int write_archive_entry(const struct object_id *oid, const char *base,
                int baselen, const char *filename, unsigned mode, int stage,
                void *context)
 {
@@ -153,7 +153,7 @@ static int write_archive_entry(const unsigned char *sha1, const char *base,
        if (S_ISDIR(mode) || S_ISGITLINK(mode)) {
                if (args->verbose)
                        fprintf(stderr, "%.*s\n", (int)path.len, path.buf);
-               err = write_entry(args, sha1, path.buf, path.len, mode);
+               err = write_entry(args, oid, path.buf, path.len, mode);
                if (err)
                        return err;
                return (S_ISDIR(mode) ? READ_TREE_RECURSIVE : 0);
@@ -161,7 +161,7 @@ static int write_archive_entry(const unsigned char *sha1, const char *base,
 
        if (args->verbose)
                fprintf(stderr, "%.*s\n", (int)path.len, path.buf);
-       return write_entry(args, sha1, path.buf, path.len, mode);
+       return write_entry(args, oid, path.buf, path.len, mode);
 }
 
 static void queue_directory(const unsigned char *sha1,
@@ -191,14 +191,14 @@ static int write_directory(struct archiver_context *c)
        d->path[d->len - 1] = '\0'; /* no trailing slash */
        ret =
                write_directory(c) ||
-               write_archive_entry(d->oid.hash, d->path, d->baselen,
+               write_archive_entry(&d->oid, d->path, d->baselen,
                                    d->path + d->baselen, d->mode,
                                    d->stage, c) != READ_TREE_RECURSIVE;
        free(d);
        return ret ? -1 : 0;
 }
 
-static int queue_or_write_archive_entry(const unsigned char *sha1,
+static int queue_or_write_archive_entry(const struct object_id *oid,
                struct strbuf *base, const char *filename,
                unsigned mode, int stage, void *context)
 {
@@ -224,14 +224,14 @@ static int queue_or_write_archive_entry(const unsigned char *sha1,
 
                if (check_attr_export_ignore(check))
                        return 0;
-               queue_directory(sha1, base, filename,
+               queue_directory(oid->hash, base, filename,
                                mode, stage, c);
                return READ_TREE_RECURSIVE;
        }
 
        if (write_directory(c))
                return -1;
-       return write_archive_entry(sha1, base->buf, base->len, filename, mode,
+       return write_archive_entry(oid, base->buf, base->len, filename, mode,
                                   stage, context);
 }
 
@@ -250,7 +250,7 @@ int write_archive_entries(struct archiver_args *args,
                        len--;
                if (args->verbose)
                        fprintf(stderr, "%.*s\n", (int)len, args->base);
-               err = write_entry(args, args->tree->object.oid.hash, args->base,
+               err = write_entry(args, &args->tree->object.oid, args->base,
                                  len, 040777);
                if (err)
                        return err;
@@ -303,7 +303,7 @@ static const struct archiver *lookup_archiver(const char *name)
        return NULL;
 }
 
-static int reject_entry(const unsigned char *sha1, struct strbuf *base,
+static int reject_entry(const struct object_id *oid, struct strbuf *base,
                        const char *filename, unsigned mode,
                        int stage, void *context)
 {
@@ -397,8 +397,8 @@ static void parse_treeish_arg(const char **argv,
                unsigned int mode;
                int err;
 
-               err = get_tree_entry(tree->object.oid.hash, prefix,
-                                    tree_oid.hash, &mode);
+               err = get_tree_entry(&tree->object.oid, prefix, &tree_oid,
+                                    &mode);
                if (err || !S_ISDIR(mode))
                        die("current working directory is untracked");
 
index 62d1d82c1af0fa3bf77b32d63e9b4866f3428898..1f9954f7cdc5a1ee8036321e439a65bdfb90e59f 100644 (file)
--- a/archive.h
+++ b/archive.h
@@ -31,7 +31,7 @@ extern void init_tar_archiver(void);
 extern void init_zip_archiver(void);
 
 typedef int (*write_archive_entry_fn_t)(struct archiver_args *args,
-                                       const unsigned char *sha1,
+                                       const struct object_id *oid,
                                        const char *path, size_t pathlen,
                                        unsigned int mode);
 
@@ -39,9 +39,9 @@ extern int write_archive_entries(struct archiver_args *args, write_archive_entry
 extern int write_archive(int argc, const char **argv, const char *prefix, const char *name_hint, int remote);
 
 const char *archive_format_from_filename(const char *filename);
-extern void *sha1_file_to_archive(const struct archiver_args *args,
-                                 const char *path, const unsigned char *sha1,
-                                 unsigned int mode, enum object_type *type,
-                                 unsigned long *sizep);
+extern void *object_file_to_archive(const struct archiver_args *args,
+                                   const char *path, const struct object_id *oid,
+                                   unsigned int mode, enum object_type *type,
+                                   unsigned long *sizep);
 
 #endif /* ARCHIVE_H */
index f6d05bd66f42bd9874a08f5585ae99337d22dad5..a579b50884f8e6f8ce8390308d39b2664d050583 100644 (file)
--- a/bisect.c
+++ b/bisect.c
@@ -132,7 +132,8 @@ static void show_list(const char *debug, int counted, int nr,
                unsigned flags = commit->object.flags;
                enum object_type type;
                unsigned long size;
-               char *buf = read_sha1_file(commit->object.oid.hash, &type, &size);
+               char *buf = read_object_file(&commit->object.oid, &type,
+                                            &size);
                const char *subject_start;
                int subject_len;
 
@@ -144,10 +145,10 @@ static void show_list(const char *debug, int counted, int nr,
                        fprintf(stderr, "%3d", weight(p));
                else
                        fprintf(stderr, "---");
-               fprintf(stderr, " %.*s", 8, sha1_to_hex(commit->object.oid.hash));
+               fprintf(stderr, " %.*s", 8, oid_to_hex(&commit->object.oid));
                for (pp = commit->parents; pp; pp = pp->next)
                        fprintf(stderr, " %.*s", 8,
-                               sha1_to_hex(pp->item->object.oid.hash));
+                               oid_to_hex(&pp->item->object.oid));
 
                subject_len = find_commit_subject(buf, &subject_start);
                if (subject_len)
diff --git a/blame.c b/blame.c
index 200e0ad9a299adb13982cdc27cb6e9a768560f58..78c9808bd1a04a4c641b0f5f853540ea7618a522 100644 (file)
--- a/blame.c
+++ b/blame.c
@@ -80,8 +80,8 @@ static void verify_working_tree_path(struct commit *work_tree, const char *path)
                struct object_id blob_oid;
                unsigned mode;
 
-               if (!get_tree_entry(commit_oid->hash, path, blob_oid.hash, &mode) &&
-                   sha1_object_info(blob_oid.hash, NULL) == OBJ_BLOB)
+               if (!get_tree_entry(commit_oid, path, &blob_oid, &mode) &&
+                   oid_object_info(&blob_oid, NULL) == OBJ_BLOB)
                        return;
        }
 
@@ -297,8 +297,8 @@ static void fill_origin_blob(struct diff_options *opt,
                    textconv_object(o->path, o->mode, &o->blob_oid, 1, &file->ptr, &file_size))
                        ;
                else
-                       file->ptr = read_sha1_file(o->blob_oid.hash, &type,
-                                                  &file_size);
+                       file->ptr = read_object_file(&o->blob_oid, &type,
+                                                    &file_size);
                file->size = file_size;
 
                if (!file->ptr)
@@ -502,11 +502,9 @@ static int fill_blob_sha1_and_mode(struct blame_origin *origin)
 {
        if (!is_null_oid(&origin->blob_oid))
                return 0;
-       if (get_tree_entry(origin->commit->object.oid.hash,
-                          origin->path,
-                          origin->blob_oid.hash, &origin->mode))
+       if (get_tree_entry(&origin->commit->object.oid, origin->path, &origin->blob_oid, &origin->mode))
                goto error_out;
-       if (sha1_object_info(origin->blob_oid.hash, NULL) != OBJ_BLOB)
+       if (oid_object_info(&origin->blob_oid, NULL) != OBJ_BLOB)
                goto error_out;
        return 0;
  error_out:
@@ -1831,8 +1829,8 @@ void setup_scoreboard(struct blame_scoreboard *sb, const char *path, struct blam
                                    &sb->final_buf_size))
                        ;
                else
-                       sb->final_buf = read_sha1_file(o->blob_oid.hash, &type,
-                                                      &sb->final_buf_size);
+                       sb->final_buf = read_object_file(&o->blob_oid, &type,
+                                                        &sb->final_buf_size);
 
                if (!sb->final_buf)
                        die(_("cannot read blob %s for path %s"),
index 1151b5c73aec81dbfca36a799cd4049429c75973..9c82603f70ff9605aa25c78023355b94860a7ce0 100644 (file)
@@ -1550,7 +1550,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa
        discard_cache();
        read_cache_from(index_path);
 
-       if (write_index_as_tree(orig_tree.hash, &the_index, index_path, 0, NULL))
+       if (write_index_as_tree(&orig_tree, &the_index, index_path, 0, NULL))
                return error(_("Repository lacks necessary blobs to fall back on 3-way merge."));
 
        say(state, stdout, _("Using index info to reconstruct a base tree..."));
@@ -1575,7 +1575,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa
                return error(_("Did you hand edit your patch?\n"
                                "It does not apply to blobs recorded in its index."));
 
-       if (write_index_as_tree(their_tree.hash, &the_index, index_path, 0, NULL))
+       if (write_index_as_tree(&their_tree, &the_index, index_path, 0, NULL))
                return error("could not write tree");
 
        say(state, stdout, _("Falling back to patching base and 3-way merge..."));
@@ -1626,7 +1626,7 @@ static void do_commit(const struct am_state *state)
        if (run_hook_le(NULL, "pre-applypatch", NULL))
                exit(1);
 
-       if (write_cache_as_tree(tree.hash, 0, NULL))
+       if (write_cache_as_tree(&tree, 0, NULL))
                die(_("git write-tree failed to write a tree"));
 
        if (!get_oid_commit("HEAD", &parent)) {
@@ -1862,7 +1862,7 @@ static void am_run(struct am_state *state, int resume)
         */
        if (!state->rebasing) {
                am_destroy(state);
-               close_all_packs();
+               close_all_packs(the_repository->objects);
                run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
        }
 }
@@ -2004,7 +2004,7 @@ static int clean_index(const struct object_id *head, const struct object_id *rem
        if (fast_forward_to(head_tree, head_tree, 1))
                return -1;
 
-       if (write_cache_as_tree(index.hash, 0, NULL))
+       if (write_cache_as_tree(&index, 0, NULL))
                return -1;
 
        index_tree = parse_tree_indirect(&index);
index 9dcb367b90d99fc9ebbbf878f53cd5b4651d7864..db38c0b307c5719ab3bd5e6b8597ec8810c0de3d 100644 (file)
@@ -499,7 +499,7 @@ static int read_ancestry(const char *graft_file)
 
 static int update_auto_abbrev(int auto_abbrev, struct blame_origin *suspect)
 {
-       const char *uniq = find_unique_abbrev(suspect->commit->object.oid.hash,
+       const char *uniq = find_unique_abbrev(&suspect->commit->object.oid,
                                              auto_abbrev);
        int len = strlen(uniq);
        if (auto_abbrev < len)
@@ -655,7 +655,7 @@ static int is_a_rev(const char *name)
 
        if (get_oid(name, &oid))
                return 0;
-       return OBJ_NONE < sha1_object_info(oid.hash, NULL);
+       return OBJ_NONE < oid_object_info(&oid, NULL);
 }
 
 int cmd_blame(int argc, const char **argv, const char *prefix)
@@ -729,6 +729,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
        for (;;) {
                switch (parse_options_step(&ctx, options, blame_opt_usage)) {
                case PARSE_OPT_HELP:
+               case PARSE_OPT_ERROR:
                        exit(129);
                case PARSE_OPT_DONE:
                        if (ctx.argv[0])
index 6d0cea9d4bcc4eb866280d6424a6dec32b5f9c87..5bd2a0dd4891ce0d42ad897c7b5fe0f66ca73be4 100644 (file)
@@ -273,7 +273,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
                               bname.buf,
                               (flags & REF_ISBROKEN) ? "broken"
                               : (flags & REF_ISSYMREF) ? target
-                              : find_unique_abbrev(oid.hash, DEFAULT_ABBREV));
+                              : find_unique_abbrev(&oid, DEFAULT_ABBREV));
                }
                delete_branch_config(bname.buf);
 
index d90170f070f4f6ab7750c31fdcfac462c934b26d..2c46d257cd9a09a8f8ff05820b53224394385c7d 100644 (file)
@@ -32,7 +32,7 @@ static int filter_object(const char *path, unsigned mode,
 {
        enum object_type type;
 
-       *buf = read_sha1_file(oid->hash, &type, size);
+       *buf = read_object_file(oid, &type, size);
        if (!*buf)
                return error(_("cannot read object %s '%s'"),
                             oid_to_hex(oid), path);
@@ -77,7 +77,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
        switch (opt) {
        case 't':
                oi.type_name = &sb;
-               if (sha1_object_info_extended(oid.hash, &oi, flags) < 0)
+               if (oid_object_info_extended(&oid, &oi, flags) < 0)
                        die("git cat-file: could not get object info");
                if (sb.len) {
                        printf("%s\n", sb.buf);
@@ -88,7 +88,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
 
        case 's':
                oi.sizep = &size;
-               if (sha1_object_info_extended(oid.hash, &oi, flags) < 0)
+               if (oid_object_info_extended(&oid, &oi, flags) < 0)
                        die("git cat-file: could not get object info");
                printf("%lu\n", size);
                return 0;
@@ -116,7 +116,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
                /* else fallthrough */
 
        case 'p':
-               type = sha1_object_info(oid.hash, NULL);
+               type = oid_object_info(&oid, NULL);
                if (type < 0)
                        die("Not a valid object name %s", obj_name);
 
@@ -130,7 +130,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
 
                if (type == OBJ_BLOB)
                        return stream_blob_to_fd(1, &oid, NULL, 0);
-               buf = read_sha1_file(oid.hash, &type, &size);
+               buf = read_object_file(&oid, &type, &size);
                if (!buf)
                        die("Cannot read object %s", obj_name);
 
@@ -140,8 +140,9 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
        case 0:
                if (type_from_string(exp_type) == OBJ_BLOB) {
                        struct object_id blob_oid;
-                       if (sha1_object_info(oid.hash, NULL) == OBJ_TAG) {
-                               char *buffer = read_sha1_file(oid.hash, &type, &size);
+                       if (oid_object_info(&oid, NULL) == OBJ_TAG) {
+                               char *buffer = read_object_file(&oid, &type,
+                                                               &size);
                                const char *target;
                                if (!skip_prefix(buffer, "object ", &target) ||
                                    get_oid_hex(target, &blob_oid))
@@ -150,7 +151,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
                        } else
                                oidcpy(&blob_oid, &oid);
 
-                       if (sha1_object_info(blob_oid.hash, NULL) == OBJ_BLOB)
+                       if (oid_object_info(&blob_oid, NULL) == OBJ_BLOB)
                                return stream_blob_to_fd(1, &blob_oid, NULL, 0);
                        /*
                         * we attempted to dereference a tag to a blob
@@ -159,7 +160,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
                         * fall-back to the usual case.
                         */
                }
-               buf = read_object_with_reference(oid.hash, exp_type, &size, NULL);
+               buf = read_object_with_reference(&oid, exp_type, &size, NULL);
                break;
 
        default:
@@ -304,8 +305,9 @@ static void print_object_or_die(struct batch_options *opt, struct expand_data *d
                                enum object_type type;
                                if (!textconv_object(data->rest, 0100644, oid,
                                                     1, &contents, &size))
-                                       contents = read_sha1_file(oid->hash, &type,
-                                                                 &size);
+                                       contents = read_object_file(oid,
+                                                                   &type,
+                                                                   &size);
                                if (!contents)
                                        die("could not convert '%s' %s",
                                            oid_to_hex(oid), data->rest);
@@ -321,7 +323,7 @@ static void print_object_or_die(struct batch_options *opt, struct expand_data *d
                unsigned long size;
                void *contents;
 
-               contents = read_sha1_file(oid->hash, &type, &size);
+               contents = read_object_file(oid, &type, &size);
                if (!contents)
                        die("object %s disappeared", oid_to_hex(oid));
                if (type != data->type)
@@ -340,8 +342,8 @@ static void batch_object_write(const char *obj_name, struct batch_options *opt,
        struct strbuf buf = STRBUF_INIT;
 
        if (!data->skip_object_info &&
-           sha1_object_info_extended(data->oid.hash, &data->info,
-                                     OBJECT_INFO_LOOKUP_REPLACE) < 0) {
+           oid_object_info_extended(&data->oid, &data->info,
+                                    OBJECT_INFO_LOOKUP_REPLACE) < 0) {
                printf("%s missing\n",
                       obj_name ? obj_name : oid_to_hex(&data->oid));
                fflush(stdout);
index d76e13c8524003fcc5c55d706c1177f66520b9d4..b49b5820718335ba6a70b70ef339ece7157281cc 100644 (file)
@@ -66,7 +66,7 @@ static int post_checkout_hook(struct commit *old_commit, struct commit *new_comm
 
 }
 
-static int update_some(const unsigned char *sha1, struct strbuf *base,
+static int update_some(const struct object_id *oid, struct strbuf *base,
                const char *pathname, unsigned mode, int stage, void *context)
 {
        int len;
@@ -78,7 +78,7 @@ static int update_some(const unsigned char *sha1, struct strbuf *base,
 
        len = base->len + strlen(pathname);
        ce = xcalloc(1, cache_entry_size(len));
-       hashcpy(ce->oid.hash, sha1);
+       oidcpy(&ce->oid, oid);
        memcpy(ce->name, base->buf, base->len);
        memcpy(ce->name + base->len, pathname, len - base->len);
        ce->ce_flags = create_ce_flags(0) | CE_UPDATE;
@@ -405,10 +405,10 @@ static void describe_detached_head(const char *msg, struct commit *commit)
                pp_commit_easy(CMIT_FMT_ONELINE, commit, &sb);
        if (print_sha1_ellipsis()) {
                fprintf(stderr, "%s %s... %s\n", msg,
-                       find_unique_abbrev(commit->object.oid.hash, DEFAULT_ABBREV), sb.buf);
+                       find_unique_abbrev(&commit->object.oid, DEFAULT_ABBREV), sb.buf);
        } else {
                fprintf(stderr, "%s %s %s\n", msg,
-                       find_unique_abbrev(commit->object.oid.hash, DEFAULT_ABBREV), sb.buf);
+                       find_unique_abbrev(&commit->object.oid, DEFAULT_ABBREV), sb.buf);
        }
        strbuf_release(&sb);
 }
@@ -720,7 +720,7 @@ static int add_pending_uninteresting_ref(const char *refname,
 static void describe_one_orphan(struct strbuf *sb, struct commit *commit)
 {
        strbuf_addstr(sb, "  ");
-       strbuf_add_unique_abbrev(sb, commit->object.oid.hash, DEFAULT_ABBREV);
+       strbuf_add_unique_abbrev(sb, &commit->object.oid, DEFAULT_ABBREV);
        strbuf_addch(sb, ' ');
        if (!parse_commit(commit))
                pp_commit_easy(CMIT_FMT_ONELINE, commit, sb);
@@ -778,7 +778,7 @@ static void suggest_reattach(struct commit *commit, struct rev_info *revs)
                        " git branch <new-branch-name> %s\n\n",
                        /* Give ngettext() the count */
                        lost),
-                       find_unique_abbrev(commit->object.oid.hash, DEFAULT_ABBREV));
+                       find_unique_abbrev(&commit->object.oid, DEFAULT_ABBREV));
 }
 
 /*
index 101c27a593f4c64a735410f18bfcb46489728696..7df5932b855e874d45b970f6150d65ed25b06f5f 100644 (file)
@@ -27,6 +27,7 @@
 #include "connected.h"
 #include "packfile.h"
 #include "list-objects-filter-options.h"
+#include "object-store.h"
 
 /*
  * Overall FIXMEs:
@@ -1217,7 +1218,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
        transport_disconnect(transport);
 
        if (option_dissociate) {
-               close_all_packs();
+               close_all_packs(the_repository->objects);
                dissociate_from_references();
        }
 
index e5bdf57b1e14cf54916c7eef077e63edddb28901..ecf42191da10cd2e87360f001d5493e792b9682e 100644 (file)
@@ -58,7 +58,7 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
                                usage(commit_tree_usage);
                        if (get_oid_commit(argv[i], &oid))
                                die("Not a valid object name %s", argv[i]);
-                       assert_sha1_type(oid.hash, OBJ_COMMIT);
+                       assert_oid_type(&oid, OBJ_COMMIT);
                        new_parent(lookup_commit(&oid), &parents);
                        continue;
                }
index 37fcb55ab0a03a5fdabaca1913bc700201fd8e10..5571d4a3e2be5ee8a71b7d5dba72b782c848f15e 100644 (file)
@@ -218,8 +218,7 @@ static int list_paths(struct string_list *list, const char *with_tree,
 
        if (with_tree) {
                char *max_prefix = common_prefix(pattern);
-               overlay_tree_on_index(&the_index, with_tree,
-                                     max_prefix ? max_prefix : prefix);
+               overlay_tree_on_index(&the_index, with_tree, max_prefix);
                free(max_prefix);
        }
 
index 33343818c830bf64452640b14b2ce7b876221022..b054713e1a1e7d83563df0ec82d46dbca6bdb666 100644 (file)
@@ -7,10 +7,12 @@
 #include "cache.h"
 #include "config.h"
 #include "dir.h"
+#include "repository.h"
 #include "builtin.h"
 #include "parse-options.h"
 #include "quote.h"
 #include "packfile.h"
+#include "object-store.h"
 
 static unsigned long garbage;
 static off_t size_garbage;
@@ -120,9 +122,8 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)
                struct strbuf loose_buf = STRBUF_INIT;
                struct strbuf pack_buf = STRBUF_INIT;
                struct strbuf garbage_buf = STRBUF_INIT;
-               if (!packed_git)
-                       prepare_packed_git();
-               for (p = packed_git; p; p = p->next) {
+
+               for (p = get_packed_git(the_repository); p; p = p->next) {
                        if (!p->pack_local)
                                continue;
                        if (open_pack_index(p))
index e4869df7b434845544dfcc0c37cae6a77cd42dad..de840f96a4ba0135667261cfd74c674672f4c6b4 100644 (file)
@@ -285,7 +285,7 @@ static void append_name(struct commit_name *n, struct strbuf *dst)
 
 static void append_suffix(int depth, const struct object_id *oid, struct strbuf *dst)
 {
-       strbuf_addf(dst, "-%d-g%s", depth, find_unique_abbrev(oid->hash, abbrev));
+       strbuf_addf(dst, "-%d-g%s", depth, find_unique_abbrev(oid, abbrev));
 }
 
 static void describe_commit(struct object_id *oid, struct strbuf *dst)
@@ -383,7 +383,7 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst)
        if (!match_cnt) {
                struct object_id *cmit_oid = &cmit->object.oid;
                if (always) {
-                       strbuf_add_unique_abbrev(dst, cmit_oid->hash, abbrev);
+                       strbuf_add_unique_abbrev(dst, cmit_oid, abbrev);
                        if (suffix)
                                strbuf_addstr(dst, suffix);
                        return;
@@ -502,7 +502,7 @@ static void describe(const char *arg, int last_one)
 
        if (cmit)
                describe_commit(&oid, &sb);
-       else if (sha1_object_info(oid.hash, NULL) == OBJ_BLOB)
+       else if (oid_object_info(&oid, NULL) == OBJ_BLOB)
                describe_blob(oid, &sb);
        else
                die(_("%s is neither a commit nor blob"), arg);
index bcc79d1888f2217bcb380ffb1e7178c100a41e8e..ee8dce019e1ca04111de185b5f47c12076b32a0c 100644 (file)
@@ -306,7 +306,7 @@ static char *get_symlink(const struct object_id *oid, const char *path)
        } else {
                enum object_type type;
                unsigned long size;
-               data = read_sha1_file(oid->hash, &type, &size);
+               data = read_object_file(oid, &type, &size);
                if (!data)
                        die(_("could not read object %s for symlink %s"),
                                oid_to_hex(oid), path);
index 27b2cc138e67c013adbee3cbe152ca48c3d82ff5..a15898d64177b380ea021e3bc63fb91446bc02b3 100644 (file)
@@ -237,10 +237,10 @@ static void export_blob(const struct object_id *oid)
                object = (struct object *)lookup_blob(oid);
                eaten = 0;
        } else {
-               buf = read_sha1_file(oid->hash, &type, &size);
+               buf = read_object_file(oid, &type, &size);
                if (!buf)
                        die ("Could not read blob %s", oid_to_hex(oid));
-               if (check_sha1_signature(oid->hash, buf, size, type_name(type)) < 0)
+               if (check_object_signature(oid, buf, size, type_name(type)) < 0)
                        die("sha1 mismatch in blob %s", oid_to_hex(oid));
                object = parse_object_buffer(oid, type, size, buf, &eaten);
        }
@@ -682,7 +682,7 @@ static void handle_tag(const char *name, struct tag *tag)
                return;
        }
 
-       buf = read_sha1_file(tag->object.oid.hash, &type, &size);
+       buf = read_object_file(&tag->object.oid, &type, &size);
        if (!buf)
                die ("Could not read tag %s", oid_to_hex(&tag->object.oid));
        message = memmem(buf, size, "\n\n", 2);
@@ -947,7 +947,7 @@ static void import_marks(char *input_file)
                if (last_idnum < mark)
                        last_idnum = mark;
 
-               type = sha1_object_info(oid.hash, NULL);
+               type = oid_object_info(&oid, NULL);
                if (type < 0)
                        die("object not found: %s", oid_to_hex(&oid));
 
index 6d73656a486fed1afd031e6cf5e26e1c2039e0cb..dcdfc66f09af70c4b8e3c08a99c80202be7b4e68 100644 (file)
@@ -637,7 +637,7 @@ static int update_local_ref(struct ref *ref,
        struct branch *current_branch = branch_get(NULL);
        const char *pretty_ref = prettify_refname(ref->name);
 
-       type = sha1_object_info(ref->new_oid.hash, NULL);
+       type = oid_object_info(&ref->new_oid, NULL);
        if (type < 0)
                die(_("object %s not found"), oid_to_hex(&ref->new_oid));
 
@@ -708,9 +708,9 @@ static int update_local_ref(struct ref *ref,
        if (in_merge_bases(current, updated)) {
                struct strbuf quickref = STRBUF_INIT;
                int r;
-               strbuf_add_unique_abbrev(&quickref, current->object.oid.hash, DEFAULT_ABBREV);
+               strbuf_add_unique_abbrev(&quickref, &current->object.oid, DEFAULT_ABBREV);
                strbuf_addstr(&quickref, "..");
-               strbuf_add_unique_abbrev(&quickref, ref->new_oid.hash, DEFAULT_ABBREV);
+               strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
                if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
                    (recurse_submodules != RECURSE_SUBMODULES_ON))
                        check_for_new_submodule_commits(&ref->new_oid);
@@ -723,9 +723,9 @@ static int update_local_ref(struct ref *ref,
        } else if (force || ref->force) {
                struct strbuf quickref = STRBUF_INIT;
                int r;
-               strbuf_add_unique_abbrev(&quickref, current->object.oid.hash, DEFAULT_ABBREV);
+               strbuf_add_unique_abbrev(&quickref, &current->object.oid, DEFAULT_ABBREV);
                strbuf_addstr(&quickref, "...");
-               strbuf_add_unique_abbrev(&quickref, ref->new_oid.hash, DEFAULT_ABBREV);
+               strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
                if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
                    (recurse_submodules != RECURSE_SUBMODULES_ON))
                        check_for_new_submodule_commits(&ref->new_oid);
@@ -1516,7 +1516,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
 
        string_list_clear(&list, 0);
 
-       close_all_packs();
+       close_all_packs(the_repository->objects);
 
        argv_array_pushl(&argv_gc_auto, "gc", "--auto", NULL);
        if (verbosity < 0)
index 8e8a15ea4ad6de2bb73f63d39a0895a263918774..bd680be6874da29cf776c84468a60888beea53fb 100644 (file)
@@ -485,10 +485,10 @@ static void fmt_merge_msg_sigs(struct strbuf *out)
        struct strbuf tagbuf = STRBUF_INIT;
 
        for (i = 0; i < origins.nr; i++) {
-               unsigned char *sha1 = origins.items[i].util;
+               struct object_id *oid = origins.items[i].util;
                enum object_type type;
                unsigned long size, len;
-               char *buf = read_sha1_file(sha1, &type, &size);
+               char *buf = read_object_file(oid, &type, &size);
                struct strbuf sig = STRBUF_INIT;
 
                if (!buf || type != OBJ_TAG)
index ef78c6c00cbf4401ed672d6ad954bbbc68c9c115..087360a6757c607c4b38cce5fafad3bbb0822fc0 100644 (file)
@@ -1,5 +1,6 @@
 #include "builtin.h"
 #include "cache.h"
+#include "repository.h"
 #include "config.h"
 #include "commit.h"
 #include "tree.h"
@@ -16,6 +17,7 @@
 #include "streaming.h"
 #include "decorate.h"
 #include "packfile.h"
+#include "object-store.h"
 
 #define REACHABLE 0x0001
 #define SEEN      0x0002
@@ -65,7 +67,7 @@ static const char *printable_type(struct object *obj)
        const char *ret;
 
        if (obj->type == OBJ_NONE) {
-               enum object_type type = sha1_object_info(obj->oid.hash, NULL);
+               enum object_type type = oid_object_info(&obj->oid, NULL);
                if (type > 0)
                        object_as_type(obj, type, 0);
        }
@@ -513,7 +515,7 @@ static struct object *parse_loose_object(const struct object_id *oid,
        unsigned long size;
        int eaten;
 
-       if (read_loose_object(path, oid->hash, &type, &size, &contents) < 0)
+       if (read_loose_object(path, oid, &type, &size, &contents) < 0)
                return NULL;
 
        if (!contents && type != OBJ_BLOB)
@@ -719,9 +721,12 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
                for_each_loose_object(mark_loose_for_connectivity, NULL, 0);
                for_each_packed_object(mark_packed_for_connectivity, NULL, 0);
        } else {
+               struct alternate_object_database *alt_odb_list;
+
                fsck_object_dir(get_object_directory());
 
-               prepare_alt_odb();
+               prepare_alt_odb(the_repository);
+               alt_odb_list = the_repository->objects->alt_odb_list;
                for (alt = alt_odb_list; alt; alt = alt->next)
                        fsck_object_dir(alt->path);
 
@@ -730,10 +735,9 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
                        uint32_t total = 0, count = 0;
                        struct progress *progress = NULL;
 
-                       prepare_packed_git();
-
                        if (show_progress) {
-                               for (p = packed_git; p; p = p->next) {
+                               for (p = get_packed_git(the_repository); p;
+                                    p = p->next) {
                                        if (open_pack_index(p))
                                                continue;
                                        total += p->num_objects;
@@ -741,7 +745,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
 
                                progress = start_progress(_("Checking objects"), total);
                        }
-                       for (p = packed_git; p; p = p->next) {
+                       for (p = get_packed_git(the_repository); p;
+                            p = p->next) {
                                /* verify gives error messages itself */
                                if (verify_pack(p, fsck_obj_buffer,
                                                progress, count))
index f51e5a6500fc294cb719716671259de42f31bfe7..3e67124eaaed256f440eea2a08101e87678eee0e 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include "builtin.h"
+#include "repository.h"
 #include "config.h"
 #include "tempfile.h"
 #include "lockfile.h"
@@ -20,6 +21,7 @@
 #include "argv-array.h"
 #include "commit.h"
 #include "packfile.h"
+#include "object-store.h"
 
 #define FAILED_RUN "failed to run %s"
 
@@ -172,8 +174,7 @@ static int too_many_packs(void)
        if (gc_auto_pack_limit <= 0)
                return 0;
 
-       prepare_packed_git();
-       for (cnt = 0, p = packed_git; p; p = p->next) {
+       for (cnt = 0, p = get_packed_git(the_repository); p; p = p->next) {
                if (!p->pack_local)
                        continue;
                if (p->pack_keep)
@@ -479,7 +480,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
                return error(FAILED_RUN, rerere.argv[0]);
 
        report_garbage = report_pack_garbage;
-       reprepare_packed_git();
+       reprepare_packed_git(the_repository);
        if (pack_garbage.nr > 0)
                clean_pack_garbage();
 
index 789a89133aca7b8eeb93a936fd2301bd3f37d0c7..5f32d2ce84f27bca725c12aa51d2d91a0c38be8b 100644 (file)
@@ -22,6 +22,7 @@
 #include "pathspec.h"
 #include "submodule.h"
 #include "submodule-config.h"
+#include "object-store.h"
 
 static char const * const grep_usage[] = {
        N_("git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]"),
@@ -306,7 +307,7 @@ static void *lock_and_read_oid_file(const struct object_id *oid, enum object_typ
        void *data;
 
        grep_read_lock();
-       data = read_sha1_file(oid->hash, type, size);
+       data = read_object_file(oid, type, size);
        grep_read_unlock();
        return data;
 }
@@ -439,7 +440,7 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
         * object.
         */
        grep_read_lock();
-       add_to_alternates_memory(submodule.objectdir);
+       add_to_alternates_memory(submodule.objects->objectdir);
        grep_read_unlock();
 
        if (oid) {
@@ -452,7 +453,7 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
                object = parse_object_or_die(oid, oid_to_hex(oid));
 
                grep_read_lock();
-               data = read_object_with_reference(object->oid.hash, tree_type,
+               data = read_object_with_reference(&object->oid, tree_type,
                                                  &size, NULL);
                grep_read_unlock();
 
@@ -614,7 +615,7 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
                int hit, len;
 
                grep_read_lock();
-               data = read_object_with_reference(obj->oid.hash, tree_type,
+               data = read_object_with_reference(&obj->oid, tree_type,
                                                  &size, NULL);
                grep_read_unlock();
 
index bda84a92effe41adb1e50a06ff6accac0563d04a..d81473e722e7c99b9b05b34506fa4925196ff6d7 100644 (file)
@@ -13,6 +13,7 @@
 #include "streaming.h"
 #include "thread-utils.h"
 #include "packfile.h"
+#include "object-store.h"
 
 static const char index_pack_usage[] =
 "git index-pack [-v] [-o <index-file>] [--keep | --keep=<msg>] [--verify] [--strict] (<pack-file> | --stdin [--fix-thin] [<pack-file>])";
@@ -59,7 +60,7 @@ struct ofs_delta_entry {
 };
 
 struct ref_delta_entry {
-       unsigned char sha1[20];
+       struct object_id oid;
        int obj_no;
 };
 
@@ -222,7 +223,7 @@ static unsigned check_object(struct object *obj)
 
        if (!(obj->flags & FLAG_CHECKED)) {
                unsigned long size;
-               int type = sha1_object_info(obj->oid.hash, &size);
+               int type = oid_object_info(&obj->oid, &size);
                if (type <= 0)
                        die(_("did not receive expected object %s"),
                              oid_to_hex(&obj->oid));
@@ -672,18 +673,18 @@ static void find_ofs_delta_children(off_t offset,
        *last_index = last;
 }
 
-static int compare_ref_delta_bases(const unsigned char *sha1,
-                                  const unsigned char *sha2,
+static int compare_ref_delta_bases(const struct object_id *oid1,
+                                  const struct object_id *oid2,
                                   enum object_type type1,
                                   enum object_type type2)
 {
        int cmp = type1 - type2;
        if (cmp)
                return cmp;
-       return hashcmp(sha1, sha2);
+       return oidcmp(oid1, oid2);
 }
 
-static int find_ref_delta(const unsigned char *sha1, enum object_type type)
+static int find_ref_delta(const struct object_id *oid, enum object_type type)
 {
        int first = 0, last = nr_ref_deltas;
 
@@ -692,7 +693,7 @@ static int find_ref_delta(const unsigned char *sha1, enum object_type type)
                struct ref_delta_entry *delta = &ref_deltas[next];
                int cmp;
 
-               cmp = compare_ref_delta_bases(sha1, delta->sha1,
+               cmp = compare_ref_delta_bases(oid, &delta->oid,
                                              type, objects[delta->obj_no].type);
                if (!cmp)
                        return next;
@@ -705,11 +706,11 @@ static int find_ref_delta(const unsigned char *sha1, enum object_type type)
        return -first-1;
 }
 
-static void find_ref_delta_children(const unsigned char *sha1,
+static void find_ref_delta_children(const struct object_id *oid,
                                    int *first_index, int *last_index,
                                    enum object_type type)
 {
-       int first = find_ref_delta(sha1, type);
+       int first = find_ref_delta(oid, type);
        int last = first;
        int end = nr_ref_deltas - 1;
 
@@ -718,9 +719,9 @@ static void find_ref_delta_children(const unsigned char *sha1,
                *last_index = -1;
                return;
        }
-       while (first > 0 && !hashcmp(ref_deltas[first - 1].sha1, sha1))
+       while (first > 0 && !oidcmp(&ref_deltas[first - 1].oid, oid))
                --first;
-       while (last < end && !hashcmp(ref_deltas[last + 1].sha1, sha1))
+       while (last < end && !oidcmp(&ref_deltas[last + 1].oid, oid))
                ++last;
        *first_index = first;
        *last_index = last;
@@ -772,7 +773,7 @@ static int check_collison(struct object_entry *entry)
 
        memset(&data, 0, sizeof(data));
        data.entry = entry;
-       data.st = open_istream(entry->idx.oid.hash, &type, &size, NULL);
+       data.st = open_istream(&entry->idx.oid, &type, &size, NULL);
        if (!data.st)
                return -1;
        if (size != entry->size || type != entry->type)
@@ -811,12 +812,12 @@ static void sha1_object(const void *data, struct object_entry *obj_entry,
                enum object_type has_type;
                unsigned long has_size;
                read_lock();
-               has_type = sha1_object_info(oid->hash, &has_size);
+               has_type = oid_object_info(oid, &has_size);
                if (has_type < 0)
                        die(_("cannot read existing object info %s"), oid_to_hex(oid));
                if (has_type != type || has_size != size)
                        die(_("SHA1 COLLISION FOUND WITH %s !"), oid_to_hex(oid));
-               has_data = read_sha1_file(oid->hash, &has_type, &has_size);
+               has_data = read_object_file(oid, &has_type, &has_size);
                read_unlock();
                if (!data)
                        data = new_data = get_data_from_pack(obj_entry);
@@ -992,7 +993,7 @@ static struct base_data *find_unresolved_deltas_1(struct base_data *base,
                                                  struct base_data *prev_base)
 {
        if (base->ref_last == -1 && base->ofs_last == -1) {
-               find_ref_delta_children(base->obj->idx.oid.hash,
+               find_ref_delta_children(&base->obj->idx.oid,
                                        &base->ref_first, &base->ref_last,
                                        OBJ_REF_DELTA);
 
@@ -1076,7 +1077,7 @@ static int compare_ref_delta_entry(const void *a, const void *b)
        const struct ref_delta_entry *delta_a = a;
        const struct ref_delta_entry *delta_b = b;
 
-       return hashcmp(delta_a->sha1, delta_b->sha1);
+       return oidcmp(&delta_a->oid, &delta_b->oid);
 }
 
 static void resolve_base(struct object_entry *obj)
@@ -1142,7 +1143,7 @@ static void parse_pack_objects(unsigned char *hash)
                        ofs_delta++;
                } else if (obj->type == OBJ_REF_DELTA) {
                        ALLOC_GROW(ref_deltas, nr_ref_deltas + 1, ref_deltas_alloc);
-                       hashcpy(ref_deltas[nr_ref_deltas].sha1, ref_delta_oid.hash);
+                       oidcpy(&ref_deltas[nr_ref_deltas].oid, &ref_delta_oid);
                        ref_deltas[nr_ref_deltas].obj_no = i;
                        nr_ref_deltas++;
                } else if (!data) {
@@ -1374,14 +1375,15 @@ static void fix_unresolved_deltas(struct hashfile *f)
 
                if (objects[d->obj_no].real_type != OBJ_REF_DELTA)
                        continue;
-               base_obj->data = read_sha1_file(d->sha1, &type, &base_obj->size);
+               base_obj->data = read_object_file(&d->oid, &type,
+                                                 &base_obj->size);
                if (!base_obj->data)
                        continue;
 
-               if (check_sha1_signature(d->sha1, base_obj->data,
+               if (check_object_signature(&d->oid, base_obj->data,
                                base_obj->size, type_name(type)))
-                       die(_("local object %s is corrupt"), sha1_to_hex(d->sha1));
-               base_obj->obj = append_obj_to_pack(f, d->sha1,
+                       die(_("local object %s is corrupt"), oid_to_hex(&d->oid));
+               base_obj->obj = append_obj_to_pack(f, d->oid.hash,
                                        base_obj->data, base_obj->size, type);
                find_unresolved_deltas(base_obj);
                display_progress(progress, nr_resolved_deltas);
index 94ee177d56d6ff9c82b02ebfb2d27cf789527974..71f68a3e4f59d987c653fb8f32a4d8770e9c6654 100644 (file)
@@ -518,7 +518,7 @@ static int show_tag_object(const struct object_id *oid, struct rev_info *rev)
 {
        unsigned long size;
        enum object_type type;
-       char *buf = read_sha1_file(oid->hash, &type, &size);
+       char *buf = read_object_file(oid, &type, &size);
        int offset = 0;
 
        if (!buf)
@@ -541,7 +541,7 @@ static int show_tag_object(const struct object_id *oid, struct rev_info *rev)
        return 0;
 }
 
-static int show_tree_object(const unsigned char *sha1,
+static int show_tree_object(const struct object_id *oid,
                struct strbuf *base,
                const char *pathname, unsigned mode, int stage, void *context)
 {
@@ -1873,12 +1873,12 @@ static void print_commit(char sign, struct commit *commit, int verbose,
 {
        if (!verbose) {
                fprintf(file, "%c %s\n", sign,
-                      find_unique_abbrev(commit->object.oid.hash, abbrev));
+                      find_unique_abbrev(&commit->object.oid, abbrev));
        } else {
                struct strbuf buf = STRBUF_INIT;
                pp_commit_easy(CMIT_FMT_ONELINE, commit, &buf);
                fprintf(file, "%c %s %s\n", sign,
-                      find_unique_abbrev(commit->object.oid.hash, abbrev),
+                      find_unique_abbrev(&commit->object.oid, abbrev),
                       buf.buf);
                strbuf_release(&buf);
        }
index 2fc836e33086d5b70b86a3fc746f9e75706ef7ea..a71f6bd088a2666f0637463e1c168171dd319a96 100644 (file)
@@ -240,7 +240,7 @@ static void show_ce(struct repository *repo, struct dir_struct *dir,
                        printf("%s%06o %s %d\t",
                               tag,
                               ce->ce_mode,
-                              find_unique_abbrev(ce->oid.hash, abbrev),
+                              find_unique_abbrev(&ce->oid, abbrev),
                               ce_stage(ce));
                }
                write_eolinfo(repo->index, ce, fullname);
@@ -271,7 +271,7 @@ static void show_ru_info(const struct index_state *istate)
                        if (!ui->mode[i])
                                continue;
                        printf("%s%06o %s %d\t", tag_resolve_undo, ui->mode[i],
-                              find_unique_abbrev(ui->sha1[i], abbrev),
+                              find_unique_abbrev(&ui->oid[i], abbrev),
                               i + 1);
                        write_name(path);
                }
index ef965408e8fc5d80fa9e9daf0264a91abccd978c..d44b4f9c27d31cfa331ccef7ae538d8a6e6c38c6 100644 (file)
@@ -60,7 +60,7 @@ static int show_recursive(const char *base, int baselen, const char *pathname)
        return 0;
 }
 
-static int show_tree(const unsigned char *sha1, struct strbuf *base,
+static int show_tree(const struct object_id *oid, struct strbuf *base,
                const char *pathname, unsigned mode, int stage, void *context)
 {
        int retval = 0;
@@ -94,7 +94,7 @@ static int show_tree(const unsigned char *sha1, struct strbuf *base,
                        char size_text[24];
                        if (!strcmp(type, blob_type)) {
                                unsigned long size;
-                               if (sha1_object_info(sha1, &size) == OBJ_BAD)
+                               if (oid_object_info(oid, &size) == OBJ_BAD)
                                        xsnprintf(size_text, sizeof(size_text),
                                                  "BAD");
                                else
@@ -103,11 +103,11 @@ static int show_tree(const unsigned char *sha1, struct strbuf *base,
                        } else
                                xsnprintf(size_text, sizeof(size_text), "-");
                        printf("%06o %s %s %7s\t", mode, type,
-                              find_unique_abbrev(sha1, abbrev),
+                              find_unique_abbrev(oid, abbrev),
                               size_text);
                } else
                        printf("%06o %s %s\t", mode, type,
-                              find_unique_abbrev(sha1, abbrev));
+                              find_unique_abbrev(oid, abbrev));
        }
        baselen = base->len;
        strbuf_addstr(base, pathname);
index d01ddecf6602eabdca97a175e5c2a57bf1257865..32736e0b1011f575d2585fd2e012501d807f9e9b 100644 (file)
@@ -60,7 +60,7 @@ static void *result(struct merge_list *entry, unsigned long *size)
        const char *path = entry->path;
 
        if (!entry->stage)
-               return read_sha1_file(entry->blob->object.oid.hash, &type, size);
+               return read_object_file(&entry->blob->object.oid, &type, size);
        base = NULL;
        if (entry->stage == 1) {
                base = entry->blob;
@@ -82,7 +82,8 @@ static void *origin(struct merge_list *entry, unsigned long *size)
        enum object_type type;
        while (entry) {
                if (entry->stage == 2)
-                       return read_sha1_file(entry->blob->object.oid.hash, &type, size);
+                       return read_object_file(&entry->blob->object.oid,
+                                               &type, size);
                entry = entry->link;
        }
        return NULL;
index ee050a47f34d7394d048f955baabb37a9e716ef8..9db5a2cf16e189bb3bd0ceec7d34c6651d630225 100644 (file)
@@ -412,7 +412,7 @@ static void finish(struct commit *head_commit,
                         * We ignore errors in 'gc --auto', since the
                         * user should see them.
                         */
-                       close_all_packs();
+                       close_all_packs(the_repository->objects);
                        run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
                }
        }
@@ -639,7 +639,7 @@ static int read_tree_trivial(struct object_id *common, struct object_id *head,
 
 static void write_tree_trivial(struct object_id *oid)
 {
-       if (write_cache_as_tree(oid->hash, 0, NULL))
+       if (write_cache_as_tree(oid, 0, NULL))
                die(_("git write-tree failed to write a tree"));
 }
 
@@ -1324,7 +1324,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
 
                        check_commit_signature(commit, &signature_check);
 
-                       find_unique_abbrev_r(hex, commit->object.oid.hash, DEFAULT_ABBREV);
+                       find_unique_abbrev_r(hex, &commit->object.oid, DEFAULT_ABBREV);
                        switch (signature_check.result) {
                        case 'G':
                                break;
@@ -1417,9 +1417,9 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
 
                if (verbosity >= 0) {
                        printf(_("Updating %s..%s\n"),
-                              find_unique_abbrev(head_commit->object.oid.hash,
+                              find_unique_abbrev(&head_commit->object.oid,
                                                  DEFAULT_ABBREV),
-                              find_unique_abbrev(remoteheads->item->object.oid.hash,
+                              find_unique_abbrev(&remoteheads->item->object.oid,
                                                  DEFAULT_ABBREV));
                }
                strbuf_addstr(&msg, "Fast-forward");
index beb552847ba1ef36c78d9d10d3ff9e98e6a288bc..9f5a50a8fd5b0b3acf664df8d20ae5bdee288fe8 100644 (file)
 /*
  * We refuse to tag something we can't verify. Just because.
  */
-static int verify_object(const unsigned char *sha1, const char *expected_type)
+static int verify_object(const struct object_id *oid, const char *expected_type)
 {
        int ret = -1;
        enum object_type type;
        unsigned long size;
-       void *buffer = read_sha1_file(sha1, &type, &size);
-       const unsigned char *repl = lookup_replace_object(sha1);
+       void *buffer = read_object_file(oid, &type, &size);
+       const struct object_id *repl = lookup_replace_object(oid);
 
        if (buffer) {
                if (type == type_from_string(expected_type))
-                       ret = check_sha1_signature(repl, buffer, size, expected_type);
+                       ret = check_object_signature(repl, buffer, size, expected_type);
                free(buffer);
        }
        return ret;
@@ -38,8 +38,8 @@ static int verify_tag(char *buffer, unsigned long size)
 {
        int typelen;
        char type[20];
-       unsigned char sha1[20];
-       const char *object, *type_line, *tag_line, *tagger_line, *lb, *rb;
+       struct object_id oid;
+       const char *object, *type_line, *tag_line, *tagger_line, *lb, *rb, *p;
        size_t len;
 
        if (size < 84)
@@ -52,11 +52,11 @@ static int verify_tag(char *buffer, unsigned long size)
        if (memcmp(object, "object ", 7))
                return error("char%d: does not start with \"object \"", 0);
 
-       if (get_sha1_hex(object + 7, sha1))
+       if (parse_oid_hex(object + 7, &oid, &p))
                return error("char%d: could not get SHA1 hash", 7);
 
        /* Verify type line */
-       type_line = object + 48;
+       type_line = p + 1;
        if (memcmp(type_line - 1, "\ntype ", 6))
                return error("char%d: could not find \"\\ntype \"", 47);
 
@@ -80,8 +80,8 @@ static int verify_tag(char *buffer, unsigned long size)
        type[typelen] = 0;
 
        /* Verify that the object matches */
-       if (verify_object(sha1, type))
-               return error("char%d: could not verify object %s", 7, sha1_to_hex(sha1));
+       if (verify_object(&oid, type))
+               return error("char%d: could not verify object %s", 7, oid_to_hex(&oid));
 
        /* Verify the tag-name: we don't allow control characters or spaces in it */
        tag_line += 4;
index f5f3c0eea1cb6f2f61073e4d81fc0dd9c47dee60..263c530315a4fe435a88f2042c768350f72e837b 100644 (file)
 
 static struct treeent {
        unsigned mode;
-       unsigned char sha1[20];
+       struct object_id oid;
        int len;
        char name[FLEX_ARRAY];
 } **entries;
 static int alloc, used;
 
-static void append_to_tree(unsigned mode, unsigned char *sha1, char *path)
+static void append_to_tree(unsigned mode, struct object_id *oid, char *path)
 {
        struct treeent *ent;
        size_t len = strlen(path);
@@ -26,7 +26,7 @@ static void append_to_tree(unsigned mode, unsigned char *sha1, char *path)
        FLEX_ALLOC_MEM(ent, name, path, len);
        ent->mode = mode;
        ent->len = len;
-       hashcpy(ent->sha1, sha1);
+       oidcpy(&ent->oid, oid);
 
        ALLOC_GROW(entries, used + 1, alloc);
        entries[used++] = ent;
@@ -54,7 +54,7 @@ static void write_tree(struct object_id *oid)
        for (i = 0; i < used; i++) {
                struct treeent *ent = entries[i];
                strbuf_addf(&buf, "%o %s%c", ent->mode, ent->name, '\0');
-               strbuf_add(&buf, ent->sha1, 20);
+               strbuf_add(&buf, ent->oid.hash, the_hash_algo->rawsz);
        }
 
        write_object_file(buf.buf, buf.len, tree_type, oid);
@@ -69,11 +69,12 @@ static const char *mktree_usage[] = {
 static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_missing)
 {
        char *ptr, *ntr;
+       const char *p;
        unsigned mode;
        enum object_type mode_type; /* object type derived from mode */
        enum object_type obj_type; /* object type derived from sha */
        char *path, *to_free = NULL;
-       unsigned char sha1[20];
+       struct object_id oid;
 
        ptr = buf;
        /*
@@ -85,9 +86,8 @@ static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_miss
                die("input format error: %s", buf);
        ptr = ntr + 1; /* type */
        ntr = strchr(ptr, ' ');
-       if (!ntr || buf + len <= ntr + 40 ||
-           ntr[41] != '\t' ||
-           get_sha1_hex(ntr + 1, sha1))
+       if (!ntr || parse_oid_hex(ntr + 1, &oid, &p) ||
+           *p != '\t')
                die("input format error: %s", buf);
 
        /* It is perfectly normal if we do not have a commit from a submodule */
@@ -116,12 +116,12 @@ static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_miss
        }
 
        /* Check the type of object identified by sha1 */
-       obj_type = sha1_object_info(sha1, NULL);
+       obj_type = oid_object_info(&oid, NULL);
        if (obj_type < 0) {
                if (allow_missing) {
                        ; /* no problem - missing objects are presumed to be of the right type */
                } else {
-                       die("entry '%s' object %s is unavailable", path, sha1_to_hex(sha1));
+                       die("entry '%s' object %s is unavailable", path, oid_to_hex(&oid));
                }
        } else {
                if (obj_type != mode_type) {
@@ -131,11 +131,11 @@ static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_miss
                         * because the new tree entry will never be correct.
                         */
                        die("entry '%s' object %s is a %s but specified type was (%s)",
-                               path, sha1_to_hex(sha1), type_name(obj_type), type_name(mode_type));
+                               path, oid_to_hex(&oid), type_name(obj_type), type_name(mode_type));
                }
        }
 
-       append_to_tree(mode, sha1, path);
+       append_to_tree(mode, &oid, path);
        free(to_free);
 }
 
index 9e088ebd11dced248640df9e17adbbd8b9a73ffb..387ddf85d21a443f060dbb212fe95a983d9e4f58 100644 (file)
@@ -328,7 +328,7 @@ static void show_name(const struct object *obj,
        else if (allow_undefined)
                printf("undefined\n");
        else if (always)
-               printf("%s\n", find_unique_abbrev(oid->hash, DEFAULT_ABBREV));
+               printf("%s\n", find_unique_abbrev(oid, DEFAULT_ABBREV));
        else
                die("cannot describe '%s'", oid_to_hex(oid));
        strbuf_release(&buf);
index 6d2fda4a7d7ba89633f5cfee73f39cacb9f27898..921e08d5bf545ac4124933459d257d95e2144409 100644 (file)
@@ -118,11 +118,11 @@ static int list_each_note(const struct object_id *object_oid,
        return 0;
 }
 
-static void copy_obj_to_fd(int fd, const unsigned char *sha1)
+static void copy_obj_to_fd(int fd, const struct object_id *oid)
 {
        unsigned long size;
        enum object_type type;
-       char *buf = read_sha1_file(sha1, &type, &size);
+       char *buf = read_object_file(oid, &type, &size);
        if (buf) {
                if (size)
                        write_or_die(fd, buf, size);
@@ -162,7 +162,7 @@ static void write_commented_object(int fd, const struct object_id *object)
 }
 
 static void prepare_note_data(const struct object_id *object, struct note_data *d,
-               const unsigned char *old_note)
+               const struct object_id *old_note)
 {
        if (d->use_editor || !d->given) {
                int fd;
@@ -253,7 +253,7 @@ static int parse_reuse_arg(const struct option *opt, const char *arg, int unset)
 
        if (get_oid(arg, &object))
                die(_("failed to resolve '%s' as a valid ref."), arg);
-       if (!(buf = read_sha1_file(object.hash, &type, &len))) {
+       if (!(buf = read_object_file(&object, &type, &len))) {
                free(buf);
                die(_("failed to read object '%s'."), arg);
        }
@@ -457,7 +457,7 @@ static int add(int argc, const char **argv, const char *prefix)
                        oid_to_hex(&object));
        }
 
-       prepare_note_data(&object, &d, note ? note->hash : NULL);
+       prepare_note_data(&object, &d, note);
        if (d.buf.len || allow_empty) {
                write_note_data(&d, &new_note);
                if (add_note(t, &object, &new_note, combine_notes_overwrite))
@@ -602,13 +602,13 @@ static int append_edit(int argc, const char **argv, const char *prefix)
        t = init_notes_check(argv[0], NOTES_INIT_WRITABLE);
        note = get_note(t, &object);
 
-       prepare_note_data(&object, &d, edit && note ? note->hash : NULL);
+       prepare_note_data(&object, &d, edit && note ? note : NULL);
 
        if (note && !edit) {
                /* Append buf to previous note contents */
                unsigned long size;
                enum object_type type;
-               char *prev_buf = read_sha1_file(note->hash, &type, &size);
+               char *prev_buf = read_object_file(note, &type, &size);
 
                strbuf_grow(&d.buf, size + 1);
                if (d.buf.len && prev_buf && size)
index e9d3cfb9e33a6b874751ac6acc5aac2361d4a58d..4bdae5a1d8f4c988064475c0583e19c06dabf101 100644 (file)
@@ -1,5 +1,6 @@
 #include "builtin.h"
 #include "cache.h"
+#include "repository.h"
 #include "config.h"
 #include "attr.h"
 #include "object.h"
@@ -28,6 +29,7 @@
 #include "argv-array.h"
 #include "list.h"
 #include "packfile.h"
+#include "object-store.h"
 
 static const char *pack_usage[] = {
        N_("git pack-objects --stdout [<options>...] [< <ref-list> | < <object-list>]"),
@@ -122,11 +124,10 @@ static void *get_delta(struct object_entry *entry)
        void *buf, *base_buf, *delta_buf;
        enum object_type type;
 
-       buf = read_sha1_file(entry->idx.oid.hash, &type, &size);
+       buf = read_object_file(&entry->idx.oid, &type, &size);
        if (!buf)
                die("unable to read %s", oid_to_hex(&entry->idx.oid));
-       base_buf = read_sha1_file(entry->delta->idx.oid.hash, &type,
-                                 &base_size);
+       base_buf = read_object_file(&entry->delta->idx.oid, &type, &base_size);
        if (!base_buf)
                die("unable to read %s",
                    oid_to_hex(&entry->delta->idx.oid));
@@ -267,11 +268,10 @@ static unsigned long write_no_reuse_object(struct hashfile *f, struct object_ent
        if (!usable_delta) {
                if (entry->type == OBJ_BLOB &&
                    entry->size > big_file_threshold &&
-                   (st = open_istream(entry->idx.oid.hash, &type, &size, NULL)) != NULL)
+                   (st = open_istream(&entry->idx.oid, &type, &size, NULL)) != NULL)
                        buf = NULL;
                else {
-                       buf = read_sha1_file(entry->idx.oid.hash, &type,
-                                            &size);
+                       buf = read_object_file(&entry->idx.oid, &type, &size);
                        if (!buf)
                                die(_("unable to read %s"),
                                    oid_to_hex(&entry->idx.oid));
@@ -1025,8 +1025,7 @@ static int want_object_in_pack(const struct object_id *oid,
                if (want != -1)
                        return want;
        }
-
-       list_for_each(pos, &packed_git_mru) {
+       list_for_each(pos, get_packed_git_mru(the_repository)) {
                struct packed_git *p = list_entry(pos, struct packed_git, mru);
                off_t offset;
 
@@ -1044,7 +1043,8 @@ static int want_object_in_pack(const struct object_id *oid,
                        }
                        want = want_found_object(exclude, p);
                        if (!exclude && want > 0)
-                               list_move(&p->mru, &packed_git_mru);
+                               list_move(&p->mru,
+                                         get_packed_git_mru(the_repository));
                        if (want != -1)
                                return want;
                }
@@ -1190,7 +1190,7 @@ static struct pbase_tree_cache *pbase_tree_get(const struct object_id *oid)
        /* Did not find one.  Either we got a bogus request or
         * we need to read and perhaps cache.
         */
-       data = read_sha1_file(oid->hash, &type, &size);
+       data = read_object_file(oid, &type, &size);
        if (!data)
                return NULL;
        if (type != OBJ_TREE) {
@@ -1351,7 +1351,7 @@ static void add_preferred_base(struct object_id *oid)
        if (window <= num_preferred_base++)
                return;
 
-       data = read_object_with_reference(oid->hash, tree_type, &size, tree_oid.hash);
+       data = read_object_with_reference(oid, tree_type, &size, &tree_oid);
        if (!data)
                return;
 
@@ -1516,7 +1516,7 @@ static void check_object(struct object_entry *entry)
                unuse_pack(&w_curs);
        }
 
-       entry->type = sha1_object_info(entry->idx.oid.hash, &entry->size);
+       entry->type = oid_object_info(&entry->idx.oid, &entry->size);
        /*
         * The error condition is checked in prepare_pack().  This is
         * to permit a missing preferred base object to be ignored
@@ -1578,8 +1578,7 @@ static void drop_reused_delta(struct object_entry *entry)
                 * And if that fails, the error will be recorded in entry->type
                 * and dealt with in prepare_pack().
                 */
-               entry->type = sha1_object_info(entry->idx.oid.hash,
-                                              &entry->size);
+               entry->type = oid_object_info(&entry->idx.oid, &entry->size);
        }
 }
 
@@ -1871,8 +1870,7 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
        /* Load data if not already done */
        if (!trg->data) {
                read_lock();
-               trg->data = read_sha1_file(trg_entry->idx.oid.hash, &type,
-                                          &sz);
+               trg->data = read_object_file(&trg_entry->idx.oid, &type, &sz);
                read_unlock();
                if (!trg->data)
                        die("object %s cannot be read",
@@ -1885,8 +1883,7 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
        }
        if (!src->data) {
                read_lock();
-               src->data = read_sha1_file(src_entry->idx.oid.hash, &type,
-                                          &sz);
+               src->data = read_object_file(&src_entry->idx.oid, &type, &sz);
                read_unlock();
                if (!src->data) {
                        if (src_entry->preferred_base) {
@@ -2674,7 +2671,7 @@ static void add_objects_in_unpacked_packs(struct rev_info *revs)
 
        memset(&in_pack, 0, sizeof(in_pack));
 
-       for (p = packed_git; p; p = p->next) {
+       for (p = get_packed_git(the_repository); p; p = p->next) {
                struct object_id oid;
                struct object *o;
 
@@ -2709,7 +2706,7 @@ static void add_objects_in_unpacked_packs(struct rev_info *revs)
 static int add_loose_object(const struct object_id *oid, const char *path,
                            void *data)
 {
-       enum object_type type = sha1_object_info(oid->hash, NULL);
+       enum object_type type = oid_object_info(oid, NULL);
 
        if (type < 0) {
                warning("loose object at %s could not be examined", path);
@@ -2737,7 +2734,8 @@ static int has_sha1_pack_kept_or_nonlocal(const struct object_id *oid)
        static struct packed_git *last_found = (void *)1;
        struct packed_git *p;
 
-       p = (last_found != (void *)1) ? last_found : packed_git;
+       p = (last_found != (void *)1) ? last_found :
+                                       get_packed_git(the_repository);
 
        while (p) {
                if ((!p->pack_local || p->pack_keep) &&
@@ -2746,7 +2744,7 @@ static int has_sha1_pack_kept_or_nonlocal(const struct object_id *oid)
                        return 1;
                }
                if (p == last_found)
-                       p = packed_git;
+                       p = get_packed_git(the_repository);
                else
                        p = p->next;
                if (p == last_found)
@@ -2782,7 +2780,7 @@ static void loosen_unused_packed_objects(struct rev_info *revs)
        uint32_t i;
        struct object_id oid;
 
-       for (p = packed_git; p; p = p->next) {
+       for (p = get_packed_git(the_repository); p; p = p->next) {
                if (!p->pack_local || p->pack_keep)
                        continue;
 
@@ -3150,10 +3148,9 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
        if (progress && all_progress_implied)
                progress = 2;
 
-       prepare_packed_git();
        if (ignore_packed_keep) {
                struct packed_git *p;
-               for (p = packed_git; p; p = p->next)
+               for (p = get_packed_git(the_repository); p; p = p->next)
                        if (p->pack_local && p->pack_keep)
                                break;
                if (!p) /* no keep-able packs found */
@@ -3166,7 +3163,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
                 * also covers non-local objects
                 */
                struct packed_git *p;
-               for (p = packed_git; p; p = p->next) {
+               for (p = get_packed_git(the_repository); p; p = p->next) {
                        if (!p->pack_local) {
                                have_non_local_packs = 1;
                                break;
index 991e1bb76fd66bb189a3523ea5cddf0cd823e343..354478a12762d0b500cf7f56baf90ffc8d2b7c93 100644 (file)
@@ -7,7 +7,9 @@
 */
 
 #include "builtin.h"
+#include "repository.h"
 #include "packfile.h"
+#include "object-store.h"
 
 #define BLKSIZE 512
 
@@ -571,7 +573,7 @@ static struct pack_list * add_pack(struct packed_git *p)
 
 static struct pack_list * add_pack_file(const char *filename)
 {
-       struct packed_git *p = packed_git;
+       struct packed_git *p = get_packed_git(the_repository);
 
        if (strlen(filename) < 40)
                die("Bad pack filename: %s", filename);
@@ -586,7 +588,7 @@ static struct pack_list * add_pack_file(const char *filename)
 
 static void load_all(void)
 {
-       struct packed_git *p = packed_git;
+       struct packed_git *p = get_packed_git(the_repository);
 
        while (p) {
                add_pack(p);
@@ -629,8 +631,6 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix)
                        break;
        }
 
-       prepare_packed_git();
-
        if (load_all_packs)
                load_all();
        else
index 4394d01c9350ae3e1fa26de034edf1509128469e..38ced18dadff03836c6bed3fcbdefe8bd528a7c0 100644 (file)
@@ -50,7 +50,7 @@ static int prune_object(const struct object_id *oid, const char *fullpath,
        if (st.st_mtime > expire)
                return 0;
        if (show_only || verbose) {
-               enum object_type type = sha1_object_info(oid->hash, NULL);
+               enum object_type type = oid_object_info(oid, NULL);
                printf("%s %s\n", oid_to_hex(oid),
                       (type > 0) ? type_name(type) : "unknown");
        }
index 75e7f18aceffc42b5fdc58296559c67d47203098..c4272fbc96dc274f3287ab01f3fbe57c2cdb9d9c 100644 (file)
@@ -1,4 +1,5 @@
 #include "builtin.h"
+#include "repository.h"
 #include "config.h"
 #include "lockfile.h"
 #include "pack.h"
@@ -1242,11 +1243,11 @@ static void check_aliased_update(struct command *cmd, struct string_list *list)
        rp_error("refusing inconsistent update between symref '%s' (%s..%s) and"
                 " its target '%s' (%s..%s)",
                 cmd->ref_name,
-                find_unique_abbrev(cmd->old_oid.hash, DEFAULT_ABBREV),
-                find_unique_abbrev(cmd->new_oid.hash, DEFAULT_ABBREV),
+                find_unique_abbrev(&cmd->old_oid, DEFAULT_ABBREV),
+                find_unique_abbrev(&cmd->new_oid, DEFAULT_ABBREV),
                 dst_cmd->ref_name,
-                find_unique_abbrev(dst_cmd->old_oid.hash, DEFAULT_ABBREV),
-                find_unique_abbrev(dst_cmd->new_oid.hash, DEFAULT_ABBREV));
+                find_unique_abbrev(&dst_cmd->old_oid, DEFAULT_ABBREV),
+                find_unique_abbrev(&dst_cmd->new_oid, DEFAULT_ABBREV));
 
        cmd->error_string = dst_cmd->error_string =
                "inconsistent aliased update";
@@ -1778,7 +1779,7 @@ static const char *unpack(int err_fd, struct shallow_info *si)
                status = finish_command(&child);
                if (status)
                        return "index-pack abnormal exit";
-               reprepare_packed_git();
+               reprepare_packed_git(the_repository);
        }
        return NULL;
 }
@@ -2027,7 +2028,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
                        proc.git_cmd = 1;
                        proc.argv = argv_gc_auto;
 
-                       close_all_packs();
+                       close_all_packs(the_repository->objects);
                        if (!start_command(&proc)) {
                                if (use_sideband)
                                        copy_to_sideband(proc.err, -1, NULL);
index 4719a5354cf182eb91b257a99da97b9b81da5257..a89bd1dd25252ddfe5ad6b32ee89950d3a4b258f 100644 (file)
@@ -75,7 +75,7 @@ static int tree_is_complete(const struct object_id *oid)
        if (!tree->buffer) {
                enum object_type type;
                unsigned long size;
-               void *data = read_sha1_file(oid->hash, &type, &size);
+               void *data = read_object_file(oid, &type, &size);
                if (!data) {
                        tree->object.flags |= INCOMPLETE;
                        return 0;
index 482f12018fa912eeea860721af2acbf5f8a2e87d..935647be6bdf2ffc2b460038a10e63c2eb387a5c 100644 (file)
@@ -53,8 +53,8 @@ static int show_reference(const char *refname, const struct object_id *oid,
                        if (get_oid(refname, &object))
                                return error("Failed to resolve '%s' as a valid ref.", refname);
 
-                       obj_type = sha1_object_info(object.hash, NULL);
-                       repl_type = sha1_object_info(oid->hash, NULL);
+                       obj_type = oid_object_info(&object, NULL);
+                       repl_type = oid_object_info(oid, NULL);
 
                        printf("%s (%s) -> %s (%s)\n", refname, type_name(obj_type),
                               oid_to_hex(oid), type_name(repl_type));
@@ -162,8 +162,8 @@ static int replace_object_oid(const char *object_ref,
        struct ref_transaction *transaction;
        struct strbuf err = STRBUF_INIT;
 
-       obj_type = sha1_object_info(object->hash, NULL);
-       repl_type = sha1_object_info(repl->hash, NULL);
+       obj_type = oid_object_info(object, NULL);
+       repl_type = oid_object_info(repl, NULL);
        if (!force && obj_type != repl_type)
                die("Objects must be of the same type.\n"
                    "'%s' points to a replaced object of type '%s'\n"
@@ -290,7 +290,7 @@ static int edit_and_replace(const char *object_ref, int force, int raw)
        if (get_oid(object_ref, &old_oid) < 0)
                die("Not a valid object name: '%s'", object_ref);
 
-       type = sha1_object_info(old_oid.hash, NULL);
+       type = oid_object_info(&old_oid, NULL);
        if (type < 0)
                die("unable to get object type for %s", oid_to_hex(&old_oid));
 
index 5da0f75de95cc9dc19db7d53a5e4df5140845082..7f1c3f02a302128d6c00c35b8783c1a62353b37a 100644 (file)
@@ -109,7 +109,7 @@ static void print_new_head_line(struct commit *commit)
        struct strbuf buf = STRBUF_INIT;
 
        printf(_("HEAD is now at %s"),
-               find_unique_abbrev(commit->object.oid.hash, DEFAULT_ABBREV));
+               find_unique_abbrev(&commit->object.oid, DEFAULT_ABBREV));
 
        pp_commit_easy(CMIT_FMT_ONELINE, commit, &buf);
        if (buf.len > 0)
index 6f5b9b0847321ca214b4d32719eaeacefffd5ce4..fadd3ec14cbf0469c332a85278e5d1b4932ef788 100644 (file)
@@ -108,7 +108,7 @@ static void show_commit(struct commit *commit, void *data)
        if (!revs->graph)
                fputs(get_revision_mark(revs, commit), stdout);
        if (revs->abbrev_commit && revs->abbrev)
-               fputs(find_unique_abbrev(commit->object.oid.hash, revs->abbrev),
+               fputs(find_unique_abbrev(&commit->object.oid, revs->abbrev),
                      stdout);
        else
                fputs(oid_to_hex(&commit->object.oid), stdout);
index a1e680b5e912beeed183dc271b0ae970a45a4814..36b208778280e6019d9bc4fb4063dff3d44f08e6 100644 (file)
@@ -159,7 +159,7 @@ static void show_rev(int type, const struct object_id *oid, const char *name)
                }
        }
        else if (abbrev)
-               show_with_type(type, find_unique_abbrev(oid->hash, abbrev));
+               show_with_type(type, find_unique_abbrev(oid, abbrev));
        else
                show_with_type(type, oid_to_hex(oid));
 }
index 4447bb4d0faf8c34f3fc96361a651eaad396d6d4..5b6fc7ee818be4a4f060dc06f12fb45a25a2ea9b 100644 (file)
@@ -178,7 +178,7 @@ static int check_local_mod(struct object_id *head, int index_only)
                 * way as changed from the HEAD.
                 */
                if (no_head
-                    || get_tree_entry(head->hash, name, oid.hash, &mode)
+                    || get_tree_entry(head, name, &oid, &mode)
                     || ce->ce_mode != create_ce_mode(mode)
                     || oidcmp(&ce->oid, &oid))
                        staged_changes = 1;
index e29875b84389b25237e39e0112eafa8ac34599ee..608d6ba77bdfb4673513444651053d0e8e789020 100644 (file)
@@ -11,7 +11,8 @@
 #include "parse-options.h"
 
 static char const * const shortlog_usage[] = {
-       N_("git shortlog [<options>] [<revision-range>] [[--] [<path>...]]"),
+       N_("git shortlog [<options>] [<revision-range>] [[--] <path>...]"),
+       N_("git log --pretty=short | git shortlog [<options>]"),
        NULL
 };
 
@@ -283,6 +284,7 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix)
        for (;;) {
                switch (parse_options_step(&ctx, options, shortlog_usage)) {
                case PARSE_OPT_HELP:
+               case PARSE_OPT_ERROR:
                        exit(129);
                case PARSE_OPT_DONE:
                        goto parse_done;
@@ -292,6 +294,11 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix)
 parse_done:
        argc = parse_options_end(&ctx);
 
+       if (nongit && argc > 1) {
+               error(_("too many arguments given outside repository"));
+               usage_with_options(shortlog_usage, options);
+       }
+
        if (setup_revisions(argc, argv, &rev, NULL) != 1) {
                error(_("unrecognized argument: %s"), argv[1]);
                usage_with_options(shortlog_usage, options);
index e8a4aa40cb4b6cf8787af3dd35d833a92a85bba3..6c2148b71db593af1a4ef8d2d1bdbdfe16661851 100644 (file)
@@ -292,7 +292,7 @@ static void show_one_commit(struct commit *commit, int no_name)
                }
                else
                        printf("[%s] ",
-                              find_unique_abbrev(commit->object.oid.hash,
+                              find_unique_abbrev(&commit->object.oid,
                                                  DEFAULT_ABBREV));
        }
        puts(pretty_str);
index 41e5e71cad660d26ddc90ffeaa383fd7bf10f79f..f2eb1a7724058bb1db237a6199d16e5ff1ef495a 100644 (file)
@@ -29,7 +29,7 @@ static void show_one(const char *refname, const struct object_id *oid)
        if (quiet)
                return;
 
-       hex = find_unique_abbrev(oid->hash, abbrev);
+       hex = find_unique_abbrev(oid, abbrev);
        if (hash_only)
                printf("%s\n", hex);
        else
@@ -39,7 +39,7 @@ static void show_one(const char *refname, const struct object_id *oid)
                return;
 
        if (!peel_ref(refname, &peeled)) {
-               hex = find_unique_abbrev(peeled.hash, abbrev);
+               hex = find_unique_abbrev(&peeled, abbrev);
                printf("%s %s^{}\n", hex, refname);
        }
 }
index 6ba8587b6d3b7b8b1bc7a96451916c60210b093b..a404df3ea494d4e4753e5ca95be06b7eed14f617 100644 (file)
@@ -16,6 +16,7 @@
 #include "revision.h"
 #include "diffcore.h"
 #include "diff.h"
+#include "object-store.h"
 
 #define OPT_QUIET (1 << 0)
 #define OPT_CACHED (1 << 1)
@@ -654,9 +655,13 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
                             displaypath);
        } else if (!(flags & OPT_CACHED)) {
                struct object_id oid;
+               struct ref_store *refs = get_submodule_ref_store(path);
 
-               if (refs_head_ref(get_submodule_ref_store(path),
-                                 handle_submodule_head_ref, &oid))
+               if (!refs) {
+                       print_status(flags, '-', path, ce_oid, displaypath);
+                       goto cleanup;
+               }
+               if (refs_head_ref(refs, handle_submodule_head_ref, &oid))
                        die(_("could not resolve HEAD ref inside the "
                              "submodule '%s'"), path);
 
index 42278f51672acae675785b90aad43eb415f3fb14..46a5c6a1da17fa12ff65f33889527ec76869c3cd 100644 (file)
@@ -99,7 +99,8 @@ static int delete_tag(const char *name, const char *ref,
 {
        if (delete_ref(NULL, ref, oid, 0))
                return 1;
-       printf(_("Deleted tag '%s' (was %s)\n"), name, find_unique_abbrev(oid->hash, DEFAULT_ABBREV));
+       printf(_("Deleted tag '%s' (was %s)\n"), name,
+              find_unique_abbrev(oid, DEFAULT_ABBREV));
        return 0;
 }
 
@@ -167,7 +168,7 @@ static void write_tag_body(int fd, const struct object_id *oid)
        enum object_type type;
        char *buf, *sp;
 
-       buf = read_sha1_file(oid->hash, &type, &size);
+       buf = read_object_file(oid, &type, &size);
        if (!buf)
                return;
        /* skip header */
@@ -211,7 +212,7 @@ static void create_tag(const struct object_id *object, const char *tag,
        struct strbuf header = STRBUF_INIT;
        char *path = NULL;
 
-       type = sha1_object_info(object->hash, NULL);
+       type = oid_object_info(object, NULL);
        if (type <= OBJ_NONE)
            die(_("bad object type."));
 
@@ -293,17 +294,17 @@ static void create_reflog_msg(const struct object_id *oid, struct strbuf *sb)
                strbuf_addstr(sb, rla);
        } else {
                strbuf_addstr(sb, "tag: tagging ");
-               strbuf_add_unique_abbrev(sb, oid->hash, DEFAULT_ABBREV);
+               strbuf_add_unique_abbrev(sb, oid, DEFAULT_ABBREV);
        }
 
        strbuf_addstr(sb, " (");
-       type = sha1_object_info(oid->hash, NULL);
+       type = oid_object_info(oid, NULL);
        switch (type) {
        default:
                strbuf_addstr(sb, "object of unknown type");
                break;
        case OBJ_COMMIT:
-               if ((buf = read_sha1_file(oid->hash, &type, &size)) != NULL) {
+               if ((buf = read_object_file(oid, &type, &size)) != NULL) {
                        subject_len = find_commit_subject(buf, &subject_start);
                        strbuf_insert(sb, sb->len, subject_start, subject_len);
                } else {
@@ -558,7 +559,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
                die("%s", err.buf);
        ref_transaction_free(transaction);
        if (force && !is_null_oid(&prev) && oidcmp(&prev, &object))
-               printf(_("Updated tag '%s' (was %s)\n"), tag, find_unique_abbrev(prev.hash, DEFAULT_ABBREV));
+               printf(_("Updated tag '%s' (was %s)\n"), tag,
+                      find_unique_abbrev(&prev, DEFAULT_ABBREV));
 
        UNLEAK(buf);
        UNLEAK(ref);
index 32e01555774c838e489fd33c675488e754c3e8e2..300eb59657e29cace38798029a9170834cac7c9e 100644 (file)
@@ -9,7 +9,7 @@ static char *create_temp_file(struct object_id *oid)
        unsigned long size;
        int fd;
 
-       buf = read_sha1_file(oid->hash, &type, &size);
+       buf = read_object_file(oid, &type, &size);
        if (!buf || type != OBJ_BLOB)
                die("unable to read blob object %s", oid_to_hex(oid));
 
index 6620feec68b15573340f4c28fe6be952e3c00e3a..b7755c6cc5a05a536666d0ae2fd9d0c3171a6cfd 100644 (file)
@@ -199,7 +199,7 @@ static int check_object(struct object *obj, int type, void *data, struct fsck_op
 
        if (!(obj->flags & FLAG_OPEN)) {
                unsigned long size;
-               int type = sha1_object_info(obj->oid.hash, &size);
+               int type = oid_object_info(&obj->oid, &size);
                if (type != obj->type || type <= 0)
                        die("object of unexpected type");
                obj->flags |= FLAG_WRITTEN;
@@ -423,7 +423,7 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size,
        if (resolve_against_held(nr, &base_oid, delta_data, delta_size))
                return;
 
-       base = read_sha1_file(base_oid.hash, &type, &base_size);
+       base = read_object_file(&base_oid, &type, &base_size);
        if (!base) {
                error("failed to read delta-pack base object %s",
                      oid_to_hex(&base_oid));
index 58d1c2d2827d61899d73f1ea7632c5ee219f3ace..10d070a76fb1b0b94c058f60934bb05db37a4164 100644 (file)
@@ -592,7 +592,7 @@ static struct cache_entry *read_one_ent(const char *which,
        int size;
        struct cache_entry *ce;
 
-       if (get_tree_entry(ent->hash, path, oid.hash, &mode)) {
+       if (get_tree_entry(ent, path, &oid, &mode)) {
                if (which)
                        error("%s: not in %s branch.", path, which);
                return NULL;
@@ -1059,6 +1059,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
                        break;
                switch (parseopt_state) {
                case PARSE_OPT_HELP:
+               case PARSE_OPT_ERROR:
                        exit(129);
                case PARSE_OPT_NON_OPTION:
                case PARSE_OPT_DONE:
index 05315ea7c966d3ed5b91e4cbd77eaa9943af253d..dcdaada111071c84b56022d9050ae06ffafbc25f 100644 (file)
@@ -44,7 +44,7 @@ static int verify_commit(const char *name, unsigned flags)
        if (get_oid(name, &oid))
                return error("commit '%s' not found.", name);
 
-       buf = read_sha1_file(oid.hash, &type, &size);
+       buf = read_object_file(&oid, &type, &size);
        if (!buf)
                return error("%s: unable to read file.", name);
        if (type != OBJ_COMMIT)
index 670555deddaca8ff8050c03ea68c83c7b4e459e6..40a438ed6ce802e0745495ba611e49c23e2eefce 100644 (file)
@@ -101,16 +101,9 @@ static int prune_worktree(const char *id, struct strbuf *reason)
        }
        path[len] = '\0';
        if (!file_exists(path)) {
-               struct stat st_link;
                free(path);
-               /*
-                * the repo is moved manually and has not been
-                * accessed since?
-                */
-               if (!stat(git_path("worktrees/%s/link", id), &st_link) &&
-                   st_link.st_nlink > 1)
-                       return 0;
-               if (st.st_mtime <= expire) {
+               if (stat(git_path("worktrees/%s/index", id), &st) ||
+                   st.st_mtime <= expire) {
                        strbuf_addf(reason, _("Removing worktrees/%s: gitdir file points to non-existent location"), id);
                        return 1;
                } else {
@@ -502,7 +495,7 @@ static void show_worktree(struct worktree *wt, int path_maxlen, int abbrev_len)
                strbuf_addstr(&sb, "(bare)");
        else {
                strbuf_addf(&sb, "%-*s ", abbrev_len,
-                               find_unique_abbrev(wt->head_oid.hash, DEFAULT_ABBREV));
+                               find_unique_abbrev(&wt->head_oid, DEFAULT_ABBREV));
                if (wt->is_detached)
                        strbuf_addstr(&sb, "(detached HEAD)");
                else if (wt->head_ref) {
@@ -527,7 +520,7 @@ static void measure_widths(struct worktree **wt, int *abbrev, int *maxlen)
 
                if (path_len > *maxlen)
                        *maxlen = path_len;
-               sha1_len = strlen(find_unique_abbrev(wt[i]->head_oid.hash, *abbrev));
+               sha1_len = strlen(find_unique_abbrev(&wt[i]->head_oid, *abbrev));
                if (sha1_len > *abbrev)
                        *abbrev = sha1_len;
        }
index bd0a78aa3c56b7e817c7ddf6fcaba703d6d5fecc..c9d3c544e79f46bab9e5fd50079d1bb574b722f2 100644 (file)
@@ -19,7 +19,7 @@ int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)
 {
        int flags = 0, ret;
        const char *prefix = NULL;
-       unsigned char sha1[20];
+       struct object_id oid;
        const char *me = "git-write-tree";
        struct option write_tree_options[] = {
                OPT_BIT(0, "missing-ok", &flags, N_("allow missing objects"),
@@ -38,10 +38,10 @@ int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)
        argc = parse_options(argc, argv, unused_prefix, write_tree_options,
                             write_tree_usage, 0);
 
-       ret = write_cache_as_tree(sha1, flags, prefix);
+       ret = write_cache_as_tree(&oid, flags, prefix);
        switch (ret) {
        case 0:
-               printf("%s\n", sha1_to_hex(sha1));
+               printf("%s\n", oid_to_hex(&oid));
                break;
        case WRITE_TREE_UNREADABLE_INDEX:
                die("%s: error reading the index", me);
index 9d87eac07ba1d9bf01bfe4a24c8ba784e71dbac4..de1f4040c788f683a0cca3695c10b163811dd945 100644 (file)
@@ -3,6 +3,7 @@
  */
 #include "cache.h"
 #include "bulk-checkin.h"
+#include "repository.h"
 #include "csum-file.h"
 #include "pack.h"
 #include "strbuf.h"
@@ -57,20 +58,20 @@ static void finish_bulk_checkin(struct bulk_checkin_state *state)
 
        strbuf_release(&packname);
        /* Make objects we just wrote available to ourselves */
-       reprepare_packed_git();
+       reprepare_packed_git(the_repository);
 }
 
-static int already_written(struct bulk_checkin_state *state, unsigned char sha1[])
+static int already_written(struct bulk_checkin_state *state, struct object_id *oid)
 {
        int i;
 
        /* The object may already exist in the repository */
-       if (has_sha1_file(sha1))
+       if (has_sha1_file(oid->hash))
                return 1;
 
        /* Might want to keep the list sorted */
        for (i = 0; i < state->nr_written; i++)
-               if (!hashcmp(state->written[i]->oid.hash, sha1))
+               if (!oidcmp(&state->written[i]->oid, oid))
                        return 1;
 
        /* This is a new object we need to keep */
@@ -186,7 +187,7 @@ static void prepare_to_stream(struct bulk_checkin_state *state,
 }
 
 static int deflate_to_pack(struct bulk_checkin_state *state,
-                          unsigned char result_sha1[],
+                          struct object_id *result_oid,
                           int fd, size_t size,
                           enum object_type type, const char *path,
                           unsigned flags)
@@ -236,17 +237,17 @@ static int deflate_to_pack(struct bulk_checkin_state *state,
                if (lseek(fd, seekback, SEEK_SET) == (off_t) -1)
                        return error("cannot seek back");
        }
-       the_hash_algo->final_fn(result_sha1, &ctx);
+       the_hash_algo->final_fn(result_oid->hash, &ctx);
        if (!idx)
                return 0;
 
        idx->crc32 = crc32_end(state->f);
-       if (already_written(state, result_sha1)) {
+       if (already_written(state, result_oid)) {
                hashfile_truncate(state->f, &checkpoint);
                state->offset = checkpoint.offset;
                free(idx);
        } else {
-               hashcpy(idx->oid.hash, result_sha1);
+               oidcpy(&idx->oid, result_oid);
                ALLOC_GROW(state->written,
                           state->nr_written + 1,
                           state->alloc_written);
@@ -255,11 +256,11 @@ static int deflate_to_pack(struct bulk_checkin_state *state,
        return 0;
 }
 
-int index_bulk_checkin(unsigned char *sha1,
+int index_bulk_checkin(struct object_id *oid,
                       int fd, size_t size, enum object_type type,
                       const char *path, unsigned flags)
 {
-       int status = deflate_to_pack(&state, sha1, fd, size, type,
+       int status = deflate_to_pack(&state, oid, fd, size, type,
                                     path, flags);
        if (!state.plugged)
                finish_bulk_checkin(&state);
index fbd40fc98c955c192a6de698a75b8d56af766f09..a85527318b15b36bb60b0b6b166569b4fcaa9dcf 100644 (file)
@@ -4,7 +4,7 @@
 #ifndef BULK_CHECKIN_H
 #define BULK_CHECKIN_H
 
-extern int index_bulk_checkin(unsigned char sha1[],
+extern int index_bulk_checkin(struct object_id *oid,
                              int fd, size_t size, enum object_type type,
                              const char *path, unsigned flags);
 
index efe547e25fe2a53bd0ef7954cf3bec6d55218365..902c9b54485be2000696a697472fa10d97b36153 100644 (file)
--- a/bundle.c
+++ b/bundle.c
@@ -222,7 +222,7 @@ static int is_tag_in_date_range(struct object *tag, struct rev_info *revs)
        if (revs->max_age == -1 && revs->min_age == -1)
                goto out;
 
-       buf = read_sha1_file(tag->oid.hash, &type, &size);
+       buf = read_object_file(&tag->oid, &type, &size);
        if (!buf)
                goto out;
        line = memmem(buf, size, "\ntagger ", 8);
index c52e4303dfcbc6a17796f536e8602017b1d951f0..6a555f4d431f9f6dbf8dad06d75a4ec81a4254fd 100644 (file)
@@ -320,7 +320,7 @@ static int update_one(struct cache_tree *it,
                struct cache_tree_sub *sub = NULL;
                const char *path, *slash;
                int pathlen, entlen;
-               const unsigned char *sha1;
+               const struct object_id *oid;
                unsigned mode;
                int expected_missing = 0;
                int contains_ita = 0;
@@ -338,7 +338,7 @@ static int update_one(struct cache_tree *it,
                                die("cache-tree.c: '%.*s' in '%s' not found",
                                    entlen, path + baselen, path);
                        i += sub->count;
-                       sha1 = sub->cache_tree->oid.hash;
+                       oid = &sub->cache_tree->oid;
                        mode = S_IFDIR;
                        contains_ita = sub->cache_tree->entry_count < 0;
                        if (contains_ita) {
@@ -347,19 +347,19 @@ static int update_one(struct cache_tree *it,
                        }
                }
                else {
-                       sha1 = ce->oid.hash;
+                       oid = &ce->oid;
                        mode = ce->ce_mode;
                        entlen = pathlen - baselen;
                        i++;
                }
 
-               if (is_null_sha1(sha1) ||
-                   (mode != S_IFGITLINK && !missing_ok && !has_sha1_file(sha1))) {
+               if (is_null_oid(oid) ||
+                   (mode != S_IFGITLINK && !missing_ok && !has_object_file(oid))) {
                        strbuf_release(&buffer);
                        if (expected_missing)
                                return -1;
                        return error("invalid object %06o %s for '%.*s'",
-                               mode, sha1_to_hex(sha1), entlen+baselen, path);
+                               mode, oid_to_hex(oid), entlen+baselen, path);
                }
 
                /*
@@ -385,12 +385,12 @@ static int update_one(struct cache_tree *it,
                /*
                 * "sub" can be an empty tree if all subentries are i-t-a.
                 */
-               if (contains_ita && !hashcmp(sha1, EMPTY_TREE_SHA1_BIN))
+               if (contains_ita && !oidcmp(oid, &empty_tree_oid))
                        continue;
 
                strbuf_grow(&buffer, entlen + 100);
                strbuf_addf(&buffer, "%o %.*s%c", mode, entlen, path + baselen, '\0');
-               strbuf_add(&buffer, sha1, 20);
+               strbuf_add(&buffer, oid->hash, the_hash_algo->rawsz);
 
 #if DEBUG
                fprintf(stderr, "cache-tree update-one %o %.*s\n",
@@ -401,7 +401,7 @@ static int update_one(struct cache_tree *it,
        if (repair) {
                struct object_id oid;
                hash_object_file(buffer.buf, buffer.len, tree_type, &oid);
-               if (has_sha1_file(oid.hash))
+               if (has_object_file(&oid))
                        oidcpy(&it->oid, &oid);
                else
                        to_invalidate = 1;
@@ -465,7 +465,7 @@ static void write_one(struct strbuf *buffer, struct cache_tree *it,
 #endif
 
        if (0 <= it->entry_count) {
-               strbuf_add(buffer, it->oid.hash, 20);
+               strbuf_add(buffer, it->oid.hash, the_hash_algo->rawsz);
        }
        for (i = 0; i < it->subtree_nr; i++) {
                struct cache_tree_sub *down = it->down[i];
@@ -492,6 +492,7 @@ static struct cache_tree *read_one(const char **buffer, unsigned long *size_p)
        char *ep;
        struct cache_tree *it;
        int i, subtree_nr;
+       const unsigned rawsz = the_hash_algo->rawsz;
 
        it = NULL;
        /* skip name, but make sure name exists */
@@ -520,11 +521,11 @@ static struct cache_tree *read_one(const char **buffer, unsigned long *size_p)
                goto free_return;
        buf++; size--;
        if (0 <= it->entry_count) {
-               if (size < 20)
+               if (size < rawsz)
                        goto free_return;
-               hashcpy(it->oid.hash, (const unsigned char*)buf);
-               buf += 20;
-               size -= 20;
+               memcpy(it->oid.hash, (const unsigned char*)buf, rawsz);
+               buf += rawsz;
+               size -= rawsz;
        }
 
 #if DEBUG
@@ -599,7 +600,7 @@ static struct cache_tree *cache_tree_find(struct cache_tree *it, const char *pat
        return it;
 }
 
-int write_index_as_tree(unsigned char *sha1, struct index_state *index_state, const char *index_path, int flags, const char *prefix)
+int write_index_as_tree(struct object_id *oid, struct index_state *index_state, const char *index_path, int flags, const char *prefix)
 {
        int entries, was_valid;
        struct lock_file lock_file = LOCK_INIT;
@@ -640,19 +641,19 @@ int write_index_as_tree(unsigned char *sha1, struct index_state *index_state, co
                        ret = WRITE_TREE_PREFIX_ERROR;
                        goto out;
                }
-               hashcpy(sha1, subtree->oid.hash);
+               oidcpy(oid, &subtree->oid);
        }
        else
-               hashcpy(sha1, index_state->cache_tree->oid.hash);
+               oidcpy(oid, &index_state->cache_tree->oid);
 
 out:
        rollback_lock_file(&lock_file);
        return ret;
 }
 
-int write_cache_as_tree(unsigned char *sha1, int flags, const char *prefix)
+int write_cache_as_tree(struct object_id *oid, int flags, const char *prefix)
 {
-       return write_index_as_tree(sha1, &the_index, get_index_file(), flags, prefix);
+       return write_index_as_tree(oid, &the_index, get_index_file(), flags, prefix);
 }
 
 static void prime_cache_tree_rec(struct cache_tree *it, struct tree *tree)
index f7b9cab7ee87dd04cecbd25f34101a58fc002014..cfd5328cc93694e23037e15148241e17bd4f3a04 100644 (file)
@@ -47,8 +47,8 @@ int update_main_cache_tree(int);
 #define WRITE_TREE_UNMERGED_INDEX (-2)
 #define WRITE_TREE_PREFIX_ERROR (-3)
 
-int write_index_as_tree(unsigned char *sha1, struct index_state *index_state, const char *index_path, int flags, const char *prefix);
-int write_cache_as_tree(unsigned char *sha1, int flags, const char *prefix);
+int write_index_as_tree(struct object_id *oid, struct index_state *index_state, const char *index_path, int flags, const char *prefix);
+int write_cache_as_tree(struct object_id *oid, int flags, const char *prefix);
 void prime_cache_tree(struct index_state *, struct tree *);
 
 extern int cache_tree_matches_traversal(struct cache_tree *, struct name_entry *ent, struct traverse_info *info);
diff --git a/cache.h b/cache.h
index a61b2d3f0d79b0f56992e0343803811f5265d716..77b7acebb6f73b6681fdd6bc4111e3b325409fdb 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -459,7 +459,7 @@ static inline enum object_type object_type(unsigned int mode)
  */
 extern const char * const local_repo_env[];
 
-extern void setup_git_env(void);
+extern void setup_git_env(const char *git_dir);
 
 /*
  * Returns true iff we have a configured git repository (either via
@@ -477,7 +477,7 @@ extern const char *get_git_common_dir(void);
 extern char *get_object_directory(void);
 extern char *get_index_file(void);
 extern char *get_graft_file(void);
-extern int set_git_dir(const char *path);
+extern void set_git_dir(const char *path);
 extern int get_common_dir_noenv(struct strbuf *sb, const char *gitdir);
 extern int get_common_dir(struct strbuf *sb, const char *gitdir);
 extern const char *get_git_namespace(void);
@@ -940,12 +940,6 @@ extern void check_repository_format(void);
 #define DATA_CHANGED    0x0020
 #define TYPE_CHANGED    0x0040
 
-/*
- * Put in `buf` the name of the file in the local object database that
- * would be used to store a loose object with the specified sha1.
- */
-extern void sha1_file_name(struct strbuf *buf, const unsigned char *sha1);
-
 /*
  * Return an abbreviated sha1 unique within this repository's object database.
  * The result will be at least `len` characters long, and will be NUL
@@ -955,14 +949,14 @@ extern void sha1_file_name(struct strbuf *buf, const unsigned char *sha1);
  * more calls to find_unique_abbrev are made.
  *
  * The `_r` variant writes to a buffer supplied by the caller, which must be at
- * least `GIT_SHA1_HEXSZ + 1` bytes. The return value is the number of bytes
+ * least `GIT_MAX_HEXSZ + 1` bytes. The return value is the number of bytes
  * written (excluding the NUL terminator).
  *
  * Note that while this version avoids the static buffer, it is not fully
  * reentrant, as it calls into other non-reentrant git code.
  */
-extern const char *find_unique_abbrev(const unsigned char *sha1, int len);
-extern int find_unique_abbrev_r(char *hex, const unsigned char *sha1, int len);
+extern const char *find_unique_abbrev(const struct object_id *oid, int len);
+extern int find_unique_abbrev_r(char *hex, const struct object_id *oid, int len);
 
 extern const unsigned char null_sha1[GIT_MAX_RAWSZ];
 extern const struct object_id null_oid;
@@ -1189,19 +1183,19 @@ extern char *xdg_config_home(const char *filename);
  */
 extern char *xdg_cache_home(const char *filename);
 
-extern void *read_sha1_file_extended(const unsigned char *sha1,
-                                    enum object_type *type,
-                                    unsigned long *size, int lookup_replace);
-static inline void *read_sha1_file(const unsigned char *sha1, enum object_type *type, unsigned long *size)
+extern void *read_object_file_extended(const struct object_id *oid,
+                                      enum object_type *type,
+                                      unsigned long *size, int lookup_replace);
+static inline void *read_object_file(const struct object_id *oid, enum object_type *type, unsigned long *size)
 {
-       return read_sha1_file_extended(sha1, type, size, 1);
+       return read_object_file_extended(oid, type, size, 1);
 }
 
 /*
  * This internal function is only declared here for the benefit of
  * lookup_replace_object().  Please do not call it directly.
  */
-extern const unsigned char *do_lookup_replace_object(const unsigned char *sha1);
+extern const struct object_id *do_lookup_replace_object(const struct object_id *oid);
 
 /*
  * If object sha1 should be replaced, return the replacement object's
@@ -1209,15 +1203,15 @@ extern const unsigned char *do_lookup_replace_object(const unsigned char *sha1);
  * either sha1 or a pointer to a permanently-allocated value.  When
  * object replacement is suppressed, always return sha1.
  */
-static inline const unsigned char *lookup_replace_object(const unsigned char *sha1)
+static inline const struct object_id *lookup_replace_object(const struct object_id *oid)
 {
        if (!check_replace_refs)
-               return sha1;
-       return do_lookup_replace_object(sha1);
+               return oid;
+       return do_lookup_replace_object(oid);
 }
 
-/* Read and unpack a sha1 file into memory, write memory to a sha1 file */
-extern int sha1_object_info(const unsigned char *, unsigned long *);
+/* Read and unpack an object file into memory, write memory to an object file */
+extern int oid_object_info(const struct object_id *, unsigned long *);
 
 extern int hash_object_file(const void *buf, unsigned long len,
                            const char *type, struct object_id *oid);
@@ -1236,23 +1230,22 @@ extern int force_object_loose(const struct object_id *oid, time_t mtime);
 
 extern int git_open_cloexec(const char *name, int flags);
 #define git_open(name) git_open_cloexec(name, O_RDONLY)
-extern void *map_sha1_file(const unsigned char *sha1, unsigned long *size);
 extern int unpack_sha1_header(git_zstream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz);
 extern int parse_sha1_header(const char *hdr, unsigned long *sizep);
 
-extern int check_sha1_signature(const unsigned char *sha1, void *buf, unsigned long size, const char *type);
+extern int check_object_signature(const struct object_id *oid, void *buf, unsigned long size, const char *type);
 
 extern int finalize_object_file(const char *tmpfile, const char *filename);
 
 /*
- * Open the loose object at path, check its sha1, and return the contents,
+ * Open the loose object at path, check its hash, and return the contents,
  * type, and size. If the object is a blob, then "contents" may return NULL,
  * to allow streaming of large blobs.
  *
  * Returns 0 on success, negative on error (details may be written to stderr).
  */
 int read_loose_object(const char *path,
-                     const unsigned char *expected_sha1,
+                     const struct object_id *expected_oid,
                      enum object_type *type,
                      unsigned long *size,
                      void **contents);
@@ -1279,7 +1272,7 @@ extern int has_object_file_with_flags(const struct object_id *oid, int flags);
  */
 extern int has_loose_object_nonlocal(const unsigned char *sha1);
 
-extern void assert_sha1_type(const unsigned char *sha1, enum object_type expect);
+extern void assert_oid_type(const struct object_id *oid, enum object_type expect);
 
 /* Helper to check and "touch" a file */
 extern int check_and_freshen_file(const char *fn, int freshen);
@@ -1435,10 +1428,10 @@ extern int df_name_compare(const char *name1, int len1, int mode1, const char *n
 extern int name_compare(const char *name1, size_t len1, const char *name2, size_t len2);
 extern int cache_name_stage_compare(const char *name1, int len1, int stage1, const char *name2, int len2, int stage2);
 
-extern void *read_object_with_reference(const unsigned char *sha1,
+extern void *read_object_with_reference(const struct object_id *oid,
                                        const char *required_type,
                                        unsigned long *size,
-                                       unsigned char *sha1_ret);
+                                       struct object_id *oid_ret);
 
 extern struct object *peel_to_type(const char *name, int namelen,
                                   struct object *o, enum object_type);
@@ -1564,57 +1557,6 @@ extern int has_dirs_only_path(const char *name, int len, int prefix_len);
 extern void schedule_dir_for_removal(const char *name, int len);
 extern void remove_scheduled_dirs(void);
 
-extern struct alternate_object_database {
-       struct alternate_object_database *next;
-
-       /* see alt_scratch_buf() */
-       struct strbuf scratch;
-       size_t base_len;
-
-       /*
-        * Used to store the results of readdir(3) calls when searching
-        * for unique abbreviated hashes.  This cache is never
-        * invalidated, thus it's racy and not necessarily accurate.
-        * That's fine for its purpose; don't use it for tasks requiring
-        * greater accuracy!
-        */
-       char loose_objects_subdir_seen[256];
-       struct oid_array loose_objects_cache;
-
-       char path[FLEX_ARRAY];
-} *alt_odb_list;
-extern void prepare_alt_odb(void);
-extern char *compute_alternate_path(const char *path, struct strbuf *err);
-typedef int alt_odb_fn(struct alternate_object_database *, void *);
-extern int foreach_alt_odb(alt_odb_fn, void*);
-
-/*
- * Allocate a "struct alternate_object_database" but do _not_ actually
- * add it to the list of alternates.
- */
-struct alternate_object_database *alloc_alt_odb(const char *dir);
-
-/*
- * Add the directory to the on-disk alternates file; the new entry will also
- * take effect in the current process.
- */
-extern void add_to_alternates_file(const char *dir);
-
-/*
- * Add the directory to the in-memory list of alternates (along with any
- * recursive alternates it points to), but do not modify the on-disk alternates
- * file.
- */
-extern void add_to_alternates_memory(const char *dir);
-
-/*
- * Returns a scratch strbuf pre-filled with the alternate object directory,
- * including a trailing slash, which can be used to access paths in the
- * alternate. Always use this over direct access to alt->scratch, as it
- * cleans up any previous use of the scratch buffer.
- */
-extern struct strbuf *alt_scratch_buf(struct alternate_object_database *alt);
-
 struct pack_window {
        struct pack_window *next;
        unsigned char *base;
@@ -1624,35 +1566,6 @@ struct pack_window {
        unsigned int inuse_cnt;
 };
 
-extern struct packed_git {
-       struct packed_git *next;
-       struct list_head mru;
-       struct pack_window *windows;
-       off_t pack_size;
-       const void *index_data;
-       size_t index_size;
-       uint32_t num_objects;
-       uint32_t num_bad_objects;
-       unsigned char *bad_object_sha1;
-       int index_version;
-       time_t mtime;
-       int pack_fd;
-       unsigned pack_local:1,
-                pack_keep:1,
-                freshened:1,
-                do_not_close:1,
-                pack_promisor:1;
-       unsigned char sha1[20];
-       struct revindex_entry *revindex;
-       /* something like ".git/objects/pack/xxxxx.pack" */
-       char pack_name[FLEX_ARRAY]; /* more */
-} *packed_git;
-
-/*
- * A most-recently-used ordered version of the packed_git list.
- */
-extern struct list_head packed_git_mru;
-
 struct pack_entry {
        off_t offset;
        unsigned char sha1[20];
@@ -1777,7 +1690,9 @@ struct object_info {
 #define OBJECT_INFO_SKIP_CACHED 4
 /* Do not retry packed storage after checking packed and loose storage */
 #define OBJECT_INFO_QUICK 8
-extern int sha1_object_info_extended(const unsigned char *, struct object_info *, unsigned flags);
+/* Do not check loose object */
+#define OBJECT_INFO_IGNORE_LOOSE 16
+extern int oid_object_info_extended(const struct object_id *, struct object_info *, unsigned flags);
 
 /*
  * Set this to 0 to prevent sha1_object_info_extended() from fetching missing
diff --git a/chdir-notify.c b/chdir-notify.c
new file mode 100644 (file)
index 0000000..5f7f2c2
--- /dev/null
@@ -0,0 +1,93 @@
+#include "cache.h"
+#include "chdir-notify.h"
+#include "list.h"
+#include "strbuf.h"
+
+struct chdir_notify_entry {
+       const char *name;
+       chdir_notify_callback cb;
+       void *data;
+       struct list_head list;
+};
+static LIST_HEAD(chdir_notify_entries);
+
+void chdir_notify_register(const char *name,
+                          chdir_notify_callback cb,
+                          void *data)
+{
+       struct chdir_notify_entry *e = xmalloc(sizeof(*e));
+       e->name = name;
+       e->cb = cb;
+       e->data = data;
+       list_add_tail(&e->list, &chdir_notify_entries);
+}
+
+static void reparent_cb(const char *name,
+                       const char *old_cwd,
+                       const char *new_cwd,
+                       void *data)
+{
+       char **path = data;
+       char *tmp = *path;
+
+       if (!tmp)
+               return;
+
+       *path = reparent_relative_path(old_cwd, new_cwd, tmp);
+       free(tmp);
+
+       if (name) {
+               trace_printf_key(&trace_setup_key,
+                                "setup: reparent %s to '%s'",
+                                name, *path);
+       }
+}
+
+void chdir_notify_reparent(const char *name, char **path)
+{
+       chdir_notify_register(name, reparent_cb, path);
+}
+
+int chdir_notify(const char *new_cwd)
+{
+       struct strbuf old_cwd = STRBUF_INIT;
+       struct list_head *pos;
+
+       if (strbuf_getcwd(&old_cwd) < 0)
+               return -1;
+       if (chdir(new_cwd) < 0) {
+               int saved_errno = errno;
+               strbuf_release(&old_cwd);
+               errno = saved_errno;
+               return -1;
+       }
+
+       trace_printf_key(&trace_setup_key,
+                        "setup: chdir from '%s' to '%s'",
+                        old_cwd.buf, new_cwd);
+
+       list_for_each(pos, &chdir_notify_entries) {
+               struct chdir_notify_entry *e =
+                       list_entry(pos, struct chdir_notify_entry, list);
+               e->cb(e->name, old_cwd.buf, new_cwd, e->data);
+       }
+
+       strbuf_release(&old_cwd);
+       return 0;
+}
+
+char *reparent_relative_path(const char *old_cwd,
+                            const char *new_cwd,
+                            const char *path)
+{
+       char *ret, *full;
+
+       if (is_absolute_path(path))
+               return xstrdup(path);
+
+       full = xstrfmt("%s/%s", old_cwd, path);
+       ret = xstrdup(remove_leading_path(full, new_cwd));
+       free(full);
+
+       return ret;
+}
diff --git a/chdir-notify.h b/chdir-notify.h
new file mode 100644 (file)
index 0000000..366e4c1
--- /dev/null
@@ -0,0 +1,73 @@
+#ifndef CHDIR_NOTIFY_H
+#define CHDIR_NOTIFY_H
+
+/*
+ * An API to let code "subscribe" to changes to the current working directory.
+ * The general idea is that some code asks to be notified when the working
+ * directory changes, and other code that calls chdir uses a special wrapper
+ * that notifies everyone.
+ */
+
+/*
+ * Callers who need to know about changes can do:
+ *
+ *   void foo(const char *old_path, const char *new_path, void *data)
+ *   {
+ *     warning("switched from %s to %s!", old_path, new_path);
+ *   }
+ *   ...
+ *   chdir_notify_register("description", foo, data);
+ *
+ * In practice most callers will want to move a relative path to the new root;
+ * they can use the reparent_relative_path() helper for that. If that's all
+ * you're doing, you can also use the convenience function:
+ *
+ *   chdir_notify_reparent("description", &my_path);
+ *
+ * Whenever a chdir event occurs, that will update my_path (if it's relative)
+ * to adjust for the new cwd by freeing any existing string and allocating a
+ * new one.
+ *
+ * Registered functions are called in the order in which they were added. Note
+ * that there's currently no way to remove a function, so make sure that the
+ * data parameter remains valid for the rest of the program.
+ *
+ * The "name" argument is used only for printing trace output from
+ * $GIT_TRACE_SETUP. It may be NULL, but if non-NULL should point to
+ * storage which lasts as long as the registration is active.
+ */
+typedef void (*chdir_notify_callback)(const char *name,
+                                     const char *old_cwd,
+                                     const char *new_cwd,
+                                     void *data);
+void chdir_notify_register(const char *name, chdir_notify_callback cb, void *data);
+void chdir_notify_reparent(const char *name, char **path);
+
+/*
+ *
+ * Callers that want to chdir:
+ *
+ *   chdir_notify(new_path);
+ *
+ * to switch to the new path and notify any callbacks.
+ *
+ * Note that you don't need to chdir_notify() if you're just temporarily moving
+ * to a directory and back, as long as you don't call any subscribed code in
+ * between (but it should be safe to do so if you're unsure).
+ */
+int chdir_notify(const char *new_cwd);
+
+/*
+ * Reparent a relative path from old_root to new_root. For example:
+ *
+ *   reparent_relative_path("/a", "/a/b", "b/rel");
+ *
+ * would return the (newly allocated) string "rel". Note that we may return an
+ * absolute path in some cases (e.g., if the resulting path is not inside
+ * new_cwd).
+ */
+char *reparent_relative_path(const char *old_cwd,
+                            const char *new_cwd,
+                            const char *path);
+
+#endif /* CHDIR_NOTIFY_H */
index 1ec9af1f813968830ee153e23a4670014124683f..2ef495963fc1cf2e092778d35f1965912d7eaac0 100644 (file)
@@ -306,7 +306,7 @@ static char *grab_blob(const struct object_id *oid, unsigned int mode,
                *size = fill_textconv(textconv, df, &blob);
                free_filespec(df);
        } else {
-               blob = read_sha1_file(oid->hash, &type, size);
+               blob = read_object_file(oid, &type, size);
                if (type != OBJ_BLOB)
                        die("object '%s' is not a blob!", oid_to_hex(oid));
        }
@@ -915,11 +915,11 @@ static void show_combined_header(struct combine_diff_path *elem,
                         "", elem->path, line_prefix, c_meta, c_reset);
        printf("%s%sindex ", line_prefix, c_meta);
        for (i = 0; i < num_parent; i++) {
-               abb = find_unique_abbrev(elem->parent[i].oid.hash,
+               abb = find_unique_abbrev(&elem->parent[i].oid,
                                         abbrev);
                printf("%s%s", i ? "," : "", abb);
        }
-       abb = find_unique_abbrev(elem->oid.hash, abbrev);
+       abb = find_unique_abbrev(&elem->oid, abbrev);
        printf("..%s%s\n", abb, c_reset);
 
        if (mode_differs) {
index 00c99c7272badc2d5a8f16c29db7d4040f5eb4d3..ca474a7c112855a49b77cce7cdfb83937fa17fae 100644 (file)
--- a/commit.c
+++ b/commit.c
@@ -266,7 +266,7 @@ const void *get_commit_buffer(const struct commit *commit, unsigned long *sizep)
        if (!ret) {
                enum object_type type;
                unsigned long size;
-               ret = read_sha1_file(commit->object.oid.hash, &type, &size);
+               ret = read_object_file(&commit->object.oid, &type, &size);
                if (!ret)
                        die("cannot read commit object %s",
                            oid_to_hex(&commit->object.oid));
@@ -383,7 +383,7 @@ int parse_commit_gently(struct commit *item, int quiet_on_missing)
                return -1;
        if (item->object.parsed)
                return 0;
-       buffer = read_sha1_file(item->object.oid.hash, &type, &size);
+       buffer = read_object_file(&item->object.oid, &type, &size);
        if (!buffer)
                return quiet_on_missing ? -1 :
                        error("Could not read %s",
@@ -1206,7 +1206,7 @@ static void handle_signed_tag(struct commit *parent, struct commit_extra_header
        desc = merge_remote_util(parent);
        if (!desc || !desc->obj)
                return;
-       buf = read_sha1_file(desc->obj->oid.hash, &type, &size);
+       buf = read_object_file(&desc->obj->oid, &type, &size);
        if (!buf || type != OBJ_TAG)
                goto free_return;
        len = parse_signature(buf, size);
@@ -1517,7 +1517,7 @@ int commit_tree_extended(const char *msg, size_t msg_len,
        int encoding_is_utf8;
        struct strbuf buffer;
 
-       assert_sha1_type(tree->hash, OBJ_TREE);
+       assert_oid_type(tree, OBJ_TREE);
 
        if (memchr(msg, '\0', msg_len))
                return error("a NUL byte in commit log message not allowed.");
index 6a689007e7ce3fe08f148e8b82c0a1c618c513a5..7d716d5a5491ba6b3a596f2128c4f08253d1d364 100644 (file)
@@ -34,6 +34,8 @@ int main(int argc, const char **argv)
 
        git_setup_gettext();
 
+       initialize_the_repository();
+
        attr_start();
 
        git_extract_argv0_path(argv[0]);
index b0c20e6cb8ab1f5dc3cd3b4573b7e9d6dbf8cd2b..563853c4be2620d86f90734034427206ed92e613 100644 (file)
--- a/config.c
+++ b/config.c
@@ -1426,6 +1426,7 @@ static int do_config_from_file(config_fn_t fn,
                void *data)
 {
        struct config_source top;
+       int ret;
 
        top.u.file = f;
        top.origin_type = origin_type;
@@ -1436,7 +1437,10 @@ static int do_config_from_file(config_fn_t fn,
        top.do_ungetc = config_file_ungetc;
        top.do_ftell = config_file_ftell;
 
-       return do_config_from(&top, fn, data);
+       flockfile(f);
+       ret = do_config_from(&top, fn, data);
+       funlockfile(f);
+       return ret;
 }
 
 static int git_config_from_stdin(config_fn_t fn, void *data)
@@ -1451,9 +1455,7 @@ int git_config_from_file(config_fn_t fn, const char *filename, void *data)
 
        f = fopen_or_warn(filename, "r");
        if (f) {
-               flockfile(f);
                ret = do_config_from_file(fn, CONFIG_ORIGIN_FILE, filename, filename, f, data);
-               funlockfile(f);
                fclose(f);
        }
        return ret;
@@ -1488,7 +1490,7 @@ int git_config_from_blob_oid(config_fn_t fn,
        unsigned long size;
        int ret;
 
-       buf = read_sha1_file(oid->hash, &type, &size);
+       buf = read_object_file(oid, &type, &size);
        if (!buf)
                return error("unable to load config blob object '%s'", name);
        if (type != OBJ_BLOB) {
index 7f8415140f309e0522310fac3160b5a01cefc7cd..6f1fd9df35ef7d477ddb75de454a4708176ad634 100644 (file)
@@ -254,25 +254,25 @@ GIT_PARSE_WITH([openssl]))
 # Perl-compatible regular expressions instead of standard or extended
 # POSIX regular expressions.
 #
-# Currently USE_LIBPCRE is a synonym for USE_LIBPCRE1, define
-# USE_LIBPCRE2 instead if you'd like to use version 2 of the PCRE
-# library. The USE_LIBPCRE flag will likely be changed to mean v2 by
-# default in future releases.
+# USE_LIBPCRE is a synonym for USE_LIBPCRE2, define USE_LIBPCRE1
+# instead if you'd like to use the legacy version 1 of the PCRE
+# library. Support for version 1 will likely be removed in some future
+# release of Git, as upstream has all but abandoned it.
 #
 # Define LIBPCREDIR=/foo/bar if your PCRE header and library files are in
 # /foo/bar/include and /foo/bar/lib directories.
 #
 AC_ARG_WITH(libpcre,
-AS_HELP_STRING([--with-libpcre],[synonym for --with-libpcre1]),
+AS_HELP_STRING([--with-libpcre],[synonym for --with-libpcre2]),
     if test "$withval" = "no"; then
-       USE_LIBPCRE1=
+       USE_LIBPCRE2=
     elif test "$withval" = "yes"; then
-       USE_LIBPCRE1=YesPlease
+       USE_LIBPCRE2=YesPlease
     else
-       USE_LIBPCRE1=YesPlease
+       USE_LIBPCRE2=YesPlease
        LIBPCREDIR=$withval
        AC_MSG_NOTICE([Setting LIBPCREDIR to $LIBPCREDIR])
-        dnl USE_LIBPCRE1 can still be modified below, so don't substitute
+        dnl USE_LIBPCRE2 can still be modified below, so don't substitute
         dnl it yet.
        GIT_CONF_SUBST([LIBPCREDIR])
     fi)
@@ -296,6 +296,10 @@ AS_HELP_STRING([],           [ARG can be also prefix for libpcre library and hea
 AC_ARG_WITH(libpcre2,
 AS_HELP_STRING([--with-libpcre2],[support Perl-compatible regexes via libpcre2 (default is NO)])
 AS_HELP_STRING([],           [ARG can be also prefix for libpcre library and headers]),
+    if test -n "$USE_LIBPCRE2"; then
+        AC_MSG_ERROR([Only supply one of --with-libpcre or its synonym --with-libpcre2!])
+    fi
+
     if test -n "$USE_LIBPCRE1"; then
         AC_MSG_ERROR([Only supply one of --with-libpcre1 or --with-libpcre2!])
     fi
@@ -549,8 +553,8 @@ if test -n "$USE_LIBPCRE1"; then
 GIT_STASH_FLAGS($LIBPCREDIR)
 
 AC_CHECK_LIB([pcre], [pcre_version],
-[USE_LIBPCRE=YesPlease],
-[USE_LIBPCRE=])
+[USE_LIBPCRE1=YesPlease],
+[USE_LIBPCRE1=])
 
 GIT_UNSTASH_FLAGS($LIBPCREDIR)
 
index b09c8a23626b431a0cb97f6f7f930cccce25bf07..a7570739454ac793430b7f0edb8ba229f3ff50d8 100644 (file)
@@ -29,6 +29,8 @@
 # tell the completion to use commit completion.  This also works with aliases
 # of form "!sh -c '...'".  For example, "!sh -c ': git commit ; ... '".
 #
+# Compatible with bash 3.2.57.
+#
 # You can set the following environment variables to influence the behavior of
 # the completion routines:
 #
@@ -1284,6 +1286,12 @@ _git_checkout ()
 
 _git_cherry ()
 {
+       case "$cur" in
+       --*)
+               __gitcomp_builtin cherry
+               return
+       esac
+
        __git_complete_refs
 }
 
@@ -1503,16 +1511,6 @@ _git_fsck ()
        esac
 }
 
-_git_gc ()
-{
-       case "$cur" in
-       --*)
-               __gitcomp_builtin gc
-               return
-               ;;
-       esac
-}
-
 _git_gitk ()
 {
        _gitk
@@ -1637,6 +1635,13 @@ _git_ls_remote ()
 
 _git_ls_tree ()
 {
+       case "$cur" in
+       --*)
+               __gitcomp_builtin ls-tree
+               return
+               ;;
+       esac
+
        __git_complete_file
 }
 
@@ -1812,11 +1817,6 @@ _git_mv ()
        fi
 }
 
-_git_name_rev ()
-{
-       __gitcomp_builtin name-rev
-}
-
 _git_notes ()
 {
        local subcommands='add append copy edit get-ref list merge prune remove show'
@@ -3036,6 +3036,45 @@ _git_worktree ()
        fi
 }
 
+__git_complete_common () {
+       local command="$1"
+
+       case "$cur" in
+       --*)
+               __gitcomp_builtin "$command"
+               ;;
+       esac
+}
+
+__git_cmds_with_parseopt_helper=
+__git_support_parseopt_helper () {
+       test -n "$__git_cmds_with_parseopt_helper" ||
+               __git_cmds_with_parseopt_helper="$(__git --list-parseopt-builtins)"
+
+       case " $__git_cmds_with_parseopt_helper " in
+       *" $1 "*)
+               return 0
+               ;;
+       *)
+               return 1
+               ;;
+       esac
+}
+
+__git_complete_command () {
+       local command="$1"
+       local completion_func="_git_${command//-/_}"
+       if declare -f $completion_func >/dev/null 2>/dev/null; then
+               $completion_func
+               return 0
+       elif __git_support_parseopt_helper "$command"; then
+               __git_complete_common "$command"
+               return 0
+       else
+               return 1
+       fi
+}
+
 __git_main ()
 {
        local i c=1 command __git_dir __git_repo_path
@@ -3095,14 +3134,12 @@ __git_main ()
                return
        fi
 
-       local completion_func="_git_${command//-/_}"
-       declare -f $completion_func >/dev/null 2>/dev/null && $completion_func && return
+       __git_complete_command "$command" && return
 
        local expansion=$(__git_aliased_command "$command")
        if [ -n "$expansion" ]; then
                words[1]=$expansion
-               completion_func="_git_${expansion//-/_}"
-               declare -f $completion_func >/dev/null 2>/dev/null && $completion_func
+               __git_complete_command "$expansion"
        fi
 }
 
index 663992e530c82f891361ccc9b952099aff3d56ec..536754583b59945e984ad487b6e524e5d1de7056 100644 (file)
@@ -21,37 +21,82 @@ package DiffHighlight;
 my $COLOR = qr/\x1b\[[0-9;]*m/;
 my $BORING = qr/$COLOR|\s/;
 
-# The patch portion of git log -p --graph should only ever have preceding | and
-# not / or \ as merge history only shows up on the commit line.
-my $GRAPH = qr/$COLOR?\|$COLOR?\s+/;
-
 my @removed;
 my @added;
 my $in_hunk;
+my $graph_indent = 0;
 
 our $line_cb = sub { print @_ };
 our $flush_cb = sub { local $| = 1 };
 
-sub handle_line {
+# Count the visible width of a string, excluding any terminal color sequences.
+sub visible_width {
        local $_ = shift;
+       my $ret = 0;
+       while (length) {
+               if (s/^$COLOR//) {
+                       # skip colors
+               } elsif (s/^.//) {
+                       $ret++;
+               }
+       }
+       return $ret;
+}
+
+# Return a substring of $str, omitting $len visible characters from the
+# beginning, where terminal color sequences do not count as visible.
+sub visible_substr {
+       my ($str, $len) = @_;
+       while ($len > 0) {
+               if ($str =~ s/^$COLOR//) {
+                       next
+               }
+               $str =~ s/^.//;
+               $len--;
+       }
+       return $str;
+}
+
+sub handle_line {
+       my $orig = shift;
+       local $_ = $orig;
+
+       # match a graph line that begins a commit
+       if (/^(?:$COLOR?\|$COLOR?[ ])* # zero or more leading "|" with space
+                $COLOR?\*$COLOR?[ ]   # a "*" with its trailing space
+             (?:$COLOR?\|$COLOR?[ ])* # zero or more trailing "|"
+                                [ ]*  # trailing whitespace for merges
+           /x) {
+               my $graph_prefix = $&;
+
+               # We must flush before setting graph indent, since the
+               # new commit may be indented differently from what we
+               # queued.
+               flush();
+               $graph_indent = visible_width($graph_prefix);
+
+       } elsif ($graph_indent) {
+               if (length($_) < $graph_indent) {
+                       $graph_indent = 0;
+               } else {
+                       $_ = visible_substr($_, $graph_indent);
+               }
+       }
 
        if (!$in_hunk) {
-               $line_cb->($_);
-               $in_hunk = /^$GRAPH*$COLOR*\@\@ /;
+               $line_cb->($orig);
+               $in_hunk = /^$COLOR*\@\@ /;
        }
-       elsif (/^$GRAPH*$COLOR*-/) {
-               push @removed, $_;
+       elsif (/^$COLOR*-/) {
+               push @removed, $orig;
        }
-       elsif (/^$GRAPH*$COLOR*\+/) {
-               push @added, $_;
+       elsif (/^$COLOR*\+/) {
+               push @added, $orig;
        }
        else {
-               show_hunk(\@removed, \@added);
-               @removed = ();
-               @added = ();
-
-               $line_cb->($_);
-               $in_hunk = /^$GRAPH*$COLOR*[\@ ]/;
+               flush();
+               $line_cb->($orig);
+               $in_hunk = /^$COLOR*[\@ ]/;
        }
 
        # Most of the time there is enough output to keep things streaming,
@@ -71,6 +116,8 @@ sub flush {
        # Flush any queued hunk (this can happen when there is no trailing
        # context in the final diff of the input).
        show_hunk(\@removed, \@added);
+       @removed = ();
+       @added = ();
 }
 
 sub highlight_stdin {
@@ -226,8 +273,8 @@ sub is_pair_interesting {
        my $suffix_a = join('', @$a[($sa+1)..$#$a]);
        my $suffix_b = join('', @$b[($sb+1)..$#$b]);
 
-       return $prefix_a !~ /^$GRAPH*$COLOR*-$BORING*$/ ||
-              $prefix_b !~ /^$GRAPH*$COLOR*\+$BORING*$/ ||
+       return visible_substr($prefix_a, $graph_indent) !~ /^$COLOR*-$BORING*$/ ||
+              visible_substr($prefix_b, $graph_indent) !~ /^$COLOR*\+$BORING*$/ ||
               $suffix_a !~ /^$BORING*$/ ||
               $suffix_b !~ /^$BORING*$/;
 }
index 3b43dbed7488c5f4a5f05809725ffd0bcd7e61b5..f6f5195d00f6ca01b0751fc1c1b58055f0ef25ee 100755 (executable)
@@ -52,15 +52,17 @@ test_strip_patch_header () {
 # dh_test_setup_history generates a contrived graph such that we have at least
 # 1 nesting (E) and 2 nestings (F).
 #
-#            A branch
-#           /
-#      D---E---F master
+#        A---B master
+#       /
+#      D---E---F branch
 #
 #      git log --all --graph
 #      * commit
-#      |    A
+#      |    B
 #      | * commit
 #      | |    F
+#      * | commit
+#      | |    A
 #      | * commit
 #      |/
 #      |    E
@@ -68,24 +70,30 @@ test_strip_patch_header () {
 #           D
 #
 dh_test_setup_history () {
-       echo "file1" >file1 &&
-       echo "file2" >file2 &&
-       echo "file3" >file3 &&
-
-       cat file1 >file &&
+       echo file1 >file &&
        git add file &&
+       test_tick &&
        git commit -m "D" &&
 
        git checkout -b branch &&
-       cat file2 >file &&
-       git commit -a -m "A" &&
+       echo file2 >file &&
+       test_tick &&
+       git commit -a -m "E" &&
 
        git checkout master &&
-       cat file2 >file &&
-       git commit -a -m "E" &&
+       echo file2 >file &&
+       test_tick &&
+       git commit -a -m "A" &&
 
-       cat file3 >file &&
-       git commit -a -m "F"
+       git checkout branch &&
+       echo file3 >file &&
+       test_tick &&
+       git commit -a -m "F" &&
+
+       git checkout master &&
+       echo file3 >file &&
+       test_tick &&
+       git commit -a -m "B"
 }
 
 left_trim () {
@@ -246,16 +254,25 @@ test_expect_failure 'diff-highlight treats combining code points as a unit' '
 test_expect_success 'diff-highlight works with the --graph option' '
        dh_test_setup_history &&
 
-       # topo-order so that the order of the commits is the same as with --graph
+       # date-order so that the commits are interleaved for both
        # trim graph elements so we can do a diff
        # trim leading space because our trim_graph is not perfect
-       git log --branches -p --topo-order |
+       git log --branches -p --date-order |
                "$DIFF_HIGHLIGHT" | left_trim >graph.exp &&
-       git log --branches -p --graph |
+       git log --branches -p --date-order --graph |
                "$DIFF_HIGHLIGHT" | trim_graph | left_trim >graph.act &&
        test_cmp graph.exp graph.act
 '
 
+# Just reuse the previous graph test, but with --color.  Our trimming
+# doesn't know about color, so just sanity check that something got
+# highlighted.
+test_expect_success 'diff-highlight works with color graph' '
+       git log --branches -p --date-order --graph --color |
+               "$DIFF_HIGHLIGHT" | trim_graph | left_trim >graph &&
+       grep "\[7m" graph
+'
+
 # Most combined diffs won't meet diff-highlight's line-number filter. So we
 # create one here where one side drops a line and the other modifies it. That
 # should result in a diff like:
@@ -293,4 +310,32 @@ test_expect_success 'diff-highlight ignores combined diffs' '
        test_cmp expect actual
 '
 
+test_expect_success 'diff-highlight handles --graph with leading dash' '
+       cat >file <<-\EOF &&
+       before
+       the old line
+       -leading dash
+       EOF
+       git add file &&
+       git commit -m before &&
+
+       sed s/old/new/ <file >file.tmp &&
+       mv file.tmp file &&
+       git add file &&
+       git commit -m after &&
+
+       cat >expect <<-EOF &&
+       --- a/file
+       +++ b/file
+       @@ -1,3 +1,3 @@
+        before
+       -the ${CW}old${CR} line
+       +the ${CW}new${CR} line
+        -leading dash
+       EOF
+       git log --graph -p -1 | "$DIFF_HIGHLIGHT" >actual.raw &&
+       trim_graph <actual.raw | sed -n "/^---/,\$p" >actual &&
+       test_cmp expect actual
+'
+
 test_done
index 6946f3dd2ad924639f03b3779635c759c938c1e4..18bc60b021be00f69d2b5a784996bbc1e98c82c1 100644 (file)
@@ -1,3 +1,20 @@
-These are original scripted implementations, kept primarily for their
-reference value to any aspiring plumbing users who want to learn how
-pieces can be fit together.
+This directory used to contain scripted implementations of builtins
+that have since been rewritten in C.
+
+They have now been removed, but can be retrieved from an older commit
+that removed them from this directory.
+
+They're interesting for their reference value to any aspiring plumbing
+users who want to learn how pieces can be fit together, but in many
+cases have drifted enough from the actual implementations Git uses to
+be instructive.
+
+Other things that can be useful:
+
+ * Some commands such as git-gc wrap other commands, and what they're
+   doing behind the scenes can be seen by running them under
+   GIT_TRACE=1
+
+ * Doing `git log` on paths matching '*--helper.c' will show
+   incremental effort in the direction of moving existing shell
+   scripts to C.
diff --git a/contrib/examples/builtin-fetch--tool.c b/contrib/examples/builtin-fetch--tool.c
deleted file mode 100644 (file)
index 22648c3..0000000
+++ /dev/null
@@ -1,575 +0,0 @@
-#include "builtin.h"
-#include "cache.h"
-#include "refs.h"
-#include "commit.h"
-#include "sigchain.h"
-
-static char *get_stdin(void)
-{
-       struct strbuf buf = STRBUF_INIT;
-       if (strbuf_read(&buf, 0, 1024) < 0) {
-               die_errno("error reading standard input");
-       }
-       return strbuf_detach(&buf, NULL);
-}
-
-static void show_new(enum object_type type, unsigned char *sha1_new)
-{
-       fprintf(stderr, "  %s: %s\n", type_name(type),
-               find_unique_abbrev(sha1_new, DEFAULT_ABBREV));
-}
-
-static int update_ref_env(const char *action,
-                     const char *refname,
-                     unsigned char *sha1,
-                     unsigned char *oldval)
-{
-       char msg[1024];
-       const char *rla = getenv("GIT_REFLOG_ACTION");
-
-       if (!rla)
-               rla = "(reflog update)";
-       if (snprintf(msg, sizeof(msg), "%s: %s", rla, action) >= sizeof(msg))
-               warning("reflog message too long: %.*s...", 50, msg);
-       return update_ref(msg, refname, sha1, oldval, 0,
-                         UPDATE_REFS_QUIET_ON_ERR);
-}
-
-static int update_local_ref(const char *name,
-                           const char *new_head,
-                           const char *note,
-                           int verbose, int force)
-{
-       unsigned char sha1_old[20], sha1_new[20];
-       char oldh[41], newh[41];
-       struct commit *current, *updated;
-       enum object_type type;
-
-       if (get_sha1_hex(new_head, sha1_new))
-               die("malformed object name %s", new_head);
-
-       type = sha1_object_info(sha1_new, NULL);
-       if (type < 0)
-               die("object %s not found", new_head);
-
-       if (!*name) {
-               /* Not storing */
-               if (verbose) {
-                       fprintf(stderr, "* fetched %s\n", note);
-                       show_new(type, sha1_new);
-               }
-               return 0;
-       }
-
-       if (get_sha1(name, sha1_old)) {
-               const char *msg;
-       just_store:
-               /* new ref */
-               if (!strncmp(name, "refs/tags/", 10))
-                       msg = "storing tag";
-               else
-                       msg = "storing head";
-               fprintf(stderr, "* %s: storing %s\n",
-                       name, note);
-               show_new(type, sha1_new);
-               return update_ref_env(msg, name, sha1_new, NULL);
-       }
-
-       if (!hashcmp(sha1_old, sha1_new)) {
-               if (verbose) {
-                       fprintf(stderr, "* %s: same as %s\n", name, note);
-                       show_new(type, sha1_new);
-               }
-               return 0;
-       }
-
-       if (!strncmp(name, "refs/tags/", 10)) {
-               fprintf(stderr, "* %s: updating with %s\n", name, note);
-               show_new(type, sha1_new);
-               return update_ref_env("updating tag", name, sha1_new, NULL);
-       }
-
-       current = lookup_commit_reference(sha1_old);
-       updated = lookup_commit_reference(sha1_new);
-       if (!current || !updated)
-               goto just_store;
-
-       strcpy(oldh, find_unique_abbrev(current->object.sha1, DEFAULT_ABBREV));
-       strcpy(newh, find_unique_abbrev(sha1_new, DEFAULT_ABBREV));
-
-       if (in_merge_bases(current, updated)) {
-               fprintf(stderr, "* %s: fast-forward to %s\n",
-                       name, note);
-               fprintf(stderr, "  old..new: %s..%s\n", oldh, newh);
-               return update_ref_env("fast-forward", name, sha1_new, sha1_old);
-       }
-       if (!force) {
-               fprintf(stderr,
-                       "* %s: not updating to non-fast-forward %s\n",
-                       name, note);
-               fprintf(stderr,
-                       "  old...new: %s...%s\n", oldh, newh);
-               return 1;
-       }
-       fprintf(stderr,
-               "* %s: forcing update to non-fast-forward %s\n",
-               name, note);
-       fprintf(stderr, "  old...new: %s...%s\n", oldh, newh);
-       return update_ref_env("forced-update", name, sha1_new, sha1_old);
-}
-
-static int append_fetch_head(FILE *fp,
-                            const char *head, const char *remote,
-                            const char *remote_name, const char *remote_nick,
-                            const char *local_name, int not_for_merge,
-                            int verbose, int force)
-{
-       struct commit *commit;
-       int remote_len, i, note_len;
-       unsigned char sha1[20];
-       char note[1024];
-       const char *what, *kind;
-
-       if (get_sha1(head, sha1))
-               return error("Not a valid object name: %s", head);
-       commit = lookup_commit_reference_gently(sha1, 1);
-       if (!commit)
-               not_for_merge = 1;
-
-       if (!strcmp(remote_name, "HEAD")) {
-               kind = "";
-               what = "";
-       }
-       else if (!strncmp(remote_name, "refs/heads/", 11)) {
-               kind = "branch";
-               what = remote_name + 11;
-       }
-       else if (!strncmp(remote_name, "refs/tags/", 10)) {
-               kind = "tag";
-               what = remote_name + 10;
-       }
-       else if (!strncmp(remote_name, "refs/remotes/", 13)) {
-               kind = "remote-tracking branch";
-               what = remote_name + 13;
-       }
-       else {
-               kind = "";
-               what = remote_name;
-       }
-
-       remote_len = strlen(remote);
-       for (i = remote_len - 1; remote[i] == '/' && 0 <= i; i--)
-               ;
-       remote_len = i + 1;
-       if (4 < i && !strncmp(".git", remote + i - 3, 4))
-               remote_len = i - 3;
-
-       note_len = 0;
-       if (*what) {
-               if (*kind)
-                       note_len += sprintf(note + note_len, "%s ", kind);
-               note_len += sprintf(note + note_len, "'%s' of ", what);
-       }
-       note_len += sprintf(note + note_len, "%.*s", remote_len, remote);
-       fprintf(fp, "%s\t%s\t%s\n",
-               sha1_to_hex(commit ? commit->object.sha1 : sha1),
-               not_for_merge ? "not-for-merge" : "",
-               note);
-       return update_local_ref(local_name, head, note, verbose, force);
-}
-
-static char *keep;
-static void remove_keep(void)
-{
-       if (keep && *keep)
-               unlink(keep);
-}
-
-static void remove_keep_on_signal(int signo)
-{
-       remove_keep();
-       sigchain_pop(signo);
-       raise(signo);
-}
-
-static char *find_local_name(const char *remote_name, const char *refs,
-                            int *force_p, int *not_for_merge_p)
-{
-       const char *ref = refs;
-       int len = strlen(remote_name);
-
-       while (ref) {
-               const char *next;
-               int single_force, not_for_merge;
-
-               while (*ref == '\n')
-                       ref++;
-               if (!*ref)
-                       break;
-               next = strchr(ref, '\n');
-
-               single_force = not_for_merge = 0;
-               if (*ref == '+') {
-                       single_force = 1;
-                       ref++;
-               }
-               if (*ref == '.') {
-                       not_for_merge = 1;
-                       ref++;
-                       if (*ref == '+') {
-                               single_force = 1;
-                               ref++;
-                       }
-               }
-               if (!strncmp(remote_name, ref, len) && ref[len] == ':') {
-                       const char *local_part = ref + len + 1;
-                       int retlen;
-
-                       if (!next)
-                               retlen = strlen(local_part);
-                       else
-                               retlen = next - local_part;
-                       *force_p = single_force;
-                       *not_for_merge_p = not_for_merge;
-                       return xmemdupz(local_part, retlen);
-               }
-               ref = next;
-       }
-       return NULL;
-}
-
-static int fetch_native_store(FILE *fp,
-                             const char *remote,
-                             const char *remote_nick,
-                             const char *refs,
-                             int verbose, int force)
-{
-       char buffer[1024];
-       int err = 0;
-
-       sigchain_push_common(remove_keep_on_signal);
-       atexit(remove_keep);
-
-       while (fgets(buffer, sizeof(buffer), stdin)) {
-               int len;
-               char *cp;
-               char *local_name;
-               int single_force, not_for_merge;
-
-               for (cp = buffer; *cp && !isspace(*cp); cp++)
-                       ;
-               if (*cp)
-                       *cp++ = 0;
-               len = strlen(cp);
-               if (len && cp[len-1] == '\n')
-                       cp[--len] = 0;
-               if (!strcmp(buffer, "failed"))
-                       die("Fetch failure: %s", remote);
-               if (!strcmp(buffer, "pack"))
-                       continue;
-               if (!strcmp(buffer, "keep")) {
-                       char *od = get_object_directory();
-                       int len = strlen(od) + strlen(cp) + 50;
-                       keep = xmalloc(len);
-                       sprintf(keep, "%s/pack/pack-%s.keep", od, cp);
-                       continue;
-               }
-
-               local_name = find_local_name(cp, refs,
-                                            &single_force, &not_for_merge);
-               if (!local_name)
-                       continue;
-               err |= append_fetch_head(fp,
-                                        buffer, remote, cp, remote_nick,
-                                        local_name, not_for_merge,
-                                        verbose, force || single_force);
-       }
-       return err;
-}
-
-static int parse_reflist(const char *reflist)
-{
-       const char *ref;
-
-       printf("refs='");
-       for (ref = reflist; ref; ) {
-               const char *next;
-               while (*ref && isspace(*ref))
-                       ref++;
-               if (!*ref)
-                       break;
-               for (next = ref; *next && !isspace(*next); next++)
-                       ;
-               printf("\n%.*s", (int)(next - ref), ref);
-               ref = next;
-       }
-       printf("'\n");
-
-       printf("rref='");
-       for (ref = reflist; ref; ) {
-               const char *next, *colon;
-               while (*ref && isspace(*ref))
-                       ref++;
-               if (!*ref)
-                       break;
-               for (next = ref; *next && !isspace(*next); next++)
-                       ;
-               if (*ref == '.')
-                       ref++;
-               if (*ref == '+')
-                       ref++;
-               colon = strchr(ref, ':');
-               putchar('\n');
-               printf("%.*s", (int)((colon ? colon : next) - ref), ref);
-               ref = next;
-       }
-       printf("'\n");
-       return 0;
-}
-
-static int expand_refs_wildcard(const char *ls_remote_result, int numrefs,
-                               const char **refs)
-{
-       int i, matchlen, replacelen;
-       int found_one = 0;
-       const char *remote = *refs++;
-       numrefs--;
-
-       if (numrefs == 0) {
-               fprintf(stderr, "Nothing specified for fetching with remote.%s.fetch\n",
-                       remote);
-               printf("empty\n");
-       }
-
-       for (i = 0; i < numrefs; i++) {
-               const char *ref = refs[i];
-               const char *lref = ref;
-               const char *colon;
-               const char *tail;
-               const char *ls;
-               const char *next;
-
-               if (*lref == '+')
-                       lref++;
-               colon = strchr(lref, ':');
-               tail = lref + strlen(lref);
-               if (!(colon &&
-                     2 < colon - lref &&
-                     colon[-1] == '*' &&
-                     colon[-2] == '/' &&
-                     2 < tail - (colon + 1) &&
-                     tail[-1] == '*' &&
-                     tail[-2] == '/')) {
-                       /* not a glob */
-                       if (!found_one++)
-                               printf("explicit\n");
-                       printf("%s\n", ref);
-                       continue;
-               }
-
-               /* glob */
-               if (!found_one++)
-                       printf("glob\n");
-
-               /* lref to colon-2 is remote hierarchy name;
-                * colon+1 to tail-2 is local.
-                */
-               matchlen = (colon-1) - lref;
-               replacelen = (tail-1) - (colon+1);
-               for (ls = ls_remote_result; ls; ls = next) {
-                       const char *eol;
-                       unsigned char sha1[20];
-                       int namelen;
-
-                       while (*ls && isspace(*ls))
-                               ls++;
-                       next = strchr(ls, '\n');
-                       eol = !next ? (ls + strlen(ls)) : next;
-                       if (!memcmp("^{}", eol-3, 3))
-                               continue;
-                       if (eol - ls < 40)
-                               continue;
-                       if (get_sha1_hex(ls, sha1))
-                               continue;
-                       ls += 40;
-                       while (ls < eol && isspace(*ls))
-                               ls++;
-                       /* ls to next (or eol) is the name.
-                        * is it identical to lref to colon-2?
-                        */
-                       if ((eol - ls) <= matchlen ||
-                           strncmp(ls, lref, matchlen))
-                               continue;
-
-                       /* Yes, it is a match */
-                       namelen = eol - ls;
-                       if (lref != ref)
-                               putchar('+');
-                       printf("%.*s:%.*s%.*s\n",
-                              namelen, ls,
-                              replacelen, colon + 1,
-                              namelen - matchlen, ls + matchlen);
-               }
-       }
-       return 0;
-}
-
-static int pick_rref(int sha1_only, const char *rref, const char *ls_remote_result)
-{
-       int err = 0;
-       int lrr_count = lrr_count, i, pass;
-       const char *cp;
-       struct lrr {
-               const char *line;
-               const char *name;
-               int namelen;
-               int shown;
-       } *lrr_list = lrr_list;
-
-       for (pass = 0; pass < 2; pass++) {
-               /* pass 0 counts and allocates, pass 1 fills... */
-               cp = ls_remote_result;
-               i = 0;
-               while (1) {
-                       const char *np;
-                       while (*cp && isspace(*cp))
-                               cp++;
-                       if (!*cp)
-                               break;
-                       np = strchrnul(cp, '\n');
-                       if (pass) {
-                               lrr_list[i].line = cp;
-                               lrr_list[i].name = cp + 41;
-                               lrr_list[i].namelen = np - (cp + 41);
-                       }
-                       i++;
-                       cp = np;
-               }
-               if (!pass) {
-                       lrr_count = i;
-                       lrr_list = xcalloc(lrr_count, sizeof(*lrr_list));
-               }
-       }
-
-       while (1) {
-               const char *next;
-               int rreflen;
-               int i;
-
-               while (*rref && isspace(*rref))
-                       rref++;
-               if (!*rref)
-                       break;
-               next = strchrnul(rref, '\n');
-               rreflen = next - rref;
-
-               for (i = 0; i < lrr_count; i++) {
-                       struct lrr *lrr = &(lrr_list[i]);
-
-                       if (rreflen == lrr->namelen &&
-                           !memcmp(lrr->name, rref, rreflen)) {
-                               if (!lrr->shown)
-                                       printf("%.*s\n",
-                                              sha1_only ? 40 : lrr->namelen + 41,
-                                              lrr->line);
-                               lrr->shown = 1;
-                               break;
-                       }
-               }
-               if (lrr_count <= i) {
-                       error("pick-rref: %.*s not found", rreflen, rref);
-                       err = 1;
-               }
-               rref = next;
-       }
-       free(lrr_list);
-       return err;
-}
-
-int cmd_fetch__tool(int argc, const char **argv, const char *prefix)
-{
-       int verbose = 0;
-       int force = 0;
-       int sopt = 0;
-
-       while (1 < argc) {
-               const char *arg = argv[1];
-               if (!strcmp("-v", arg))
-                       verbose = 1;
-               else if (!strcmp("-f", arg))
-                       force = 1;
-               else if (!strcmp("-s", arg))
-                       sopt = 1;
-               else
-                       break;
-               argc--;
-               argv++;
-       }
-
-       if (argc <= 1)
-               return error("Missing subcommand");
-
-       if (!strcmp("append-fetch-head", argv[1])) {
-               int result;
-               FILE *fp;
-               char *filename;
-
-               if (argc != 8)
-                       return error("append-fetch-head takes 6 args");
-               filename = git_path_fetch_head();
-               fp = fopen(filename, "a");
-               if (!fp)
-                       return error("cannot open %s: %s", filename, strerror(errno));
-               result = append_fetch_head(fp, argv[2], argv[3],
-                                          argv[4], argv[5],
-                                          argv[6], !!argv[7][0],
-                                          verbose, force);
-               fclose(fp);
-               return result;
-       }
-       if (!strcmp("native-store", argv[1])) {
-               int result;
-               FILE *fp;
-               char *filename;
-
-               if (argc != 5)
-                       return error("fetch-native-store takes 3 args");
-               filename = git_path_fetch_head();
-               fp = fopen(filename, "a");
-               if (!fp)
-                       return error("cannot open %s: %s", filename, strerror(errno));
-               result = fetch_native_store(fp, argv[2], argv[3], argv[4],
-                                           verbose, force);
-               fclose(fp);
-               return result;
-       }
-       if (!strcmp("parse-reflist", argv[1])) {
-               const char *reflist;
-               if (argc != 3)
-                       return error("parse-reflist takes 1 arg");
-               reflist = argv[2];
-               if (!strcmp(reflist, "-"))
-                       reflist = get_stdin();
-               return parse_reflist(reflist);
-       }
-       if (!strcmp("pick-rref", argv[1])) {
-               const char *ls_remote_result;
-               if (argc != 4)
-                       return error("pick-rref takes 2 args");
-               ls_remote_result = argv[3];
-               if (!strcmp(ls_remote_result, "-"))
-                       ls_remote_result = get_stdin();
-               return pick_rref(sopt, argv[2], ls_remote_result);
-       }
-       if (!strcmp("expand-refs-wildcard", argv[1])) {
-               const char *reflist;
-               if (argc < 4)
-                       return error("expand-refs-wildcard takes at least 2 args");
-               reflist = argv[2];
-               if (!strcmp(reflist, "-"))
-                       reflist = get_stdin();
-               return expand_refs_wildcard(reflist, argc - 3, argv + 3);
-       }
-
-       return error("Unknown subcommand: %s", argv[1]);
-}
diff --git a/contrib/examples/git-am.sh b/contrib/examples/git-am.sh
deleted file mode 100755 (executable)
index dd539f1..0000000
+++ /dev/null
@@ -1,975 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005, 2006 Junio C Hamano
-
-SUBDIRECTORY_OK=Yes
-OPTIONS_KEEPDASHDASH=
-OPTIONS_STUCKLONG=t
-OPTIONS_SPEC="\
-git am [options] [(<mbox>|<Maildir>)...]
-git am [options] (--continue | --skip | --abort)
---
-i,interactive   run interactively
-b,binary*       (historical option -- no-op)
-3,3way          allow fall back on 3way merging if needed
-q,quiet         be quiet
-s,signoff       add a Signed-off-by line to the commit message
-u,utf8          recode into utf8 (default)
-k,keep          pass -k flag to git-mailinfo
-keep-non-patch  pass -b flag to git-mailinfo
-m,message-id    pass -m flag to git-mailinfo
-keep-cr         pass --keep-cr flag to git-mailsplit for mbox format
-no-keep-cr      do not pass --keep-cr flag to git-mailsplit independent of am.keepcr
-c,scissors      strip everything before a scissors line
-whitespace=     pass it through git-apply
-ignore-space-change pass it through git-apply
-ignore-whitespace pass it through git-apply
-directory=      pass it through git-apply
-exclude=        pass it through git-apply
-include=        pass it through git-apply
-C=              pass it through git-apply
-p=              pass it through git-apply
-patch-format=   format the patch(es) are in
-reject          pass it through git-apply
-resolvemsg=     override error message when patch failure occurs
-continue        continue applying patches after resolving a conflict
-r,resolved      synonyms for --continue
-skip            skip the current patch
-abort           restore the original branch and abort the patching operation.
-committer-date-is-author-date    lie about committer date
-ignore-date     use current timestamp for author date
-rerere-autoupdate update the index with reused conflict resolution if possible
-S,gpg-sign?     GPG-sign commits
-rebasing*       (internal use for git-rebase)"
-
-. git-sh-setup
-. git-sh-i18n
-prefix=$(git rev-parse --show-prefix)
-set_reflog_action am
-require_work_tree
-cd_to_toplevel
-
-git var GIT_COMMITTER_IDENT >/dev/null ||
-       die "$(gettext "You need to set your committer info first")"
-
-if git rev-parse --verify -q HEAD >/dev/null
-then
-       HAS_HEAD=yes
-else
-       HAS_HEAD=
-fi
-
-cmdline="git am"
-if test '' != "$interactive"
-then
-       cmdline="$cmdline -i"
-fi
-if test '' != "$threeway"
-then
-       cmdline="$cmdline -3"
-fi
-
-empty_tree=4b825dc642cb6eb9a060e54bf8d69288fbee4904
-
-sq () {
-       git rev-parse --sq-quote "$@"
-}
-
-stop_here () {
-    echo "$1" >"$dotest/next"
-    git rev-parse --verify -q HEAD >"$dotest/abort-safety"
-    exit 1
-}
-
-safe_to_abort () {
-       if test -f "$dotest/dirtyindex"
-       then
-               return 1
-       fi
-
-       if ! test -f "$dotest/abort-safety"
-       then
-               return 0
-       fi
-
-       abort_safety=$(cat "$dotest/abort-safety")
-       if test "z$(git rev-parse --verify -q HEAD)" = "z$abort_safety"
-       then
-               return 0
-       fi
-       gettextln "You seem to have moved HEAD since the last 'am' failure.
-Not rewinding to ORIG_HEAD" >&2
-       return 1
-}
-
-stop_here_user_resolve () {
-    if [ -n "$resolvemsg" ]; then
-           printf '%s\n' "$resolvemsg"
-           stop_here $1
-    fi
-    eval_gettextln "When you have resolved this problem, run \"\$cmdline --continue\".
-If you prefer to skip this patch, run \"\$cmdline --skip\" instead.
-To restore the original branch and stop patching, run \"\$cmdline --abort\"."
-
-    stop_here $1
-}
-
-go_next () {
-       rm -f "$dotest/$msgnum" "$dotest/msg" "$dotest/msg-clean" \
-               "$dotest/patch" "$dotest/info"
-       echo "$next" >"$dotest/next"
-       this=$next
-}
-
-cannot_fallback () {
-       echo "$1"
-       gettextln "Cannot fall back to three-way merge."
-       exit 1
-}
-
-fall_back_3way () {
-    O_OBJECT=$(cd "$GIT_OBJECT_DIRECTORY" && pwd)
-
-    rm -fr "$dotest"/patch-merge-*
-    mkdir "$dotest/patch-merge-tmp-dir"
-
-    # First see if the patch records the index info that we can use.
-    cmd="git apply $git_apply_opt --build-fake-ancestor" &&
-    cmd="$cmd "'"$dotest/patch-merge-tmp-index" "$dotest/patch"' &&
-    eval "$cmd" &&
-    GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
-    git write-tree >"$dotest/patch-merge-base+" ||
-    cannot_fallback "$(gettext "Repository lacks necessary blobs to fall back on 3-way merge.")"
-
-    say "$(gettext "Using index info to reconstruct a base tree...")"
-
-    cmd='GIT_INDEX_FILE="$dotest/patch-merge-tmp-index"'
-
-    if test -z "$GIT_QUIET"
-    then
-       eval "$cmd git diff-index --cached --diff-filter=AM --name-status HEAD"
-    fi
-
-    cmd="$cmd git apply --cached $git_apply_opt"' <"$dotest/patch"'
-    if eval "$cmd"
-    then
-       mv "$dotest/patch-merge-base+" "$dotest/patch-merge-base"
-       mv "$dotest/patch-merge-tmp-index" "$dotest/patch-merge-index"
-    else
-       cannot_fallback "$(gettext "Did you hand edit your patch?
-It does not apply to blobs recorded in its index.")"
-    fi
-
-    test -f "$dotest/patch-merge-index" &&
-    his_tree=$(GIT_INDEX_FILE="$dotest/patch-merge-index" git write-tree) &&
-    orig_tree=$(cat "$dotest/patch-merge-base") &&
-    rm -fr "$dotest"/patch-merge-* || exit 1
-
-    say "$(gettext "Falling back to patching base and 3-way merge...")"
-
-    # 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 recursive ends up canceling them,
-    # saying that we reverted all those changes.
-
-    eval GITHEAD_$his_tree='"$FIRSTLINE"'
-    export GITHEAD_$his_tree
-    if test -n "$GIT_QUIET"
-    then
-           GIT_MERGE_VERBOSITY=0 && export GIT_MERGE_VERBOSITY
-    fi
-    our_tree=$(git rev-parse --verify -q HEAD || echo $empty_tree)
-    git-merge-recursive $orig_tree -- $our_tree $his_tree || {
-           git rerere $allow_rerere_autoupdate
-           die "$(gettext "Failed to merge in the changes.")"
-    }
-    unset GITHEAD_$his_tree
-}
-
-clean_abort () {
-       test $# = 0 || echo >&2 "$@"
-       rm -fr "$dotest"
-       exit 1
-}
-
-patch_format=
-
-check_patch_format () {
-       # early return if patch_format was set from the command line
-       if test -n "$patch_format"
-       then
-               return 0
-       fi
-
-       # we default to mbox format if input is from stdin and for
-       # directories
-       if test $# = 0 || test "x$1" = "x-" || test -d "$1"
-       then
-               patch_format=mbox
-               return 0
-       fi
-
-       # otherwise, check the first few non-blank lines of the first
-       # patch to try to detect its format
-       {
-               # Start from first line containing non-whitespace
-               l1=
-               while test -z "$l1"
-               do
-                       read l1 || break
-               done
-               read l2
-               read l3
-               case "$l1" in
-               "From "* | "From: "*)
-                       patch_format=mbox
-                       ;;
-               '# This series applies on GIT commit'*)
-                       patch_format=stgit-series
-                       ;;
-               "# HG changeset patch")
-                       patch_format=hg
-                       ;;
-               *)
-                       # if the second line is empty and the third is
-                       # a From, Author or Date entry, this is very
-                       # likely an StGIT patch
-                       case "$l2,$l3" in
-                       ,"From: "* | ,"Author: "* | ,"Date: "*)
-                               patch_format=stgit
-                               ;;
-                       *)
-                               ;;
-                       esac
-                       ;;
-               esac
-               if test -z "$patch_format" &&
-                       test -n "$l1" &&
-                       test -n "$l2" &&
-                       test -n "$l3"
-               then
-                       # This begins with three non-empty lines.  Is this a
-                       # piece of e-mail a-la RFC2822?  Grab all the headers,
-                       # discarding the indented remainder of folded lines,
-                       # and see if it looks like that they all begin with the
-                       # header field names...
-                       tr -d '\015' <"$1" |
-                       sed -n -e '/^$/q' -e '/^[       ]/d' -e p |
-                       sane_egrep -v '^[!-9;-~]+:' >/dev/null ||
-                       patch_format=mbox
-               fi
-       } < "$1" || clean_abort
-}
-
-split_patches () {
-       case "$patch_format" in
-       mbox)
-               if test t = "$keepcr"
-               then
-                   keep_cr=--keep-cr
-               else
-                   keep_cr=
-               fi
-               git mailsplit -d"$prec" -o"$dotest" -b $keep_cr -- "$@" > "$dotest/last" ||
-               clean_abort
-               ;;
-       stgit-series)
-               if test $# -ne 1
-               then
-                       clean_abort "$(gettext "Only one StGIT patch series can be applied at once")"
-               fi
-               series_dir=$(dirname "$1")
-               series_file="$1"
-               shift
-               {
-                       set x
-                       while read filename
-                       do
-                               set "$@" "$series_dir/$filename"
-                       done
-                       # remove the safety x
-                       shift
-                       # remove the arg coming from the first-line comment
-                       shift
-               } < "$series_file" || clean_abort
-               # set the patch format appropriately
-               patch_format=stgit
-               # now handle the actual StGIT patches
-               split_patches "$@"
-               ;;
-       stgit)
-               this=0
-               test 0 -eq "$#" && set -- -
-               for stgit in "$@"
-               do
-                       this=$(expr "$this" + 1)
-                       msgnum=$(printf "%0${prec}d" $this)
-                       # Perl version of StGIT parse_patch. The first nonemptyline
-                       # not starting with Author, From or Date is the
-                       # subject, and the body starts with the next nonempty
-                       # line not starting with Author, From or Date
-                       @@PERL@@ -ne 'BEGIN { $subject = 0 }
-                               if ($subject > 1) { print ; }
-                               elsif (/^\s+$/) { next ; }
-                               elsif (/^Author:/) { s/Author/From/ ; print ;}
-                               elsif (/^(From|Date)/) { print ; }
-                               elsif ($subject) {
-                                       $subject = 2 ;
-                                       print "\n" ;
-                                       print ;
-                               } else {
-                                       print "Subject: ", $_ ;
-                                       $subject = 1;
-                               }
-                       ' -- "$stgit" >"$dotest/$msgnum" || clean_abort
-               done
-               echo "$this" > "$dotest/last"
-               this=
-               msgnum=
-               ;;
-       hg)
-               this=0
-               test 0 -eq "$#" && set -- -
-               for hg in "$@"
-               do
-                       this=$(( $this + 1 ))
-                       msgnum=$(printf "%0${prec}d" $this)
-                       # hg stores changeset metadata in #-commented lines preceding
-                       # the commit message and diff(s). The only metadata we care about
-                       # are the User and Date (Node ID and Parent are hashes which are
-                       # only relevant to the hg repository and thus not useful to us)
-                       # Since we cannot guarantee that the commit message is in
-                       # git-friendly format, we put no Subject: line and just consume
-                       # all of the message as the body
-                       LANG=C LC_ALL=C @@PERL@@ -M'POSIX qw(strftime)' -ne 'BEGIN { $subject = 0 }
-                               if ($subject) { print ; }
-                               elsif (/^\# User /) { s/\# User/From:/ ; print ; }
-                               elsif (/^\# Date /) {
-                                       my ($hashsign, $str, $time, $tz) = split ;
-                                       $tz_str = sprintf "%+05d", (0-$tz)/36;
-                                       print "Date: " .
-                                             strftime("%a, %d %b %Y %H:%M:%S ",
-                                                      gmtime($time-$tz))
-                                             . "$tz_str\n";
-                               } elsif (/^\# /) { next ; }
-                               else {
-                                       print "\n", $_ ;
-                                       $subject = 1;
-                               }
-                       ' -- "$hg" >"$dotest/$msgnum" || clean_abort
-               done
-               echo "$this" >"$dotest/last"
-               this=
-               msgnum=
-               ;;
-       *)
-               if test -n "$patch_format"
-               then
-                       clean_abort "$(eval_gettext "Patch format \$patch_format is not supported.")"
-               else
-                       clean_abort "$(gettext "Patch format detection failed.")"
-               fi
-               ;;
-       esac
-}
-
-prec=4
-dotest="$GIT_DIR/rebase-apply"
-sign= utf8=t keep= keepcr= skip= interactive= resolved= rebasing= abort=
-messageid= resolvemsg= resume= scissors= no_inbody_headers=
-git_apply_opt=
-committer_date_is_author_date=
-ignore_date=
-allow_rerere_autoupdate=
-gpg_sign_opt=
-threeway=
-
-if test "$(git config --bool --get am.messageid)" = true
-then
-    messageid=t
-fi
-
-if test "$(git config --bool --get am.keepcr)" = true
-then
-    keepcr=t
-fi
-
-while test $# != 0
-do
-       case "$1" in
-       -i|--interactive)
-               interactive=t ;;
-       -b|--binary)
-               gettextln >&2 "The -b/--binary option has been a no-op for long time, and
-it will be removed. Please do not use it anymore."
-               ;;
-       -3|--3way)
-               threeway=t ;;
-       -s|--signoff)
-               sign=t ;;
-       -u|--utf8)
-               utf8=t ;; # this is now default
-       --no-utf8)
-               utf8= ;;
-       -m|--message-id)
-               messageid=t ;;
-       --no-message-id)
-               messageid=f ;;
-       -k|--keep)
-               keep=t ;;
-       --keep-non-patch)
-               keep=b ;;
-       -c|--scissors)
-               scissors=t ;;
-       --no-scissors)
-               scissors=f ;;
-       -r|--resolved|--continue)
-               resolved=t ;;
-       --skip)
-               skip=t ;;
-       --abort)
-               abort=t ;;
-       --rebasing)
-               rebasing=t threeway=t ;;
-       --resolvemsg=*)
-               resolvemsg="${1#--resolvemsg=}" ;;
-       --whitespace=*|--directory=*|--exclude=*|--include=*)
-               git_apply_opt="$git_apply_opt $(sq "$1")" ;;
-       -C*|-p*)
-               git_apply_opt="$git_apply_opt $(sq "$1")" ;;
-       --patch-format=*)
-               patch_format="${1#--patch-format=}" ;;
-       --reject|--ignore-whitespace|--ignore-space-change)
-               git_apply_opt="$git_apply_opt $1" ;;
-       --committer-date-is-author-date)
-               committer_date_is_author_date=t ;;
-       --ignore-date)
-               ignore_date=t ;;
-       --rerere-autoupdate|--no-rerere-autoupdate)
-               allow_rerere_autoupdate="$1" ;;
-       -q|--quiet)
-               GIT_QUIET=t ;;
-       --keep-cr)
-               keepcr=t ;;
-       --no-keep-cr)
-               keepcr=f ;;
-       --gpg-sign)
-               gpg_sign_opt=-S ;;
-       --gpg-sign=*)
-               gpg_sign_opt="-S${1#--gpg-sign=}" ;;
-       --)
-               shift; break ;;
-       *)
-               usage ;;
-       esac
-       shift
-done
-
-# If the dotest directory exists, but we have finished applying all the
-# patches in them, clear it out.
-if test -d "$dotest" &&
-   test -f "$dotest/last" &&
-   test -f "$dotest/next" &&
-   last=$(cat "$dotest/last") &&
-   next=$(cat "$dotest/next") &&
-   test $# != 0 &&
-   test "$next" -gt "$last"
-then
-   rm -fr "$dotest"
-fi
-
-if test -d "$dotest" && test -f "$dotest/last" && test -f "$dotest/next"
-then
-       case "$#,$skip$resolved$abort" in
-       0,*t*)
-               # Explicit resume command and we do not have file, so
-               # we are happy.
-               : ;;
-       0,)
-               # No file input but without resume parameters; catch
-               # user error to feed us a patch from standard input
-               # when there is already $dotest.  This is somewhat
-               # unreliable -- stdin could be /dev/null for example
-               # and the caller did not intend to feed us a patch but
-               # wanted to continue unattended.
-               test -t 0
-               ;;
-       *)
-               false
-               ;;
-       esac ||
-       die "$(eval_gettext "previous rebase directory \$dotest still exists but mbox given.")"
-       resume=yes
-
-       case "$skip,$abort" in
-       t,t)
-               die "$(gettext "Please make up your mind. --skip or --abort?")"
-               ;;
-       t,)
-               git rerere clear
-               head_tree=$(git rev-parse --verify -q HEAD || echo $empty_tree) &&
-               git read-tree --reset -u $head_tree $head_tree &&
-               index_tree=$(git write-tree) &&
-               git read-tree -m -u $index_tree $head_tree
-               git read-tree -m $head_tree
-               ;;
-       ,t)
-               if test -f "$dotest/rebasing"
-               then
-                       exec git rebase --abort
-               fi
-               git rerere clear
-               if safe_to_abort
-               then
-                       head_tree=$(git rev-parse --verify -q HEAD || echo $empty_tree) &&
-                       git read-tree --reset -u $head_tree $head_tree &&
-                       index_tree=$(git write-tree) &&
-                       orig_head=$(git rev-parse --verify -q ORIG_HEAD || echo $empty_tree) &&
-                       git read-tree -m -u $index_tree $orig_head
-                       if git rev-parse --verify -q ORIG_HEAD >/dev/null 2>&1
-                       then
-                               git reset ORIG_HEAD
-                       else
-                               git read-tree $empty_tree
-                               curr_branch=$(git symbolic-ref HEAD 2>/dev/null) &&
-                               git update-ref -d $curr_branch
-                       fi
-               fi
-               rm -fr "$dotest"
-               exit ;;
-       esac
-       rm -f "$dotest/dirtyindex"
-else
-       # Possible stray $dotest directory in the independent-run
-       # case; in the --rebasing case, it is upto the caller
-       # (git-rebase--am) to take care of stray directories.
-       if test -d "$dotest" && test -z "$rebasing"
-       then
-               case "$skip,$resolved,$abort" in
-               ,,t)
-                       rm -fr "$dotest"
-                       exit 0
-                       ;;
-               *)
-                       die "$(eval_gettext "Stray \$dotest directory found.
-Use \"git am --abort\" to remove it.")"
-                       ;;
-               esac
-       fi
-
-       # Make sure we are not given --skip, --continue, or --abort
-       test "$skip$resolved$abort" = "" ||
-               die "$(gettext "Resolve operation not in progress, we are not resuming.")"
-
-       # Start afresh.
-       mkdir -p "$dotest" || exit
-
-       if test -n "$prefix" && test $# != 0
-       then
-               first=t
-               for arg
-               do
-                       test -n "$first" && {
-                               set x
-                               first=
-                       }
-                       if is_absolute_path "$arg"
-                       then
-                               set "$@" "$arg"
-                       else
-                               set "$@" "$prefix$arg"
-                       fi
-               done
-               shift
-       fi
-
-       check_patch_format "$@"
-
-       split_patches "$@"
-
-       # -i can and must be given when resuming; everything
-       # else is kept
-       echo " $git_apply_opt" >"$dotest/apply-opt"
-       echo "$threeway" >"$dotest/threeway"
-       echo "$sign" >"$dotest/sign"
-       echo "$utf8" >"$dotest/utf8"
-       echo "$keep" >"$dotest/keep"
-       echo "$messageid" >"$dotest/messageid"
-       echo "$scissors" >"$dotest/scissors"
-       echo "$no_inbody_headers" >"$dotest/no_inbody_headers"
-       echo "$GIT_QUIET" >"$dotest/quiet"
-       echo 1 >"$dotest/next"
-       if test -n "$rebasing"
-       then
-               : >"$dotest/rebasing"
-       else
-               : >"$dotest/applying"
-               if test -n "$HAS_HEAD"
-               then
-                       git update-ref ORIG_HEAD HEAD
-               else
-                       git update-ref -d ORIG_HEAD >/dev/null 2>&1
-               fi
-       fi
-fi
-
-git update-index -q --refresh
-
-case "$resolved" in
-'')
-       case "$HAS_HEAD" in
-       '')
-               files=$(git ls-files) ;;
-       ?*)
-               files=$(git diff-index --cached --name-only HEAD --) ;;
-       esac || exit
-       if test "$files"
-       then
-               test -n "$HAS_HEAD" && : >"$dotest/dirtyindex"
-               die "$(eval_gettext "Dirty index: cannot apply patches (dirty: \$files)")"
-       fi
-esac
-
-# Now, decide what command line options we will give to the git
-# commands we invoke, based on the result of parsing command line
-# options and previous invocation state stored in $dotest/ files.
-
-if test "$(cat "$dotest/utf8")" = t
-then
-       utf8=-u
-else
-       utf8=-n
-fi
-keep=$(cat "$dotest/keep")
-case "$keep" in
-t)
-       keep=-k ;;
-b)
-       keep=-b ;;
-*)
-       keep= ;;
-esac
-case "$(cat "$dotest/messageid")" in
-t)
-       messageid=-m ;;
-f)
-       messageid= ;;
-esac
-case "$(cat "$dotest/scissors")" in
-t)
-       scissors=--scissors ;;
-f)
-       scissors=--no-scissors ;;
-esac
-if test "$(cat "$dotest/no_inbody_headers")" = t
-then
-       no_inbody_headers=--no-inbody-headers
-else
-       no_inbody_headers=
-fi
-if test "$(cat "$dotest/quiet")" = t
-then
-       GIT_QUIET=t
-fi
-if test "$(cat "$dotest/threeway")" = t
-then
-       threeway=t
-fi
-git_apply_opt=$(cat "$dotest/apply-opt")
-if test "$(cat "$dotest/sign")" = t
-then
-       SIGNOFF=$(git var GIT_COMMITTER_IDENT | sed -e '
-                       s/>.*/>/
-                       s/^/Signed-off-by: /'
-               )
-else
-       SIGNOFF=
-fi
-
-last=$(cat "$dotest/last")
-this=$(cat "$dotest/next")
-if test "$skip" = t
-then
-       this=$(expr "$this" + 1)
-       resume=
-fi
-
-while test "$this" -le "$last"
-do
-       msgnum=$(printf "%0${prec}d" $this)
-       next=$(expr "$this" + 1)
-       test -f "$dotest/$msgnum" || {
-               resume=
-               go_next
-               continue
-       }
-
-       # If we are not resuming, parse and extract the patch information
-       # into separate files:
-       #  - info records the authorship and title
-       #  - msg is the rest of commit log message
-       #  - patch is the patch body.
-       #
-       # When we are resuming, these files are either already prepared
-       # by the user, or the user can tell us to do so by --continue flag.
-       case "$resume" in
-       '')
-               if test -f "$dotest/rebasing"
-               then
-                       commit=$(sed -e 's/^From \([0-9a-f]*\) .*/\1/' \
-                               -e q "$dotest/$msgnum") &&
-                       test "$(git cat-file -t "$commit")" = commit ||
-                               stop_here $this
-                       git cat-file commit "$commit" |
-                       sed -e '1,/^$/d' >"$dotest/msg-clean"
-                       echo "$commit" >"$dotest/original-commit"
-                       get_author_ident_from_commit "$commit" >"$dotest/author-script"
-                       git diff-tree --root --binary --full-index "$commit" >"$dotest/patch"
-               else
-                       git mailinfo $keep $no_inbody_headers $messageid $scissors $utf8 "$dotest/msg" "$dotest/patch" \
-                               <"$dotest/$msgnum" >"$dotest/info" ||
-                               stop_here $this
-
-                       # skip pine's internal folder data
-                       sane_grep '^Author: Mail System Internal Data$' \
-                               <"$dotest"/info >/dev/null &&
-                               go_next && continue
-
-                       test -s "$dotest/patch" || {
-                               eval_gettextln "Patch is empty.  Was it split wrong?
-If you would prefer to skip this patch, instead run \"\$cmdline --skip\".
-To restore the original branch and stop patching run \"\$cmdline --abort\"."
-                               stop_here $this
-                       }
-                       rm -f "$dotest/original-commit" "$dotest/author-script"
-                       {
-                               sed -n '/^Subject/ s/Subject: //p' "$dotest/info"
-                               echo
-                               cat "$dotest/msg"
-                       } |
-                       git stripspace > "$dotest/msg-clean"
-               fi
-               ;;
-       esac
-
-       if test -f "$dotest/author-script"
-       then
-               eval $(cat "$dotest/author-script")
-       else
-               GIT_AUTHOR_NAME="$(sed -n '/^Author/ s/Author: //p' "$dotest/info")"
-               GIT_AUTHOR_EMAIL="$(sed -n '/^Email/ s/Email: //p' "$dotest/info")"
-               GIT_AUTHOR_DATE="$(sed -n '/^Date/ s/Date: //p' "$dotest/info")"
-       fi
-
-       if test -z "$GIT_AUTHOR_EMAIL"
-       then
-               gettextln "Patch does not have a valid e-mail address."
-               stop_here $this
-       fi
-
-       export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
-
-       case "$resume" in
-       '')
-           if test '' != "$SIGNOFF"
-           then
-               LAST_SIGNED_OFF_BY=$(
-                   sed -ne '/^Signed-off-by: /p' \
-                   "$dotest/msg-clean" |
-                   sed -ne '$p'
-               )
-               ADD_SIGNOFF=$(
-                   test "$LAST_SIGNED_OFF_BY" = "$SIGNOFF" || {
-                   test '' = "$LAST_SIGNED_OFF_BY" && echo
-                   echo "$SIGNOFF"
-               })
-           else
-               ADD_SIGNOFF=
-           fi
-           {
-               if test -s "$dotest/msg-clean"
-               then
-                       cat "$dotest/msg-clean"
-               fi
-               if test '' != "$ADD_SIGNOFF"
-               then
-                       echo "$ADD_SIGNOFF"
-               fi
-           } >"$dotest/final-commit"
-           ;;
-       *)
-               case "$resolved$interactive" in
-               tt)
-                       # This is used only for interactive view option.
-                       git diff-index -p --cached HEAD -- >"$dotest/patch"
-                       ;;
-               esac
-       esac
-
-       resume=
-       if test "$interactive" = t
-       then
-           test -t 0 ||
-           die "$(gettext "cannot be interactive without stdin connected to a terminal.")"
-           action=again
-           while test "$action" = again
-           do
-               gettextln "Commit Body is:"
-               echo "--------------------------"
-               cat "$dotest/final-commit"
-               echo "--------------------------"
-               # TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]
-               # in your translation. The program will only accept English
-               # input at this point.
-               gettext "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all "
-               read reply
-               case "$reply" in
-               [yY]*) action=yes ;;
-               [aA]*) action=yes interactive= ;;
-               [nN]*) action=skip ;;
-               [eE]*) git_editor "$dotest/final-commit"
-                      action=again ;;
-               [vV]*) action=again
-                      git_pager "$dotest/patch" ;;
-               *)     action=again ;;
-               esac
-           done
-       else
-           action=yes
-       fi
-
-       if test $action = skip
-       then
-               go_next
-               continue
-       fi
-
-       hook="$(git rev-parse --git-path hooks/applypatch-msg)"
-       if test -x "$hook"
-       then
-               "$hook" "$dotest/final-commit" || stop_here $this
-       fi
-
-       if test -f "$dotest/final-commit"
-       then
-               FIRSTLINE=$(sed 1q "$dotest/final-commit")
-       else
-               FIRSTLINE=""
-       fi
-
-       say "$(eval_gettext "Applying: \$FIRSTLINE")"
-
-       case "$resolved" in
-       '')
-               # When we are allowed to fall back to 3-way later, don't give
-               # false errors during the initial attempt.
-               squelch=
-               if test "$threeway" = t
-               then
-                       squelch='>/dev/null 2>&1 '
-               fi
-               eval "git apply $squelch$git_apply_opt"' --index "$dotest/patch"'
-               apply_status=$?
-               ;;
-       t)
-               # Resolved means the user did all the hard work, and
-               # we do not have to do any patch application.  Just
-               # trust what the user has in the index file and the
-               # working tree.
-               resolved=
-               git diff-index --quiet --cached HEAD -- && {
-                       gettextln "No changes - did you forget to use 'git add'?
-If there is nothing left to stage, chances are that something else
-already introduced the same changes; you might want to skip this patch."
-                       stop_here_user_resolve $this
-               }
-               unmerged=$(git ls-files -u)
-               if test -n "$unmerged"
-               then
-                       gettextln "You still have unmerged paths in your index
-did you forget to use 'git add'?"
-                       stop_here_user_resolve $this
-               fi
-               apply_status=0
-               git rerere
-               ;;
-       esac
-
-       if test $apply_status != 0 && test "$threeway" = t
-       then
-               if (fall_back_3way)
-               then
-                   # Applying the patch to an earlier tree and merging the
-                   # result may have produced the same tree as ours.
-                   git diff-index --quiet --cached HEAD -- && {
-                       say "$(gettext "No changes -- Patch already applied.")"
-                       go_next
-                       continue
-                   }
-                   # clear apply_status -- we have successfully merged.
-                   apply_status=0
-               fi
-       fi
-       if test $apply_status != 0
-       then
-               eval_gettextln 'Patch failed at $msgnum $FIRSTLINE'
-               if test "$(git config --bool advice.amworkdir)" != false
-               then
-                       eval_gettextln 'The copy of the patch that failed is found in:
-   $dotest/patch'
-               fi
-               stop_here_user_resolve $this
-       fi
-
-       hook="$(git rev-parse --git-path hooks/pre-applypatch)"
-       if test -x "$hook"
-       then
-               "$hook" || stop_here $this
-       fi
-
-       tree=$(git write-tree) &&
-       commit=$(
-               if test -n "$ignore_date"
-               then
-                       GIT_AUTHOR_DATE=
-               fi
-               parent=$(git rev-parse --verify -q HEAD) ||
-               say >&2 "$(gettext "applying to an empty history")"
-
-               if test -n "$committer_date_is_author_date"
-               then
-                       GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
-                       export GIT_COMMITTER_DATE
-               fi &&
-               git commit-tree ${parent:+-p} $parent ${gpg_sign_opt:+"$gpg_sign_opt"} $tree  \
-                       <"$dotest/final-commit"
-       ) &&
-       git update-ref -m "$GIT_REFLOG_ACTION: $FIRSTLINE" HEAD $commit $parent ||
-       stop_here $this
-
-       if test -f "$dotest/original-commit"; then
-               echo "$(cat "$dotest/original-commit") $commit" >> "$dotest/rewritten"
-       fi
-
-       hook="$(git rev-parse --git-path hooks/post-applypatch)"
-       test -x "$hook" && "$hook"
-
-       go_next
-done
-
-if test -s "$dotest"/rewritten; then
-    git notes copy --for-rewrite=rebase < "$dotest"/rewritten
-    hook="$(git rev-parse --git-path hooks/post-rewrite)"
-    if test -x "$hook"; then
-       "$hook" rebase < "$dotest"/rewritten
-    fi
-fi
-
-# If am was called with --rebasing (from git-rebase--am), it's up to
-# the caller to take care of housekeeping.
-if ! test -f "$dotest/rebasing"
-then
-       rm -fr "$dotest"
-       git gc --auto
-fi
diff --git a/contrib/examples/git-checkout.sh b/contrib/examples/git-checkout.sh
deleted file mode 100755 (executable)
index 683cae7..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
-#!/bin/sh
-
-OPTIONS_KEEPDASHDASH=t
-OPTIONS_SPEC="\
-git-checkout [options] [<branch>] [<paths>...]
---
-b=          create a new branch started at <branch>
-l           create the new branch's reflog
-track       arrange that the new branch tracks the remote branch
-f           proceed even if the index or working tree is not HEAD
-m           merge local modifications into the new branch
-q,quiet     be quiet
-"
-SUBDIRECTORY_OK=Sometimes
-. git-sh-setup
-require_work_tree
-
-old_name=HEAD
-old=$(git rev-parse --verify $old_name 2>/dev/null)
-oldbranch=$(git symbolic-ref $old_name 2>/dev/null)
-new=
-new_name=
-force=
-branch=
-track=
-newbranch=
-newbranch_log=
-merge=
-quiet=
-v=-v
-LF='
-'
-
-while test $# != 0; do
-       case "$1" in
-       -b)
-               shift
-               newbranch="$1"
-               [ -z "$newbranch" ] &&
-                       die "git checkout: -b needs a branch name"
-               git show-ref --verify --quiet -- "refs/heads/$newbranch" &&
-                       die "git checkout: branch $newbranch already exists"
-               git check-ref-format "heads/$newbranch" ||
-                       die "git checkout: we do not like '$newbranch' as a branch name."
-               ;;
-       -l)
-               newbranch_log=-l
-               ;;
-       --track|--no-track)
-               track="$1"
-               ;;
-       -f)
-               force=1
-               ;;
-       -m)
-               merge=1
-               ;;
-       -q|--quiet)
-               quiet=1
-               v=
-               ;;
-       --)
-               shift
-               break
-               ;;
-       *)
-               usage
-               ;;
-       esac
-       shift
-done
-
-arg="$1"
-rev=$(git rev-parse --verify "$arg" 2>/dev/null)
-if rev=$(git rev-parse --verify "$rev^0" 2>/dev/null)
-then
-       [ -z "$rev" ] && die "unknown flag $arg"
-       new_name="$arg"
-       if git show-ref --verify --quiet -- "refs/heads/$arg"
-       then
-               rev=$(git rev-parse --verify "refs/heads/$arg^0")
-               branch="$arg"
-       fi
-       new="$rev"
-       shift
-elif rev=$(git rev-parse --verify "$rev^{tree}" 2>/dev/null)
-then
-       # checking out selected paths from a tree-ish.
-       new="$rev"
-       new_name="$rev^{tree}"
-       shift
-fi
-[ "$1" = "--" ] && shift
-
-case "$newbranch,$track" in
-,--*)
-       die "git checkout: --track and --no-track require -b"
-esac
-
-case "$force$merge" in
-11)
-       die "git checkout: -f and -m are incompatible"
-esac
-
-# The behaviour of the command with and without explicit path
-# parameters is quite different.
-#
-# Without paths, we are checking out everything in the work tree,
-# possibly switching branches.  This is the traditional behaviour.
-#
-# With paths, we are _never_ switching branch, but checking out
-# the named paths from either index (when no rev is given),
-# or the named tree-ish (when rev is given).
-
-if test "$#" -ge 1
-then
-       hint=
-       if test "$#" -eq 1
-       then
-               hint="
-Did you intend to checkout '$@' which can not be resolved as commit?"
-       fi
-       if test '' != "$newbranch$force$merge"
-       then
-               die "git checkout: updating paths is incompatible with switching branches/forcing$hint"
-       fi
-       if test '' != "$new"
-       then
-               # from a specific tree-ish; note that this is for
-               # rescuing paths and is never meant to remove what
-               # is not in the named tree-ish.
-               git ls-tree --full-name -r "$new" "$@" |
-               git update-index --index-info || exit $?
-       fi
-
-       # Make sure the request is about existing paths.
-       git ls-files --full-name --error-unmatch -- "$@" >/dev/null || exit
-       git ls-files --full-name -- "$@" |
-               (cd_to_toplevel && git checkout-index -f -u --stdin)
-
-       # Run a post-checkout hook -- the HEAD does not change so the
-       # current HEAD is passed in for both args
-       if test -x "$GIT_DIR"/hooks/post-checkout; then
-           "$GIT_DIR"/hooks/post-checkout $old $old 0
-       fi
-
-       exit $?
-else
-       # Make sure we did not fall back on $arg^{tree} codepath
-       # since we are not checking out from an arbitrary tree-ish,
-       # but switching branches.
-       if test '' != "$new"
-       then
-               git rev-parse --verify "$new^{commit}" >/dev/null 2>&1 ||
-               die "Cannot switch branch to a non-commit."
-       fi
-fi
-
-# We are switching branches and checking out trees, so
-# we *NEED* to be at the toplevel.
-cd_to_toplevel
-
-[ -z "$new" ] && new=$old && new_name="$old_name"
-
-# If we don't have an existing branch that we're switching to,
-# and we don't have a new branch name for the target we
-# are switching to, then we are detaching our HEAD from any
-# branch.  However, if "git checkout HEAD" detaches the HEAD
-# from the current branch, even though that may be logically
-# correct, it feels somewhat funny.  More importantly, we do not
-# want "git checkout" or "git checkout -f" to detach HEAD.
-
-detached=
-detach_warn=
-
-describe_detached_head () {
-       test -n "$quiet" || {
-               printf >&2 "$1 "
-               GIT_PAGER= git log >&2 -1 --pretty=oneline --abbrev-commit "$2" --
-       }
-}
-
-if test -z "$branch$newbranch" && test "$new_name" != "$old_name"
-then
-       detached="$new"
-       if test -n "$oldbranch" && test -z "$quiet"
-       then
-               detach_warn="Note: moving to \"$new_name\" which isn't a local branch
-If you want to create a new branch from this checkout, you may do so
-(now or later) by using -b with the checkout command again. Example:
-  git checkout -b <new_branch_name>"
-       fi
-elif test -z "$oldbranch" && test "$new" != "$old"
-then
-       describe_detached_head 'Previous HEAD position was' "$old"
-fi
-
-if [ "X$old" = X ]
-then
-       if test -z "$quiet"
-       then
-               echo >&2 "warning: You appear to be on a branch yet to be born."
-               echo >&2 "warning: Forcing checkout of $new_name."
-       fi
-       force=1
-fi
-
-if [ "$force" ]
-then
-    git read-tree $v --reset -u $new
-else
-    git update-index --refresh >/dev/null
-    git read-tree $v -m -u --exclude-per-directory=.gitignore $old $new || (
-       case "$merge,$v" in
-       ,*)
-               exit 1 ;;
-       1,)
-               ;; # quiet
-       *)
-               echo >&2 "Falling back to 3-way merge..." ;;
-       esac
-
-       # Match the index to the working tree, and do a three-way.
-       git diff-files --name-only | git update-index --remove --stdin &&
-       work=$(git write-tree) &&
-       git read-tree $v --reset -u $new || exit
-
-       eval GITHEAD_$new='${new_name:-${branch:-$new}}' &&
-       eval GITHEAD_$work=local &&
-       export GITHEAD_$new GITHEAD_$work &&
-       git merge-recursive $old -- $new $work
-
-       # Do not register the cleanly merged paths in the index yet.
-       # this is not a real merge before committing, but just carrying
-       # the working tree changes along.
-       unmerged=$(git ls-files -u)
-       git read-tree $v --reset $new
-       case "$unmerged" in
-       '')     ;;
-       *)
-               (
-                       z40=0000000000000000000000000000000000000000
-                       echo "$unmerged" |
-                       sed -e 's/^[0-7]* [0-9a-f]* /'"0 $z40 /"
-                       echo "$unmerged"
-               ) | git update-index --index-info
-               ;;
-       esac
-       exit 0
-    )
-    saved_err=$?
-    if test "$saved_err" = 0 && test -z "$quiet"
-    then
-       git diff-index --name-status "$new"
-    fi
-    (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
-# be based on them, since we re-set the index)
-#
-if [ "$?" -eq 0 ]; then
-       if [ "$newbranch" ]; then
-               git branch $track $newbranch_log "$newbranch" "$new_name" || exit
-               branch="$newbranch"
-       fi
-       if test -n "$branch"
-       then
-               old_branch_name=$(expr "z$oldbranch" : 'zrefs/heads/\(.*\)')
-               GIT_DIR="$GIT_DIR" git symbolic-ref -m "checkout: moving from ${old_branch_name:-$old} to $branch" HEAD "refs/heads/$branch"
-               if test -n "$quiet"
-               then
-                       true    # nothing
-               elif test "refs/heads/$branch" = "$oldbranch"
-               then
-                       echo >&2 "Already on branch \"$branch\""
-               else
-                       echo >&2 "Switched to${newbranch:+ a new} branch \"$branch\""
-               fi
-       elif test -n "$detached"
-       then
-               old_branch_name=$(expr "z$oldbranch" : 'zrefs/heads/\(.*\)')
-               git update-ref --no-deref -m "checkout: moving from ${old_branch_name:-$old} to $arg" HEAD "$detached" ||
-                       die "Cannot detach HEAD"
-               if test -n "$detach_warn"
-               then
-                       echo >&2 "$detach_warn"
-               fi
-               describe_detached_head 'HEAD is now at' HEAD
-       fi
-       rm -f "$GIT_DIR/MERGE_HEAD"
-else
-       exit 1
-fi
-
-# Run a post-checkout hook
-if test -x "$GIT_DIR"/hooks/post-checkout; then
-       "$GIT_DIR"/hooks/post-checkout $old $new 1
-fi
diff --git a/contrib/examples/git-clean.sh b/contrib/examples/git-clean.sh
deleted file mode 100755 (executable)
index 01c95e9..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005-2006 Pavel Roskin
-#
-
-OPTIONS_KEEPDASHDASH=
-OPTIONS_SPEC="\
-git-clean [options] <paths>...
-
-Clean untracked files from the working directory
-
-When optional <paths>... arguments are given, the paths
-affected are further limited to those that match them.
---
-d remove directories as well
-f override clean.requireForce and clean anyway
-n don't remove anything, just show what would be done
-q be quiet, only report errors
-x remove ignored files as well
-X remove only ignored files"
-
-SUBDIRECTORY_OK=Yes
-. git-sh-setup
-require_work_tree
-
-ignored=
-ignoredonly=
-cleandir=
-rmf="rm -f --"
-rmrf="rm -rf --"
-rm_refuse="echo Not removing"
-echo1="echo"
-
-disabled=$(git config --bool clean.requireForce)
-
-while test $# != 0
-do
-       case "$1" in
-       -d)
-               cleandir=1
-               ;;
-       -f)
-               disabled=false
-               ;;
-       -n)
-               disabled=false
-               rmf="echo Would remove"
-               rmrf="echo Would remove"
-               rm_refuse="echo Would not remove"
-               echo1=":"
-               ;;
-       -q)
-               echo1=":"
-               ;;
-       -x)
-               ignored=1
-               ;;
-       -X)
-               ignoredonly=1
-               ;;
-       --)
-               shift
-               break
-               ;;
-       *)
-               usage # should not happen
-               ;;
-       esac
-       shift
-done
-
-# requireForce used to default to false but now it defaults to true.
-# IOW, lack of explicit "clean.requireForce = false" is taken as
-# "clean.requireForce = true".
-case "$disabled" in
-"")
-       die "clean.requireForce not set and -n or -f not given; refusing to clean"
-       ;;
-"true")
-       die "clean.requireForce set and -n or -f not given; refusing to clean"
-       ;;
-esac
-
-if [ "$ignored,$ignoredonly" = "1,1" ]; then
-       die "-x and -X cannot be set together"
-fi
-
-if [ -z "$ignored" ]; then
-       excl="--exclude-per-directory=.gitignore"
-       excl_info= excludes_file=
-       if [ -f "$GIT_DIR/info/exclude" ]; then
-               excl_info="--exclude-from=$GIT_DIR/info/exclude"
-       fi
-       if cfg_excl=$(git config core.excludesfile) && test -f "$cfg_excl"
-       then
-               excludes_file="--exclude-from=$cfg_excl"
-       fi
-       if [ "$ignoredonly" ]; then
-               excl="$excl --ignored"
-       fi
-fi
-
-git ls-files --others --directory \
-       $excl ${excl_info:+"$excl_info"} ${excludes_file:+"$excludes_file"} \
-       -- "$@" |
-while read -r file; do
-       if [ -d "$file" -a ! -L "$file" ]; then
-               if [ -z "$cleandir" ]; then
-                       $rm_refuse "$file"
-                       continue
-               fi
-               $echo1 "Removing $file"
-               $rmrf "$file"
-       else
-               $echo1 "Removing $file"
-               $rmf "$file"
-       fi
-done
diff --git a/contrib/examples/git-clone.sh b/contrib/examples/git-clone.sh
deleted file mode 100755 (executable)
index 08cf246..0000000
+++ /dev/null
@@ -1,525 +0,0 @@
-#!/bin/sh
-#
-# 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.
-unset CDPATH
-
-OPTIONS_SPEC="\
-git-clone [options] [--] <repo> [<dir>]
---
-n,no-checkout        don't create a checkout
-bare                 create a bare repository
-naked                create a bare repository
-l,local              to clone from a local repository
-no-hardlinks         don't use local hardlinks, always copy
-s,shared             setup as a shared repository
-template=            path to the template directory
-q,quiet              be quiet
-reference=           reference repository
-o,origin=            use <name> instead of 'origin' to track upstream
-u,upload-pack=       path to git-upload-pack on the remote
-depth=               create a shallow clone of that depth
-
-use-separate-remote  compatibility, do not use
-no-separate-remote   compatibility, do not use"
-
-die() {
-       echo >&2 "$@"
-       exit 1
-}
-
-usage() {
-       exec "$0" -h
-}
-
-eval "$(echo "$OPTIONS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?)"
-
-get_repo_base() {
-       (
-               cd "$(/bin/pwd)" &&
-               cd "$1" || cd "$1.git" &&
-               {
-                       cd .git
-                       pwd
-               }
-       ) 2>/dev/null
-}
-
-if [ -n "$GIT_SSL_NO_VERIFY" -o \
-       "$(git config --bool http.sslVerify)" = false ]; then
-    curl_extra_args="-k"
-fi
-
-http_fetch () {
-       # $1 = Remote, $2 = Local
-       curl -nsfL $curl_extra_args "$1" >"$2"
-       curl_exit_status=$?
-       case $curl_exit_status in
-       126|127) exit ;;
-       *)       return $curl_exit_status ;;
-       esac
-}
-
-clone_dumb_http () {
-       # $1 - remote, $2 - local
-       cd "$2" &&
-       clone_tmp="$GIT_DIR/clone-tmp" &&
-       mkdir -p "$clone_tmp" || exit 1
-       if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \
-               "$(git config --bool http.noEPSV)" = true ]; then
-               curl_extra_args="${curl_extra_args} --disable-epsv"
-       fi
-       http_fetch "$1/info/refs" "$clone_tmp/refs" ||
-               die "Cannot get remote repository information.
-Perhaps git-update-server-info needs to be run there?"
-       test "z$quiet" = z && v=-v || v=
-       while read sha1 refname
-       do
-               name=$(expr "z$refname" : 'zrefs/\(.*\)') &&
-               case "$name" in
-               *^*)    continue;;
-               esac
-               case "$bare,$name" in
-               yes,* | ,heads/* | ,tags/*) ;;
-               *)      continue ;;
-               esac
-               if test -n "$use_separate_remote" &&
-                  branch_name=$(expr "z$name" : 'zheads/\(.*\)')
-               then
-                       tname="remotes/$origin/$branch_name"
-               else
-                       tname=$name
-               fi
-               git-http-fetch $v -a -w "$tname" "$sha1" "$1" || exit 1
-       done <"$clone_tmp/refs"
-       rm -fr "$clone_tmp"
-       http_fetch "$1/HEAD" "$GIT_DIR/REMOTE_HEAD" ||
-       rm -f "$GIT_DIR/REMOTE_HEAD"
-       if test -f "$GIT_DIR/REMOTE_HEAD"; then
-               head_sha1=$(cat "$GIT_DIR/REMOTE_HEAD")
-               case "$head_sha1" in
-               'ref: refs/'*)
-                       ;;
-               *)
-                       git-http-fetch $v -a "$head_sha1" "$1" ||
-                       rm -f "$GIT_DIR/REMOTE_HEAD"
-                       ;;
-               esac
-       fi
-}
-
-quiet=
-local=no
-use_local_hardlink=yes
-local_shared=no
-unset template
-no_checkout=
-upload_pack=
-bare=
-reference=
-origin=
-origin_override=
-use_separate_remote=t
-depth=
-no_progress=
-local_explicitly_asked_for=
-test -t 1 || no_progress=--no-progress
-
-while test $# != 0
-do
-       case "$1" in
-       -n|--no-checkout)
-               no_checkout=yes ;;
-       --naked|--bare)
-               bare=yes ;;
-       -l|--local)
-               local_explicitly_asked_for=yes
-               use_local_hardlink=yes
-               ;;
-       --no-hardlinks)
-               use_local_hardlink=no ;;
-       -s|--shared)
-               local_shared=yes ;;
-       --template)
-               shift; template="--template=$1" ;;
-       -q|--quiet)
-               quiet=-q ;;
-       --use-separate-remote|--no-separate-remote)
-               die "clones are always made with separate-remote layout" ;;
-       --reference)
-               shift; reference="$1" ;;
-       -o|--origin)
-               shift;
-               case "$1" in
-               '')
-                   usage ;;
-               */*)
-                   die "'$1' is not suitable for an origin name"
-               esac
-               git check-ref-format "heads/$1" ||
-                   die "'$1' is not suitable for a branch name"
-               test -z "$origin_override" ||
-                   die "Do not give more than one --origin options."
-               origin_override=yes
-               origin="$1"
-               ;;
-       -u|--upload-pack)
-               shift
-               upload_pack="--upload-pack=$1" ;;
-       --depth)
-               shift
-               depth="--depth=$1" ;;
-       --)
-               shift
-               break ;;
-       *)
-               usage ;;
-       esac
-       shift
-done
-
-repo="$1"
-test -n "$repo" ||
-    die 'you must specify a repository to clone.'
-
-# --bare implies --no-checkout and --no-separate-remote
-if test yes = "$bare"
-then
-       if test yes = "$origin_override"
-       then
-               die '--bare and --origin $origin options are incompatible.'
-       fi
-       no_checkout=yes
-       use_separate_remote=
-fi
-
-if test -z "$origin"
-then
-       origin=origin
-fi
-
-# Turn the source into an absolute path if
-# it is local
-if base=$(get_repo_base "$repo"); then
-       repo="$base"
-       if test -z "$depth"
-       then
-               local=yes
-       fi
-elif test -f "$repo"
-then
-       case "$repo" in /*) ;; *) repo="$PWD/$repo" ;; esac
-fi
-
-# Decide the directory name of the new repository
-if test -n "$2"
-then
-       dir="$2"
-       test $# = 2 || die "excess parameter to git-clone"
-else
-       # Derive one from the repository name
-       # Try using "humanish" part of source repo if user didn't specify one
-       if test -f "$repo"
-       then
-               # Cloning from a bundle
-               dir=$(echo "$repo" | sed -e 's|/*\.bundle$||' -e 's|.*/||g')
-       else
-               dir=$(echo "$repo" |
-                       sed -e 's|/$||' -e 's|:*/*\.git$||' -e 's|.*[/:]||g')
-       fi
-fi
-
-[ -e "$dir" ] && die "destination directory '$dir' already exists."
-[ yes = "$bare" ] && unset GIT_WORK_TREE
-[ -n "$GIT_WORK_TREE" ] && [ -e "$GIT_WORK_TREE" ] &&
-die "working tree '$GIT_WORK_TREE' already exists."
-D=
-W=
-cleanup() {
-       test -z "$D" && rm -rf "$dir"
-       test -z "$W" && test -n "$GIT_WORK_TREE" && rm -rf "$GIT_WORK_TREE"
-       cd ..
-       test -n "$D" && rm -rf "$D"
-       test -n "$W" && rm -rf "$W"
-       exit $err
-}
-trap 'err=$?; cleanup' 0
-mkdir -p "$dir" && D=$(cd "$dir" && pwd) || usage
-test -n "$GIT_WORK_TREE" && mkdir -p "$GIT_WORK_TREE" &&
-W=$(cd "$GIT_WORK_TREE" && pwd) && GIT_WORK_TREE="$W" && export GIT_WORK_TREE
-if test yes = "$bare" || test -n "$GIT_WORK_TREE"; then
-       GIT_DIR="$D"
-else
-       GIT_DIR="$D/.git"
-fi &&
-export GIT_DIR &&
-GIT_CONFIG="$GIT_DIR/config" git-init $quiet ${template+"$template"} || usage
-
-if test -n "$bare"
-then
-       GIT_CONFIG="$GIT_DIR/config" git config core.bare true
-fi
-
-if test -n "$reference"
-then
-       ref_git=
-       if test -d "$reference"
-       then
-               if test -d "$reference/.git/objects"
-               then
-                       ref_git="$reference/.git"
-               elif test -d "$reference/objects"
-               then
-                       ref_git="$reference"
-               fi
-       fi
-       if test -n "$ref_git"
-       then
-               ref_git=$(cd "$ref_git" && pwd)
-               echo "$ref_git/objects" >"$GIT_DIR/objects/info/alternates"
-               (
-                       GIT_DIR="$ref_git" git for-each-ref \
-                               --format='%(objectname) %(*objectname)'
-               ) |
-               while read a b
-               do
-                       test -z "$a" ||
-                       git update-ref "refs/reference-tmp/$a" "$a"
-                       test -z "$b" ||
-                       git update-ref "refs/reference-tmp/$b" "$b"
-               done
-       else
-               die "reference repository '$reference' is not a local directory."
-       fi
-fi
-
-rm -f "$GIT_DIR/CLONE_HEAD"
-
-# We do local magic only when the user tells us to.
-case "$local" in
-yes)
-       ( cd "$repo/objects" ) ||
-               die "cannot chdir to local '$repo/objects'."
-
-       if test "$local_shared" = yes
-       then
-               mkdir -p "$GIT_DIR/objects/info"
-               echo "$repo/objects" >>"$GIT_DIR/objects/info/alternates"
-       else
-               cpio_quiet_flag=""
-               cpio --help 2>&1 | grep -- --quiet >/dev/null && \
-                       cpio_quiet_flag=--quiet
-               l= &&
-               if test "$use_local_hardlink" = yes
-               then
-                       # See if we can hardlink and drop "l" if not.
-                       sample_file=$(cd "$repo" && \
-                                     find objects -type f -print | sed -e 1q)
-                       # objects directory should not be empty because
-                       # we are cloning!
-                       test -f "$repo/$sample_file" ||
-                               die "fatal: cannot clone empty repository"
-                       if ln "$repo/$sample_file" "$GIT_DIR/objects/sample" 2>/dev/null
-                       then
-                               rm -f "$GIT_DIR/objects/sample"
-                               l=l
-                       elif test -n "$local_explicitly_asked_for"
-                       then
-                               echo >&2 "Warning: -l asked but cannot hardlink to $repo"
-                       fi
-               fi &&
-               cd "$repo" &&
-               # Create dirs using umask and permissions and destination
-               find objects -type d -print | (cd "$GIT_DIR" && xargs mkdir -p) &&
-               # Copy existing 0444 permissions on content
-               find objects ! -type d -print | cpio $cpio_quiet_flag -pumd$l "$GIT_DIR/" || \
-                       exit 1
-       fi
-       git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD" || exit 1
-       ;;
-*)
-       case "$repo" in
-       rsync://*)
-               case "$depth" in
-               "") ;;
-               *) die "shallow over rsync not supported" ;;
-               esac
-               rsync $quiet -av --ignore-existing  \
-                       --exclude info "$repo/objects/" "$GIT_DIR/objects/" ||
-               exit
-               # Look at objects/info/alternates for rsync -- http will
-               # support it natively and git native ones will do it on the
-               # remote end.  Not having that file is not a crime.
-               rsync -q "$repo/objects/info/alternates" \
-                       "$GIT_DIR/TMP_ALT" 2>/dev/null ||
-                       rm -f "$GIT_DIR/TMP_ALT"
-               if test -f "$GIT_DIR/TMP_ALT"
-               then
-                   ( cd "$D" &&
-                     . git-parse-remote &&
-                     resolve_alternates "$repo" <"$GIT_DIR/TMP_ALT" ) |
-                   while read alt
-                   do
-                       case "$alt" in 'bad alternate: '*) die "$alt";; esac
-                       case "$quiet" in
-                       '')     echo >&2 "Getting alternate: $alt" ;;
-                       esac
-                       rsync $quiet -av --ignore-existing  \
-                           --exclude info "$alt" "$GIT_DIR/objects" || exit
-                   done
-                   rm -f "$GIT_DIR/TMP_ALT"
-               fi
-               git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD" || exit 1
-               ;;
-       https://*|http://*|ftp://*)
-               case "$depth" in
-               "") ;;
-               *) die "shallow over http or ftp not supported" ;;
-               esac
-               if test -z "@@NO_CURL@@"
-               then
-                       clone_dumb_http "$repo" "$D"
-               else
-                       die "http transport not supported, rebuild Git with curl support"
-               fi
-               ;;
-       *)
-               if [ -f "$repo" ] ; then
-                       git bundle unbundle "$repo" > "$GIT_DIR/CLONE_HEAD" ||
-                       die "unbundle from '$repo' failed."
-               else
-                       case "$upload_pack" in
-                       '') git-fetch-pack --all -k $quiet $depth $no_progress "$repo";;
-                       *) git-fetch-pack --all -k \
-                               $quiet "$upload_pack" $depth $no_progress "$repo" ;;
-                       esac >"$GIT_DIR/CLONE_HEAD" ||
-                       die "fetch-pack from '$repo' failed."
-               fi
-               ;;
-       esac
-       ;;
-esac
-test -d "$GIT_DIR/refs/reference-tmp" && rm -fr "$GIT_DIR/refs/reference-tmp"
-
-if test -f "$GIT_DIR/CLONE_HEAD"
-then
-       # Read git-fetch-pack -k output and store the remote branches.
-       if [ -n "$use_separate_remote" ]
-       then
-               branch_top="remotes/$origin"
-       else
-               branch_top="heads"
-       fi
-       tag_top="tags"
-       while read sha1 name
-       do
-               case "$name" in
-               *'^{}')
-                       continue ;;
-               HEAD)
-                       destname="REMOTE_HEAD" ;;
-               refs/heads/*)
-                       destname="refs/$branch_top/${name#refs/heads/}" ;;
-               refs/tags/*)
-                       destname="refs/$tag_top/${name#refs/tags/}" ;;
-               *)
-                       continue ;;
-               esac
-               git update-ref -m "clone: from $repo" "$destname" "$sha1" ""
-       done < "$GIT_DIR/CLONE_HEAD"
-fi
-
-if test -n "$W"; then
-       cd "$W" || exit
-else
-       cd "$D" || exit
-fi
-
-if test -z "$bare"
-then
-       # a non-bare repository is always in separate-remote layout
-       remote_top="refs/remotes/$origin"
-       head_sha1=
-       test ! -r "$GIT_DIR/REMOTE_HEAD" || head_sha1=$(cat "$GIT_DIR/REMOTE_HEAD")
-       case "$head_sha1" in
-       'ref: refs/'*)
-               # Uh-oh, the remote told us (http transport done against
-               # new style repository with a symref HEAD).
-               # Ideally we should skip the guesswork but for now
-               # opt for minimum change.
-               head_sha1=$(expr "z$head_sha1" : 'zref: refs/heads/\(.*\)')
-               head_sha1=$(cat "$GIT_DIR/$remote_top/$head_sha1")
-               ;;
-       esac
-
-       # The name under $remote_top the remote HEAD seems to point at.
-       head_points_at=$(
-               (
-                       test -f "$GIT_DIR/$remote_top/master" && echo "master"
-                       cd "$GIT_DIR/$remote_top" &&
-                       find . -type f -print | sed -e 's/^\.\///'
-               ) | (
-               done=f
-               while read name
-               do
-                       test t = $done && continue
-                       branch_tip=$(cat "$GIT_DIR/$remote_top/$name")
-                       if test "$head_sha1" = "$branch_tip"
-                       then
-                               echo "$name"
-                               done=t
-                       fi
-               done
-               )
-       )
-
-       # Upstream URL
-       git config remote."$origin".url "$repo" &&
-
-       # Set up the mappings to track the remote branches.
-       git config remote."$origin".fetch \
-               "+refs/heads/*:$remote_top/*" '^$' &&
-
-       # Write out remote.$origin config, and update our "$head_points_at".
-       case "$head_points_at" in
-       ?*)
-               # Local default branch
-               git symbolic-ref HEAD "refs/heads/$head_points_at" &&
-
-               # Tracking branch for the primary branch at the remote.
-               git update-ref HEAD "$head_sha1" &&
-
-               rm -f "refs/remotes/$origin/HEAD"
-               git symbolic-ref "refs/remotes/$origin/HEAD" \
-                       "refs/remotes/$origin/$head_points_at" &&
-
-               git config branch."$head_points_at".remote "$origin" &&
-               git config branch."$head_points_at".merge "refs/heads/$head_points_at"
-               ;;
-       '')
-               if test -z "$head_sha1"
-               then
-                       # Source had nonexistent ref in HEAD
-                       echo >&2 "Warning: Remote HEAD refers to nonexistent ref, unable to checkout."
-                       no_checkout=t
-               else
-                       # Source had detached HEAD pointing nowhere
-                       git update-ref --no-deref HEAD "$head_sha1" &&
-                       rm -f "refs/remotes/$origin/HEAD"
-               fi
-               ;;
-       esac
-
-       case "$no_checkout" in
-       '')
-               test "z$quiet" = z && test "z$no_progress" = z && v=-v || v=
-               git read-tree -m -u $v HEAD HEAD
-       esac
-fi
-rm -f "$GIT_DIR/CLONE_HEAD" "$GIT_DIR/REMOTE_HEAD"
-
-trap - 0
diff --git a/contrib/examples/git-commit.sh b/contrib/examples/git-commit.sh
deleted file mode 100755 (executable)
index 86c9cfa..0000000
+++ /dev/null
@@ -1,639 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005 Linus Torvalds
-# Copyright (c) 2006 Junio C Hamano
-
-USAGE='[-a | --interactive] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit> | --amend] [-u] [-e] [--author <author>] [--template <file>] [[-i | -o] <path>...]'
-SUBDIRECTORY_OK=Yes
-OPTIONS_SPEC=
-. git-sh-setup
-require_work_tree
-
-git rev-parse --verify HEAD >/dev/null 2>&1 || initial_commit=t
-
-case "$0" in
-*status)
-       status_only=t
-       ;;
-*commit)
-       status_only=
-       ;;
-esac
-
-refuse_partial () {
-       echo >&2 "$1"
-       echo >&2 "You might have meant to say 'git commit -i paths...', perhaps?"
-       exit 1
-}
-
-TMP_INDEX=
-THIS_INDEX="${GIT_INDEX_FILE:-$GIT_DIR/index}"
-NEXT_INDEX="$GIT_DIR/next-index$$"
-rm -f "$NEXT_INDEX"
-save_index () {
-       cp -p "$THIS_INDEX" "$NEXT_INDEX"
-}
-
-run_status () {
-       # If TMP_INDEX is defined, that means we are doing
-       # "--only" partial commit, and that index file is used
-       # to build the tree for the commit.  Otherwise, if
-       # NEXT_INDEX exists, that is the index file used to
-       # make the commit.  Otherwise we are using as-is commit
-       # so the regular index file is what we use to compare.
-       if test '' != "$TMP_INDEX"
-       then
-               GIT_INDEX_FILE="$TMP_INDEX"
-               export GIT_INDEX_FILE
-       elif test -f "$NEXT_INDEX"
-       then
-               GIT_INDEX_FILE="$NEXT_INDEX"
-               export GIT_INDEX_FILE
-       fi
-
-       if test "$status_only" = "t" || test "$use_status_color" = "t"; then
-               color=
-       else
-               color=--nocolor
-       fi
-       git runstatus ${color} \
-               ${verbose:+--verbose} \
-               ${amend:+--amend} \
-               ${untracked_files:+--untracked}
-}
-
-trap '
-       test -z "$TMP_INDEX" || {
-               test -f "$TMP_INDEX" && rm -f "$TMP_INDEX"
-       }
-       rm -f "$NEXT_INDEX"
-' 0
-
-################################################################
-# Command line argument parsing and sanity checking
-
-all=
-also=
-allow_empty=f
-interactive=
-only=
-logfile=
-use_commit=
-amend=
-edit_flag=
-no_edit=
-log_given=
-log_message=
-verify=t
-quiet=
-verbose=
-signoff=
-force_author=
-only_include_assumed=
-untracked_files=
-templatefile="$(git config commit.template)"
-while test $# != 0
-do
-       case "$1" in
-       -F|--F|-f|--f|--fi|--fil|--file)
-               case "$#" in 1) usage ;; esac
-               shift
-               no_edit=t
-               log_given=t$log_given
-               logfile="$1"
-               ;;
-       -F*|-f*)
-               no_edit=t
-               log_given=t$log_given
-               logfile="${1#-[Ff]}"
-               ;;
-       --F=*|--f=*|--fi=*|--fil=*|--file=*)
-               no_edit=t
-               log_given=t$log_given
-               logfile="${1#*=}"
-               ;;
-       -a|--a|--al|--all)
-               all=t
-               ;;
-       --allo|--allow|--allow-|--allow-e|--allow-em|--allow-emp|\
-       --allow-empt|--allow-empty)
-               allow_empty=t
-               ;;
-       --au=*|--aut=*|--auth=*|--autho=*|--author=*)
-               force_author="${1#*=}"
-               ;;
-       --au|--aut|--auth|--autho|--author)
-               case "$#" in 1) usage ;; esac
-               shift
-               force_author="$1"
-               ;;
-       -e|--e|--ed|--edi|--edit)
-               edit_flag=t
-               ;;
-       -i|--i|--in|--inc|--incl|--inclu|--includ|--include)
-               also=t
-               ;;
-       --int|--inte|--inter|--intera|--interac|--interact|--interacti|\
-       --interactiv|--interactive)
-               interactive=t
-               ;;
-       -o|--o|--on|--onl|--only)
-               only=t
-               ;;
-       -m|--m|--me|--mes|--mess|--messa|--messag|--message)
-               case "$#" in 1) usage ;; esac
-               shift
-               log_given=m$log_given
-               log_message="${log_message:+${log_message}
-
-}$1"
-               no_edit=t
-               ;;
-       -m*)
-               log_given=m$log_given
-               log_message="${log_message:+${log_message}
-
-}${1#-m}"
-               no_edit=t
-               ;;
-       --m=*|--me=*|--mes=*|--mess=*|--messa=*|--messag=*|--message=*)
-               log_given=m$log_given
-               log_message="${log_message:+${log_message}
-
-}${1#*=}"
-               no_edit=t
-               ;;
-       -n|--n|--no|--no-|--no-v|--no-ve|--no-ver|--no-veri|--no-verif|\
-       --no-verify)
-               verify=
-               ;;
-       --a|--am|--ame|--amen|--amend)
-               amend=t
-               use_commit=HEAD
-               ;;
-       -c)
-               case "$#" in 1) usage ;; esac
-               shift
-               log_given=t$log_given
-               use_commit="$1"
-               no_edit=
-               ;;
-       --ree=*|--reed=*|--reedi=*|--reedit=*|--reedit-=*|--reedit-m=*|\
-       --reedit-me=*|--reedit-mes=*|--reedit-mess=*|--reedit-messa=*|\
-       --reedit-messag=*|--reedit-message=*)
-               log_given=t$log_given
-               use_commit="${1#*=}"
-               no_edit=
-               ;;
-       --ree|--reed|--reedi|--reedit|--reedit-|--reedit-m|--reedit-me|\
-       --reedit-mes|--reedit-mess|--reedit-messa|--reedit-messag|\
-       --reedit-message)
-               case "$#" in 1) usage ;; esac
-               shift
-               log_given=t$log_given
-               use_commit="$1"
-               no_edit=
-               ;;
-       -C)
-               case "$#" in 1) usage ;; esac
-               shift
-               log_given=t$log_given
-               use_commit="$1"
-               no_edit=t
-               ;;
-       --reu=*|--reus=*|--reuse=*|--reuse-=*|--reuse-m=*|--reuse-me=*|\
-       --reuse-mes=*|--reuse-mess=*|--reuse-messa=*|--reuse-messag=*|\
-       --reuse-message=*)
-               log_given=t$log_given
-               use_commit="${1#*=}"
-               no_edit=t
-               ;;
-       --reu|--reus|--reuse|--reuse-|--reuse-m|--reuse-me|--reuse-mes|\
-       --reuse-mess|--reuse-messa|--reuse-messag|--reuse-message)
-               case "$#" in 1) usage ;; esac
-               shift
-               log_given=t$log_given
-               use_commit="$1"
-               no_edit=t
-               ;;
-       -s|--s|--si|--sig|--sign|--signo|--signof|--signoff)
-               signoff=t
-               ;;
-       -t|--t|--te|--tem|--temp|--templ|--templa|--templat|--template)
-               case "$#" in 1) usage ;; esac
-               shift
-               templatefile="$1"
-               no_edit=
-               ;;
-       -q|--q|--qu|--qui|--quie|--quiet)
-               quiet=t
-               ;;
-       -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
-               verbose=t
-               ;;
-       -u|--u|--un|--unt|--untr|--untra|--untrac|--untrack|--untracke|\
-       --untracked|--untracked-|--untracked-f|--untracked-fi|--untracked-fil|\
-       --untracked-file|--untracked-files)
-               untracked_files=t
-               ;;
-       --)
-               shift
-               break
-               ;;
-       -*)
-               usage
-               ;;
-       *)
-               break
-               ;;
-       esac
-       shift
-done
-case "$edit_flag" in t) no_edit= ;; esac
-
-################################################################
-# Sanity check options
-
-case "$amend,$initial_commit" in
-t,t)
-       die "You do not have anything to amend." ;;
-t,)
-       if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
-               die "You are in the middle of a merge -- cannot amend."
-       fi ;;
-esac
-
-case "$log_given" in
-tt*)
-       die "Only one of -c/-C/-F can be used." ;;
-*tm*|*mt*)
-       die "Option -m cannot be combined with -c/-C/-F." ;;
-esac
-
-case "$#,$also,$only,$amend" in
-*,t,t,*)
-       die "Only one of --include/--only can be used." ;;
-0,t,,* | 0,,t,)
-       die "No paths with --include/--only does not make sense." ;;
-0,,t,t)
-       only_include_assumed="# Clever... amending the last one with dirty index." ;;
-0,,,*)
-       ;;
-*,,,*)
-       only_include_assumed="# Explicit paths specified without -i or -o; assuming --only paths..."
-       also=
-       ;;
-esac
-unset only
-case "$all,$interactive,$also,$#" in
-*t,*t,*)
-       die "Cannot use -a, --interactive or -i at the same time." ;;
-t,,,[1-9]*)
-       die "Paths with -a does not make sense." ;;
-,t,,[1-9]*)
-       die "Paths with --interactive does not make sense." ;;
-,,t,0)
-       die "No paths with -i does not make sense." ;;
-esac
-
-if test ! -z "$templatefile" && test -z "$log_given"
-then
-       if test ! -f "$templatefile"
-       then
-               die "Commit template file does not exist."
-       fi
-fi
-
-################################################################
-# Prepare index to have a tree to be committed
-
-case "$all,$also" in
-t,)
-       if test ! -f "$THIS_INDEX"
-       then
-               die 'nothing to commit (use "git add file1 file2" to include for commit)'
-       fi
-       save_index &&
-       (
-               cd_to_toplevel &&
-               GIT_INDEX_FILE="$NEXT_INDEX" &&
-               export GIT_INDEX_FILE &&
-               git diff-files --name-only -z |
-               git update-index --remove -z --stdin
-       ) || exit
-       ;;
-,t)
-       save_index &&
-       git ls-files --error-unmatch -- "$@" >/dev/null || exit
-
-       git diff-files --name-only -z -- "$@"  |
-       (
-               cd_to_toplevel &&
-               GIT_INDEX_FILE="$NEXT_INDEX" &&
-               export GIT_INDEX_FILE &&
-               git update-index --remove -z --stdin
-       ) || exit
-       ;;
-,)
-       if test "$interactive" = t; then
-               git add --interactive || exit
-       fi
-       case "$#" in
-       0)
-               ;; # commit as-is
-       *)
-               if test -f "$GIT_DIR/MERGE_HEAD"
-               then
-                       refuse_partial "Cannot do a partial commit during a merge."
-               fi
-
-               TMP_INDEX="$GIT_DIR/tmp-index$$"
-               W=
-               test -z "$initial_commit" && W=--with-tree=HEAD
-               commit_only=$(git ls-files --error-unmatch $W -- "$@") || exit
-
-               # Build a temporary index and update the real index
-               # the same way.
-               if test -z "$initial_commit"
-               then
-                       GIT_INDEX_FILE="$THIS_INDEX" \
-                       git read-tree --index-output="$TMP_INDEX" -i -m HEAD
-               else
-                       rm -f "$TMP_INDEX"
-               fi || exit
-
-               printf '%s\n' "$commit_only" |
-               GIT_INDEX_FILE="$TMP_INDEX" \
-               git update-index --add --remove --stdin &&
-
-               save_index &&
-               printf '%s\n' "$commit_only" |
-               (
-                       GIT_INDEX_FILE="$NEXT_INDEX"
-                       export GIT_INDEX_FILE
-                       git update-index --add --remove --stdin
-               ) || exit
-               ;;
-       esac
-       ;;
-esac
-
-################################################################
-# If we do as-is commit, the index file will be THIS_INDEX,
-# otherwise NEXT_INDEX after we make this commit.  We leave
-# the index as is if we abort.
-
-if test -f "$NEXT_INDEX"
-then
-       USE_INDEX="$NEXT_INDEX"
-else
-       USE_INDEX="$THIS_INDEX"
-fi
-
-case "$status_only" in
-t)
-       # This will silently fail in a read-only repository, which is
-       # what we want.
-       GIT_INDEX_FILE="$USE_INDEX" git update-index -q --unmerged --refresh
-       run_status
-       exit $?
-       ;;
-'')
-       GIT_INDEX_FILE="$USE_INDEX" git update-index -q --refresh || exit
-       ;;
-esac
-
-################################################################
-# Grab commit message, write out tree and make commit.
-
-if test t = "$verify" && test -x "$GIT_DIR"/hooks/pre-commit
-then
-    GIT_INDEX_FILE="${TMP_INDEX:-${USE_INDEX}}" "$GIT_DIR"/hooks/pre-commit \
-    || exit
-fi
-
-if test "$log_message" != ''
-then
-       printf '%s\n' "$log_message"
-elif test "$logfile" != ""
-then
-       if test "$logfile" = -
-       then
-               test -t 0 &&
-               echo >&2 "(reading log message from standard input)"
-               cat
-       else
-               cat <"$logfile"
-       fi
-elif test "$use_commit" != ""
-then
-       encoding=$(git config i18n.commitencoding || echo UTF-8)
-       git show -s --pretty=raw --encoding="$encoding" "$use_commit" |
-       sed -e '1,/^$/d' -e 's/^    //'
-elif test -f "$GIT_DIR/MERGE_MSG"
-then
-       cat "$GIT_DIR/MERGE_MSG"
-elif test -f "$GIT_DIR/SQUASH_MSG"
-then
-       cat "$GIT_DIR/SQUASH_MSG"
-elif test "$templatefile" != ""
-then
-       cat "$templatefile"
-fi | git stripspace >"$GIT_DIR"/COMMIT_EDITMSG
-
-case "$signoff" in
-t)
-       sign=$(git var GIT_COMMITTER_IDENT | sed -e '
-               s/>.*/>/
-               s/^/Signed-off-by: /
-               ')
-       blank_before_signoff=
-       tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG |
-       grep 'Signed-off-by:' >/dev/null || blank_before_signoff='
-'
-       tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG |
-       grep "$sign"$ >/dev/null ||
-       printf '%s%s\n' "$blank_before_signoff" "$sign" \
-               >>"$GIT_DIR"/COMMIT_EDITMSG
-       ;;
-esac
-
-if test -f "$GIT_DIR/MERGE_HEAD" && test -z "$no_edit"; then
-       echo "#"
-       echo "# It looks like you may be committing a MERGE."
-       echo "# If this is not correct, please remove the file"
-       printf '%s\n' "#        $GIT_DIR/MERGE_HEAD"
-       echo "# and try again"
-       echo "#"
-fi >>"$GIT_DIR"/COMMIT_EDITMSG
-
-# Author
-if test '' != "$use_commit"
-then
-       eval "$(get_author_ident_from_commit "$use_commit")"
-       export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
-fi
-if test '' != "$force_author"
-then
-       GIT_AUTHOR_NAME=$(expr "z$force_author" : 'z\(.*[^ ]\) *<.*') &&
-       GIT_AUTHOR_EMAIL=$(expr "z$force_author" : '.*\(<.*\)') &&
-       test '' != "$GIT_AUTHOR_NAME" &&
-       test '' != "$GIT_AUTHOR_EMAIL" ||
-       die "malformed --author parameter"
-       export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL
-fi
-
-PARENTS="-p HEAD"
-if test -z "$initial_commit"
-then
-       rloga='commit'
-       if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
-               rloga='commit (merge)'
-               PARENTS="-p HEAD "$(sed -e 's/^/-p /' "$GIT_DIR/MERGE_HEAD")
-       elif test -n "$amend"; then
-               rloga='commit (amend)'
-               PARENTS=$(git cat-file commit HEAD |
-                       sed -n -e '/^$/q' -e 's/^parent /-p /p')
-       fi
-       current="$(git rev-parse --verify HEAD)"
-else
-       if [ -z "$(git ls-files)" ]; then
-               echo >&2 'nothing to commit (use "git add file1 file2" to include for commit)'
-               exit 1
-       fi
-       PARENTS=""
-       rloga='commit (initial)'
-       current=''
-fi
-set_reflog_action "$rloga"
-
-if test -z "$no_edit"
-then
-       {
-               echo ""
-               echo "# Please enter the commit message for your changes."
-               echo "# (Comment lines starting with '#' will not be included)"
-               test -z "$only_include_assumed" || echo "$only_include_assumed"
-               run_status
-       } >>"$GIT_DIR"/COMMIT_EDITMSG
-else
-       # we need to check if there is anything to commit
-       run_status >/dev/null
-fi
-case "$allow_empty,$?,$PARENTS" in
-t,* | ?,0,* | ?,*,-p' '?*-p' '?*)
-       # an explicit --allow-empty, or a merge commit can record the
-       # same tree as its parent.  Otherwise having commitable paths
-       # is required.
-       ;;
-*)
-       rm -f "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
-       use_status_color=t
-       run_status
-       exit 1
-esac
-
-case "$no_edit" in
-'')
-       git var GIT_AUTHOR_IDENT > /dev/null  || die
-       git var GIT_COMMITTER_IDENT > /dev/null  || die
-       git_editor "$GIT_DIR/COMMIT_EDITMSG"
-       ;;
-esac
-
-case "$verify" in
-t)
-       if test -x "$GIT_DIR"/hooks/commit-msg
-       then
-               "$GIT_DIR"/hooks/commit-msg "$GIT_DIR"/COMMIT_EDITMSG || exit
-       fi
-esac
-
-if test -z "$no_edit"
-then
-    sed -e '
-        /^diff --git a\/.*/{
-           s///
-           q
-       }
-       /^#/d
-    ' "$GIT_DIR"/COMMIT_EDITMSG
-else
-    cat "$GIT_DIR"/COMMIT_EDITMSG
-fi |
-git stripspace >"$GIT_DIR"/COMMIT_MSG
-
-# Test whether the commit message has any content we didn't supply.
-have_commitmsg=
-grep -v -i '^Signed-off-by' "$GIT_DIR"/COMMIT_MSG |
-       git stripspace > "$GIT_DIR"/COMMIT_BAREMSG
-
-# Is the commit message totally empty?
-if test -s "$GIT_DIR"/COMMIT_BAREMSG
-then
-       if test "$templatefile" != ""
-       then
-               # Test whether this is just the unaltered template.
-               if cnt=$(sed -e '/^#/d' < "$templatefile" |
-                       git stripspace |
-                       diff "$GIT_DIR"/COMMIT_BAREMSG - |
-                       wc -l) &&
-                  test 0 -lt $cnt
-               then
-                       have_commitmsg=t
-               fi
-       else
-               # No template, so the content in the commit message must
-               # have come from the user.
-               have_commitmsg=t
-       fi
-fi
-
-rm -f "$GIT_DIR"/COMMIT_BAREMSG
-
-if test "$have_commitmsg" = "t"
-then
-       if test -z "$TMP_INDEX"
-       then
-               tree=$(GIT_INDEX_FILE="$USE_INDEX" git write-tree)
-       else
-               tree=$(GIT_INDEX_FILE="$TMP_INDEX" git write-tree) &&
-               rm -f "$TMP_INDEX"
-       fi &&
-       commit=$(git commit-tree $tree $PARENTS <"$GIT_DIR/COMMIT_MSG") &&
-       rlogm=$(sed -e 1q "$GIT_DIR"/COMMIT_MSG) &&
-       git update-ref -m "$GIT_REFLOG_ACTION: $rlogm" HEAD $commit "$current" &&
-       rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" &&
-       if test -f "$NEXT_INDEX"
-       then
-               mv "$NEXT_INDEX" "$THIS_INDEX"
-       else
-               : ;# happy
-       fi
-else
-       echo >&2 "* no commit message?  aborting commit."
-       false
-fi
-ret="$?"
-rm -f "$GIT_DIR/COMMIT_MSG" "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
-
-cd_to_toplevel
-
-git rerere
-
-if test "$ret" = 0
-then
-       git gc --auto
-       if test -x "$GIT_DIR"/hooks/post-commit
-       then
-               "$GIT_DIR"/hooks/post-commit
-       fi
-       if test -z "$quiet"
-       then
-               commit=$(git diff-tree --always --shortstat --pretty="format:%h: %s"\
-                      --abbrev --summary --root HEAD --)
-               echo "Created${initial_commit:+ initial} commit $commit"
-       fi
-fi
-
-exit "$ret"
diff --git a/contrib/examples/git-difftool.perl b/contrib/examples/git-difftool.perl
deleted file mode 100755 (executable)
index b2ea80f..0000000
+++ /dev/null
@@ -1,481 +0,0 @@
-#!/usr/bin/perl
-# Copyright (c) 2009, 2010 David Aguilar
-# Copyright (c) 2012 Tim Henigan
-#
-# This is a wrapper around the GIT_EXTERNAL_DIFF-compatible
-# git-difftool--helper script.
-#
-# This script exports GIT_EXTERNAL_DIFF and GIT_PAGER for use by git.
-# The GIT_DIFF* variables are exported for use by git-difftool--helper.
-#
-# Any arguments that are unknown to this script are forwarded to 'git diff'.
-
-use 5.008;
-use strict;
-use warnings;
-use Git::LoadCPAN::Error qw(:try);
-use File::Basename qw(dirname);
-use File::Copy;
-use File::Find;
-use File::stat;
-use File::Path qw(mkpath rmtree);
-use File::Temp qw(tempdir);
-use Getopt::Long qw(:config pass_through);
-use Git;
-use Git::I18N;
-
-sub usage
-{
-       my $exitcode = shift;
-       print << 'USAGE';
-usage: git difftool [-t|--tool=<tool>] [--tool-help]
-                    [-x|--extcmd=<cmd>]
-                    [-g|--gui] [--no-gui]
-                    [--prompt] [-y|--no-prompt]
-                    [-d|--dir-diff]
-                    ['git diff' options]
-USAGE
-       exit($exitcode);
-}
-
-sub print_tool_help
-{
-       # See the comment at the bottom of file_diff() for the reason behind
-       # using system() followed by exit() instead of exec().
-       my $rc = system(qw(git mergetool --tool-help=diff));
-       exit($rc | ($rc >> 8));
-}
-
-sub exit_cleanup
-{
-       my ($tmpdir, $status) = @_;
-       my $errno = $!;
-       rmtree($tmpdir);
-       if ($status and $errno) {
-               my ($package, $file, $line) = caller();
-               warn "$file line $line: $errno\n";
-       }
-       exit($status | ($status >> 8));
-}
-
-sub use_wt_file
-{
-       my ($file, $sha1) = @_;
-       my $null_sha1 = '0' x 40;
-
-       if (-l $file || ! -e _) {
-               return (0, $null_sha1);
-       }
-
-       my $wt_sha1 = Git::command_oneline('hash-object', $file);
-       my $use = ($sha1 eq $null_sha1) || ($sha1 eq $wt_sha1);
-       return ($use, $wt_sha1);
-}
-
-sub changed_files
-{
-       my ($repo_path, $index, $worktree) = @_;
-       $ENV{GIT_INDEX_FILE} = $index;
-
-       my @gitargs = ('--git-dir', $repo_path, '--work-tree', $worktree);
-       my @refreshargs = (
-               @gitargs, 'update-index',
-               '--really-refresh', '-q', '--unmerged');
-       try {
-               Git::command_oneline(@refreshargs);
-       } catch Git::Error::Command with {};
-
-       my @diffargs = (@gitargs, 'diff-files', '--name-only', '-z');
-       my $line = Git::command_oneline(@diffargs);
-       my @files;
-       if (defined $line) {
-               @files = split('\0', $line);
-       } else {
-               @files = ();
-       }
-
-       delete($ENV{GIT_INDEX_FILE});
-
-       return map { $_ => 1 } @files;
-}
-
-sub setup_dir_diff
-{
-       my ($worktree, $symlinks) = @_;
-       my @gitargs = ('diff', '--raw', '--no-abbrev', '-z', @ARGV);
-       my $diffrtn = Git::command_oneline(@gitargs);
-       exit(0) unless defined($diffrtn);
-
-       # Go to the root of the worktree now that we've captured the list of
-       # changed files.  The paths returned by diff --raw are relative to the
-       # top-level of the repository, but we defer changing directories so
-       # that @ARGV can perform pathspec limiting in the current directory.
-       chdir($worktree);
-
-       # Build index info for left and right sides of the diff
-       my $submodule_mode = '160000';
-       my $symlink_mode = '120000';
-       my $null_mode = '0' x 6;
-       my $null_sha1 = '0' x 40;
-       my $lindex = '';
-       my $rindex = '';
-       my $wtindex = '';
-       my %submodule;
-       my %symlink;
-       my @files = ();
-       my %working_tree_dups = ();
-       my @rawdiff = split('\0', $diffrtn);
-
-       my $i = 0;
-       while ($i < $#rawdiff) {
-               if ($rawdiff[$i] =~ /^::/) {
-                       warn __ <<'EOF';
-Combined diff formats ('-c' and '--cc') are not supported in
-directory diff mode ('-d' and '--dir-diff').
-EOF
-                       exit(1);
-               }
-
-               my ($lmode, $rmode, $lsha1, $rsha1, $status) =
-                       split(' ', substr($rawdiff[$i], 1));
-               my $src_path = $rawdiff[$i + 1];
-               my $dst_path;
-
-               if ($status =~ /^[CR]/) {
-                       $dst_path = $rawdiff[$i + 2];
-                       $i += 3;
-               } else {
-                       $dst_path = $src_path;
-                       $i += 2;
-               }
-
-               if ($lmode eq $submodule_mode or $rmode eq $submodule_mode) {
-                       $submodule{$src_path}{left} = $lsha1;
-                       if ($lsha1 ne $rsha1) {
-                               $submodule{$dst_path}{right} = $rsha1;
-                       } else {
-                               $submodule{$dst_path}{right} = "$rsha1-dirty";
-                       }
-                       next;
-               }
-
-               if ($lmode eq $symlink_mode) {
-                       $symlink{$src_path}{left} =
-                               Git::command_oneline('show', $lsha1);
-               }
-
-               if ($rmode eq $symlink_mode) {
-                       $symlink{$dst_path}{right} =
-                               Git::command_oneline('show', $rsha1);
-               }
-
-               if ($lmode ne $null_mode and $status !~ /^C/) {
-                       $lindex .= "$lmode $lsha1\t$src_path\0";
-               }
-
-               if ($rmode ne $null_mode) {
-                       # Avoid duplicate entries
-                       if ($working_tree_dups{$dst_path}++) {
-                               next;
-                       }
-                       my ($use, $wt_sha1) =
-                               use_wt_file($dst_path, $rsha1);
-                       if ($use) {
-                               push @files, $dst_path;
-                               $wtindex .= "$rmode $wt_sha1\t$dst_path\0";
-                       } else {
-                               $rindex .= "$rmode $rsha1\t$dst_path\0";
-                       }
-               }
-       }
-
-       # Go to the root of the worktree so that the left index files
-       # are properly setup -- the index is toplevel-relative.
-       chdir($worktree);
-
-       # Setup temp directories
-       my $tmpdir = tempdir('git-difftool.XXXXX', CLEANUP => 0, TMPDIR => 1);
-       my $ldir = "$tmpdir/left";
-       my $rdir = "$tmpdir/right";
-       mkpath($ldir) or exit_cleanup($tmpdir, 1);
-       mkpath($rdir) or exit_cleanup($tmpdir, 1);
-
-       # Populate the left and right directories based on each index file
-       my ($inpipe, $ctx);
-       $ENV{GIT_INDEX_FILE} = "$tmpdir/lindex";
-       ($inpipe, $ctx) =
-               Git::command_input_pipe('update-index', '-z', '--index-info');
-       print($inpipe $lindex);
-       Git::command_close_pipe($inpipe, $ctx);
-
-       my $rc = system('git', 'checkout-index', '--all', "--prefix=$ldir/");
-       exit_cleanup($tmpdir, $rc) if $rc != 0;
-
-       $ENV{GIT_INDEX_FILE} = "$tmpdir/rindex";
-       ($inpipe, $ctx) =
-               Git::command_input_pipe('update-index', '-z', '--index-info');
-       print($inpipe $rindex);
-       Git::command_close_pipe($inpipe, $ctx);
-
-       $rc = system('git', 'checkout-index', '--all', "--prefix=$rdir/");
-       exit_cleanup($tmpdir, $rc) if $rc != 0;
-
-       $ENV{GIT_INDEX_FILE} = "$tmpdir/wtindex";
-       ($inpipe, $ctx) =
-               Git::command_input_pipe('update-index', '--info-only', '-z', '--index-info');
-       print($inpipe $wtindex);
-       Git::command_close_pipe($inpipe, $ctx);
-
-       # If $GIT_DIR was explicitly set just for the update/checkout
-       # commands, then it should be unset before continuing.
-       delete($ENV{GIT_INDEX_FILE});
-
-       # Changes in the working tree need special treatment since they are
-       # not part of the index.
-       for my $file (@files) {
-               my $dir = dirname($file);
-               unless (-d "$rdir/$dir") {
-                       mkpath("$rdir/$dir") or
-                       exit_cleanup($tmpdir, 1);
-               }
-               if ($symlinks) {
-                       symlink("$worktree/$file", "$rdir/$file") or
-                       exit_cleanup($tmpdir, 1);
-               } else {
-                       copy($file, "$rdir/$file") or
-                       exit_cleanup($tmpdir, 1);
-
-                       my $mode = stat($file)->mode;
-                       chmod($mode, "$rdir/$file") or
-                       exit_cleanup($tmpdir, 1);
-               }
-       }
-
-       # Changes to submodules require special treatment. This loop writes a
-       # temporary file to both the left and right directories to show the
-       # change in the recorded SHA1 for the submodule.
-       for my $path (keys %submodule) {
-               my $ok = 0;
-               if (defined($submodule{$path}{left})) {
-                       $ok = write_to_file("$ldir/$path",
-                               "Subproject commit $submodule{$path}{left}");
-               }
-               if (defined($submodule{$path}{right})) {
-                       $ok = write_to_file("$rdir/$path",
-                               "Subproject commit $submodule{$path}{right}");
-               }
-               exit_cleanup($tmpdir, 1) if not $ok;
-       }
-
-       # Symbolic links require special treatment. The standard "git diff"
-       # shows only the link itself, not the contents of the link target.
-       # This loop replicates that behavior.
-       for my $path (keys %symlink) {
-               my $ok = 0;
-               if (defined($symlink{$path}{left})) {
-                       $ok = write_to_file("$ldir/$path",
-                                       $symlink{$path}{left});
-               }
-               if (defined($symlink{$path}{right})) {
-                       $ok = write_to_file("$rdir/$path",
-                                       $symlink{$path}{right});
-               }
-               exit_cleanup($tmpdir, 1) if not $ok;
-       }
-
-       return ($ldir, $rdir, $tmpdir, @files);
-}
-
-sub write_to_file
-{
-       my $path = shift;
-       my $value = shift;
-
-       # Make sure the path to the file exists
-       my $dir = dirname($path);
-       unless (-d "$dir") {
-               mkpath("$dir") or return 0;
-       }
-
-       # If the file already exists in that location, delete it.  This
-       # is required in the case of symbolic links.
-       unlink($path);
-
-       open(my $fh, '>', $path) or return 0;
-       print($fh $value);
-       close($fh);
-
-       return 1;
-}
-
-sub main
-{
-       # parse command-line options. all unrecognized options and arguments
-       # are passed through to the 'git diff' command.
-       my %opts = (
-               difftool_cmd => undef,
-               dirdiff => undef,
-               extcmd => undef,
-               gui => undef,
-               help => undef,
-               prompt => undef,
-               symlinks => $^O ne 'cygwin' &&
-                               $^O ne 'MSWin32' && $^O ne 'msys',
-               tool_help => undef,
-               trust_exit_code => undef,
-       );
-       GetOptions('g|gui!' => \$opts{gui},
-               'd|dir-diff' => \$opts{dirdiff},
-               'h' => \$opts{help},
-               'prompt!' => \$opts{prompt},
-               'y' => sub { $opts{prompt} = 0; },
-               'symlinks' => \$opts{symlinks},
-               'no-symlinks' => sub { $opts{symlinks} = 0; },
-               't|tool:s' => \$opts{difftool_cmd},
-               'tool-help' => \$opts{tool_help},
-               'trust-exit-code' => \$opts{trust_exit_code},
-               'no-trust-exit-code' => sub { $opts{trust_exit_code} = 0; },
-               'x|extcmd:s' => \$opts{extcmd});
-
-       if (defined($opts{help})) {
-               usage(0);
-       }
-       if (defined($opts{tool_help})) {
-               print_tool_help();
-       }
-       if (defined($opts{difftool_cmd})) {
-               if (length($opts{difftool_cmd}) > 0) {
-                       $ENV{GIT_DIFF_TOOL} = $opts{difftool_cmd};
-               } else {
-                       print __("No <tool> given for --tool=<tool>\n");
-                       usage(1);
-               }
-       }
-       if (defined($opts{extcmd})) {
-               if (length($opts{extcmd}) > 0) {
-                       $ENV{GIT_DIFFTOOL_EXTCMD} = $opts{extcmd};
-               } else {
-                       print __("No <cmd> given for --extcmd=<cmd>\n");
-                       usage(1);
-               }
-       }
-       if ($opts{gui}) {
-               my $guitool = Git::config('diff.guitool');
-               if (defined($guitool) && length($guitool) > 0) {
-                       $ENV{GIT_DIFF_TOOL} = $guitool;
-               }
-       }
-
-       if (!defined $opts{trust_exit_code}) {
-               $opts{trust_exit_code} = Git::config_bool('difftool.trustExitCode');
-       }
-       if ($opts{trust_exit_code}) {
-               $ENV{GIT_DIFFTOOL_TRUST_EXIT_CODE} = 'true';
-       } else {
-               $ENV{GIT_DIFFTOOL_TRUST_EXIT_CODE} = 'false';
-       }
-
-       # In directory diff mode, 'git-difftool--helper' is called once
-       # to compare the a/b directories.  In file diff mode, 'git diff'
-       # will invoke a separate instance of 'git-difftool--helper' for
-       # each file that changed.
-       if (defined($opts{dirdiff})) {
-               dir_diff($opts{extcmd}, $opts{symlinks});
-       } else {
-               file_diff($opts{prompt});
-       }
-}
-
-sub dir_diff
-{
-       my ($extcmd, $symlinks) = @_;
-       my $rc;
-       my $error = 0;
-       my $repo = Git->repository();
-       my $repo_path = $repo->repo_path();
-       my $worktree = $repo->wc_path();
-       $worktree =~ s|/$||; # Avoid double slashes in symlink targets
-       my ($a, $b, $tmpdir, @files) = setup_dir_diff($worktree, $symlinks);
-
-       if (defined($extcmd)) {
-               $rc = system($extcmd, $a, $b);
-       } else {
-               $ENV{GIT_DIFFTOOL_DIRDIFF} = 'true';
-               $rc = system('git', 'difftool--helper', $a, $b);
-       }
-       # If the diff including working copy files and those
-       # files were modified during the diff, then the changes
-       # should be copied back to the working tree.
-       # Do not copy back files when symlinks are used and the
-       # external tool did not replace the original link with a file.
-       #
-       # These hashes are loaded lazily since they aren't needed
-       # in the common case of --symlinks and the difftool updating
-       # files through the symlink.
-       my %wt_modified;
-       my %tmp_modified;
-       my $indices_loaded = 0;
-
-       for my $file (@files) {
-               next if $symlinks && -l "$b/$file";
-               next if ! -f "$b/$file";
-
-               if (!$indices_loaded) {
-                       %wt_modified = changed_files(
-                               $repo_path, "$tmpdir/wtindex", $worktree);
-                       %tmp_modified = changed_files(
-                               $repo_path, "$tmpdir/wtindex", $b);
-                       $indices_loaded = 1;
-               }
-
-               if (exists $wt_modified{$file} and exists $tmp_modified{$file}) {
-                       warn sprintf(__(
-                               "warning: Both files modified:\n" .
-                               "'%s/%s' and '%s/%s'.\n" .
-                               "warning: Working tree file has been left.\n" .
-                               "warning:\n"), $worktree, $file, $b, $file);
-                       $error = 1;
-               } elsif (exists $tmp_modified{$file}) {
-                       my $mode = stat("$b/$file")->mode;
-                       copy("$b/$file", $file) or
-                       exit_cleanup($tmpdir, 1);
-
-                       chmod($mode, $file) or
-                       exit_cleanup($tmpdir, 1);
-               }
-       }
-       if ($error) {
-               warn sprintf(__(
-                       "warning: Temporary files exist in '%s'.\n" .
-                       "warning: You may want to cleanup or recover these.\n"), $tmpdir);
-               exit(1);
-       } else {
-               exit_cleanup($tmpdir, $rc);
-       }
-}
-
-sub file_diff
-{
-       my ($prompt) = @_;
-
-       if (defined($prompt)) {
-               if ($prompt) {
-                       $ENV{GIT_DIFFTOOL_PROMPT} = 'true';
-               } else {
-                       $ENV{GIT_DIFFTOOL_NO_PROMPT} = 'true';
-               }
-       }
-
-       $ENV{GIT_PAGER} = '';
-       $ENV{GIT_EXTERNAL_DIFF} = 'git-difftool--helper';
-
-       # ActiveState Perl for Win32 does not implement POSIX semantics of
-       # exec* system call. It just spawns the given executable and finishes
-       # the starting program, exiting with code 0.
-       # system will at least catch the errors returned by git diff,
-       # allowing the caller of git difftool better handling of failures.
-       my $rc = system('git', 'diff', @ARGV);
-       exit($rc | ($rc >> 8));
-}
-
-main();
diff --git a/contrib/examples/git-fetch.sh b/contrib/examples/git-fetch.sh
deleted file mode 100755 (executable)
index 57d2e56..0000000
+++ /dev/null
@@ -1,379 +0,0 @@
-#!/bin/sh
-#
-
-USAGE='<fetch-options> <repository> <refspec>...'
-SUBDIRECTORY_OK=Yes
-. git-sh-setup
-set_reflog_action "fetch $*"
-cd_to_toplevel ;# probably unnecessary...
-
-. git-parse-remote
-_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
-_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
-
-LF='
-'
-IFS="$LF"
-
-no_tags=
-tags=
-append=
-force=
-verbose=
-update_head_ok=
-exec=
-keep=
-shallow_depth=
-no_progress=
-test -t 1 || no_progress=--no-progress
-quiet=
-while test $# != 0
-do
-       case "$1" in
-       -a|--a|--ap|--app|--appe|--appen|--append)
-               append=t
-               ;;
-       --upl|--uplo|--uploa|--upload|--upload-|--upload-p|\
-       --upload-pa|--upload-pac|--upload-pack)
-               shift
-               exec="--upload-pack=$1"
-               ;;
-       --upl=*|--uplo=*|--uploa=*|--upload=*|\
-       --upload-=*|--upload-p=*|--upload-pa=*|--upload-pac=*|--upload-pack=*)
-               exec=--upload-pack=$(expr "z$1" : 'z-[^=]*=\(.*\)')
-               shift
-               ;;
-       -f|--f|--fo|--for|--forc|--force)
-               force=t
-               ;;
-       -t|--t|--ta|--tag|--tags)
-               tags=t
-               ;;
-       -n|--n|--no|--no-|--no-t|--no-ta|--no-tag|--no-tags)
-               no_tags=t
-               ;;
-       -u|--u|--up|--upd|--upda|--updat|--update|--update-|--update-h|\
-       --update-he|--update-hea|--update-head|--update-head-|\
-       --update-head-o|--update-head-ok)
-               update_head_ok=t
-               ;;
-       -q|--q|--qu|--qui|--quie|--quiet)
-               quiet=--quiet
-               ;;
-       -v|--verbose)
-               verbose="$verbose"Yes
-               ;;
-       -k|--k|--ke|--kee|--keep)
-               keep='-k -k'
-               ;;
-       --depth=*)
-               shallow_depth="--depth=$(expr "z$1" : 'z-[^=]*=\(.*\)')"
-               ;;
-       --depth)
-               shift
-               shallow_depth="--depth=$1"
-               ;;
-       -*)
-               usage
-               ;;
-       *)
-               break
-               ;;
-       esac
-       shift
-done
-
-case "$#" in
-0)
-       origin=$(get_default_remote)
-       test -n "$(get_remote_url ${origin})" ||
-               die "Where do you want to fetch from today?"
-       set x $origin ; shift ;;
-esac
-
-if test -z "$exec"
-then
-       # No command line override and we have configuration for the remote.
-       exec="--upload-pack=$(get_uploadpack $1)"
-fi
-
-remote_nick="$1"
-remote=$(get_remote_url "$@")
-refs=
-rref=
-rsync_slurped_objects=
-
-if test "" = "$append"
-then
-       : >"$GIT_DIR/FETCH_HEAD"
-fi
-
-# Global that is reused later
-ls_remote_result=$(git ls-remote $exec "$remote") ||
-       die "Cannot get the repository state from $remote"
-
-append_fetch_head () {
-       flags=
-       test -n "$verbose" && flags="$flags$LF-v"
-       test -n "$force$single_force" && flags="$flags$LF-f"
-       GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION" \
-               git fetch--tool $flags append-fetch-head "$@"
-}
-
-# updating the current HEAD with git-fetch in a bare
-# repository is always fine.
-if test -z "$update_head_ok" && test $(is_bare_repository) = false
-then
-       orig_head=$(git rev-parse --verify HEAD 2>/dev/null)
-fi
-
-# Allow --tags/--notags from remote.$1.tagopt
-case "$tags$no_tags" in
-'')
-       case "$(git config --get "remote.$1.tagopt")" in
-       --tags)
-               tags=t ;;
-       --no-tags)
-               no_tags=t ;;
-       esac
-esac
-
-# If --tags (and later --heads or --all) is specified, then we are
-# not talking about defaults stored in Pull: line of remotes or
-# branches file, and just fetch those and refspecs explicitly given.
-# Otherwise we do what we always did.
-
-reflist=$(get_remote_refs_for_fetch "$@")
-if test "$tags"
-then
-       taglist=$(IFS=' ' &&
-                 echo "$ls_remote_result" |
-                 git show-ref --exclude-existing=refs/tags/ |
-                 while read sha1 name
-                 do
-                       echo ".${name}:${name}"
-                 done) || exit
-       if test "$#" -gt 1
-       then
-               # remote URL plus explicit refspecs; we need to merge them.
-               reflist="$reflist$LF$taglist"
-       else
-               # No explicit refspecs; fetch tags only.
-               reflist=$taglist
-       fi
-fi
-
-fetch_all_at_once () {
-
-  eval=$(echo "$1" | git fetch--tool parse-reflist "-")
-  eval "$eval"
-
-    ( : subshell because we muck with IFS
-      IFS="    $LF"
-      (
-       if test "$remote" = . ; then
-           git show-ref $rref || echo failed "$remote"
-       elif test -f "$remote" ; then
-           test -n "$shallow_depth" &&
-               die "shallow clone with bundle is not supported"
-           git bundle unbundle "$remote" $rref ||
-           echo failed "$remote"
-       else
-               if      test -d "$remote" &&
-
-                       # The remote might be our alternate.  With
-                       # this optimization we will bypass fetch-pack
-                       # altogether, which means we cannot be doing
-                       # the shallow stuff at all.
-                       test ! -f "$GIT_DIR/shallow" &&
-                       test -z "$shallow_depth" &&
-
-                       # See if all of what we are going to fetch are
-                       # connected to our repository's tips, in which
-                       # case we do not have to do any fetch.
-                       theirs=$(echo "$ls_remote_result" | \
-                               git fetch--tool -s pick-rref "$rref" "-") &&
-
-                       # This will barf when $theirs reach an object that
-                       # we do not have in our repository.  Otherwise,
-                       # we already have everything the fetch would bring in.
-                       git rev-list --objects $theirs --not --all \
-                               >/dev/null 2>/dev/null
-               then
-                       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 $flags "$remote" $rref ||
-                       echo failed "$remote"
-               fi
-       fi
-      ) |
-      (
-       flags=
-       test -n "$verbose" && flags="$flags -v"
-       test -n "$force" && flags="$flags -f"
-       GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION" \
-               git fetch--tool $flags native-store \
-                       "$remote" "$remote_nick" "$refs"
-      )
-    ) || exit
-
-}
-
-fetch_per_ref () {
-  reflist="$1"
-  refs=
-  rref=
-
-  for ref in $reflist
-  do
-      refs="$refs$LF$ref"
-
-      # These are relative path from $GIT_DIR, typically starting at refs/
-      # but may be HEAD
-      if expr "z$ref" : 'z\.' >/dev/null
-      then
-         not_for_merge=t
-         ref=$(expr "z$ref" : 'z\.\(.*\)')
-      else
-         not_for_merge=
-      fi
-      if expr "z$ref" : 'z+' >/dev/null
-      then
-         single_force=t
-         ref=$(expr "z$ref" : 'z+\(.*\)')
-      else
-         single_force=
-      fi
-      remote_name=$(expr "z$ref" : 'z\([^:]*\):')
-      local_name=$(expr "z$ref" : 'z[^:]*:\(.*\)')
-
-      rref="$rref$LF$remote_name"
-
-      # There are transports that can fetch only one head at a time...
-      case "$remote" in
-      http://* | https://* | ftp://*)
-         test -n "$shallow_depth" &&
-               die "shallow clone with http not supported"
-         proto=$(expr "$remote" : '\([^:]*\):')
-         if [ -n "$GIT_SSL_NO_VERIFY" ]; then
-             curl_extra_args="-k"
-         fi
-         if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \
-               "$(git config --bool http.noEPSV)" = true ]; then
-             noepsv_opt="--disable-epsv"
-         fi
-
-         # Find $remote_name from ls-remote output.
-         head=$(echo "$ls_remote_result" | \
-               git fetch--tool -s pick-rref "$remote_name" "-")
-         expr "z$head" : "z$_x40\$" >/dev/null ||
-               die "No such ref $remote_name at $remote"
-         echo >&2 "Fetching $remote_name from $remote using $proto"
-         case "$quiet" in '') v=-v ;; *) v= ;; esac
-         git-http-fetch $v -a "$head" "$remote" || exit
-         ;;
-      rsync://*)
-         test -n "$shallow_depth" &&
-               die "shallow clone with rsync not supported"
-         TMP_HEAD="$GIT_DIR/TMP_HEAD"
-         rsync -L -q "$remote/$remote_name" "$TMP_HEAD" || exit 1
-         head=$(git rev-parse --verify TMP_HEAD)
-         rm -f "$TMP_HEAD"
-         case "$quiet" in '') v=-v ;; *) v= ;; esac
-         test "$rsync_slurped_objects" || {
-             rsync -a $v --ignore-existing --exclude info \
-                 "$remote/objects/" "$GIT_OBJECT_DIRECTORY/" || exit
-
-             # Look at objects/info/alternates for rsync -- http will
-             # support it natively and git native ones will do it on
-             # the remote end.  Not having that file is not a crime.
-             rsync -q "$remote/objects/info/alternates" \
-                 "$GIT_DIR/TMP_ALT" 2>/dev/null ||
-                 rm -f "$GIT_DIR/TMP_ALT"
-             if test -f "$GIT_DIR/TMP_ALT"
-             then
-                 resolve_alternates "$remote" <"$GIT_DIR/TMP_ALT" |
-                 while read alt
-                 do
-                     case "$alt" in 'bad alternate: '*) die "$alt";; esac
-                     echo >&2 "Getting alternate: $alt"
-                     rsync -av --ignore-existing --exclude info \
-                     "$alt" "$GIT_OBJECT_DIRECTORY/" || exit
-                 done
-                 rm -f "$GIT_DIR/TMP_ALT"
-             fi
-             rsync_slurped_objects=t
-         }
-         ;;
-      esac
-
-      append_fetch_head "$head" "$remote" \
-         "$remote_name" "$remote_nick" "$local_name" "$not_for_merge" || exit
-
-  done
-
-}
-
-fetch_main () {
-       case "$remote" in
-       http://* | https://* | ftp://* | rsync://* )
-               fetch_per_ref "$@"
-               ;;
-       *)
-               fetch_all_at_once "$@"
-               ;;
-       esac
-}
-
-fetch_main "$reflist" || exit
-
-# automated tag following
-case "$no_tags$tags" in
-'')
-       case "$reflist" in
-       *:refs/*)
-               # effective only when we are following remote branch
-               # using local tracking branch.
-               taglist=$(IFS=' ' &&
-               echo "$ls_remote_result" |
-               git show-ref --exclude-existing=refs/tags/ |
-               while read sha1 name
-               do
-                       git cat-file -t "$sha1" >/dev/null 2>&1 || continue
-                       echo >&2 "Auto-following $name"
-                       echo ".${name}:${name}"
-               done)
-       esac
-       case "$taglist" in
-       '') ;;
-       ?*)
-               # do not deepen a shallow tree when following tags
-               shallow_depth=
-               fetch_main "$taglist" || exit ;;
-       esac
-esac
-
-# If the original head was empty (i.e. no "master" yet), or
-# if we were told not to worry, we do not have to check.
-case "$orig_head" in
-'')
-       ;;
-?*)
-       curr_head=$(git rev-parse --verify HEAD 2>/dev/null)
-       if test "$curr_head" != "$orig_head"
-       then
-           git update-ref \
-                       -m "$GIT_REFLOG_ACTION: Undoing incorrectly fetched HEAD." \
-                       HEAD "$orig_head"
-               die "Cannot fetch into the current branch."
-       fi
-       ;;
-esac
diff --git a/contrib/examples/git-gc.sh b/contrib/examples/git-gc.sh
deleted file mode 100755 (executable)
index 1597e9f..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2006, Shawn O. Pearce
-#
-# Cleanup unreachable files and optimize the repository.
-
-USAGE='[--prune]'
-SUBDIRECTORY_OK=Yes
-. git-sh-setup
-
-no_prune=:
-while test $# != 0
-do
-       case "$1" in
-       --prune)
-               no_prune=
-               ;;
-       --)
-               usage
-               ;;
-       esac
-       shift
-done
-
-case "$(git config --get gc.packrefs)" in
-notbare|"")
-       test $(is_bare_repository) = true || pack_refs=true;;
-*)
-       pack_refs=$(git config --bool --get gc.packrefs)
-esac
-
-test "true" != "$pack_refs" ||
-git pack-refs --prune &&
-git reflog expire --all &&
-git-repack -a -d -l &&
-$no_prune git prune &&
-git rerere gc || exit
diff --git a/contrib/examples/git-log.sh b/contrib/examples/git-log.sh
deleted file mode 100755 (executable)
index c2ea71c..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005 Linus Torvalds
-#
-
-USAGE='[--max-count=<n>] [<since>..<limit>] [--pretty=<format>] [git-rev-list options]'
-SUBDIRECTORY_OK='Yes'
-. git-sh-setup
-
-revs=$(git-rev-parse --revs-only --no-flags --default HEAD "$@") || exit
-[ "$revs" ] || {
-       die "No HEAD ref"
-}
-git-rev-list --pretty $(git-rev-parse --default HEAD "$@") |
-LESS=-S ${PAGER:-less}
diff --git a/contrib/examples/git-ls-remote.sh b/contrib/examples/git-ls-remote.sh
deleted file mode 100755 (executable)
index 2aa89a7..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-#!/bin/sh
-#
-
-usage () {
-    echo >&2 "usage: $0 [--heads] [--tags] [-u|--upload-pack <upload-pack>]"
-    echo >&2 "          <repository> <refs>..."
-    exit 1;
-}
-
-die () {
-    echo >&2 "$*"
-    exit 1
-}
-
-exec=
-while test $# != 0
-do
-  case "$1" in
-  -h|--h|--he|--hea|--head|--heads)
-  heads=heads; shift ;;
-  -t|--t|--ta|--tag|--tags)
-  tags=tags; shift ;;
-  -u|--u|--up|--upl|--uploa|--upload|--upload-|--upload-p|--upload-pa|\
-  --upload-pac|--upload-pack)
-       shift
-       exec="--upload-pack=$1"
-       shift;;
-  -u=*|--u=*|--up=*|--upl=*|--uplo=*|--uploa=*|--upload=*|\
-  --upload-=*|--upload-p=*|--upload-pa=*|--upload-pac=*|--upload-pack=*)
-       exec=--upload-pack=$(expr "z$1" : 'z-[^=]*=\(.*\)')
-       shift;;
-  --)
-  shift; break ;;
-  -*)
-  usage ;;
-  *)
-  break ;;
-  esac
-done
-
-case "$#" in 0) usage ;; esac
-
-case ",$heads,$tags," in
-,,,) heads=heads tags=tags other=other ;;
-esac
-
-. git-parse-remote
-peek_repo="$(get_remote_url "$@")"
-shift
-
-tmp=.ls-remote-$$
-trap "rm -fr $tmp-*" 0 1 2 3 15
-tmpdir=$tmp-d
-
-case "$peek_repo" in
-http://* | https://* | ftp://* )
-       if [ -n "$GIT_SSL_NO_VERIFY" -o \
-               "$(git config --bool http.sslVerify)" = false ]; then
-               curl_extra_args="-k"
-       fi
-       if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \
-               "$(git config --bool http.noEPSV)" = true ]; then
-               curl_extra_args="${curl_extra_args} --disable-epsv"
-       fi
-       curl -nsf $curl_extra_args --header "Pragma: no-cache" "$peek_repo/info/refs" ||
-               echo "failed    slurping"
-       ;;
-
-rsync://* )
-       mkdir $tmpdir &&
-       rsync -rlq "$peek_repo/HEAD" $tmpdir &&
-       rsync -rq "$peek_repo/refs" $tmpdir || {
-               echo "failed    slurping"
-               exit
-       }
-       head=$(cat "$tmpdir/HEAD") &&
-       case "$head" in
-       ref:' '*)
-               head=$(expr "z$head" : 'zref: \(.*\)') &&
-               head=$(cat "$tmpdir/$head") || exit
-       esac &&
-       echo "$head     HEAD"
-       (cd $tmpdir && find refs -type f) |
-       while read path
-       do
-               tr -d '\012' <"$tmpdir/$path"
-               echo "  $path"
-       done &&
-       rm -fr $tmpdir
-       ;;
-
-* )
-       if test -f "$peek_repo" ; then
-               git bundle list-heads "$peek_repo" ||
-               echo "failed    slurping"
-       else
-               git-peek-remote $exec "$peek_repo" ||
-               echo "failed    slurping"
-       fi
-       ;;
-esac |
-sort -t '      ' -k 2 |
-while read sha1 path
-do
-       case "$sha1" in
-       failed)
-               exit 1 ;;
-       esac
-       case "$path" in
-       refs/heads/*)
-               group=heads ;;
-       refs/tags/*)
-               group=tags ;;
-       *)
-               group=other ;;
-       esac
-       case ",$heads,$tags,$other," in
-       *,$group,*)
-               ;;
-       *)
-               continue;;
-       esac
-       case "$#" in
-       0)
-               match=yes ;;
-       *)
-               match=no
-               for pat
-               do
-                       case "/$path" in
-                       */$pat )
-                               match=yes
-                               break ;;
-                       esac
-               done
-       esac
-       case "$match" in
-       no)
-               continue ;;
-       esac
-       echo "$sha1     $path"
-done
diff --git a/contrib/examples/git-merge-ours.sh b/contrib/examples/git-merge-ours.sh
deleted file mode 100755 (executable)
index 29dba4b..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005 Junio C Hamano
-#
-# Pretend we resolved the heads, but declare our tree trumps everybody else.
-#
-
-# We need to exit with 2 if the index does not match our HEAD tree,
-# because the current index is what we will be committing as the
-# merge result.
-
-git diff-index --quiet --cached HEAD -- || exit 2
-
-exit 0
diff --git a/contrib/examples/git-merge.sh b/contrib/examples/git-merge.sh
deleted file mode 100755 (executable)
index 932e78d..0000000
+++ /dev/null
@@ -1,620 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005 Junio C Hamano
-#
-
-OPTIONS_KEEPDASHDASH=
-OPTIONS_SPEC="\
-git merge [options] <remote>...
-git merge [options] <msg> HEAD <remote>
---
-stat                 show a diffstat at the end of the merge
-n                    don't show a diffstat at the end of the merge
-summary              (synonym to --stat)
-log                  add list of one-line log to merge commit message
-squash               create a single commit instead of doing a merge
-commit               perform a commit if the merge succeeds (default)
-ff                   allow fast-forward (default)
-ff-only              abort if fast-forward is not possible
-rerere-autoupdate    update index with any reused conflict resolution
-s,strategy=          merge strategy to use
-X=                   option for selected merge strategy
-m,message=           message to be used for the merge commit (if any)
-"
-
-SUBDIRECTORY_OK=Yes
-. git-sh-setup
-require_work_tree
-cd_to_toplevel
-
-test -z "$(git ls-files -u)" ||
-       die "Merge is not possible because you have unmerged files."
-
-! test -e "$GIT_DIR/MERGE_HEAD" ||
-       die 'You have not concluded your merge (MERGE_HEAD exists).'
-
-LF='
-'
-
-all_strategies='recur recursive octopus resolve stupid ours subtree'
-all_strategies="$all_strategies recursive-ours recursive-theirs"
-not_strategies='base file index tree'
-default_twohead_strategies='recursive'
-default_octopus_strategies='octopus'
-no_fast_forward_strategies='subtree ours'
-no_trivial_strategies='recursive recur subtree ours recursive-ours recursive-theirs'
-use_strategies=
-xopt=
-
-allow_fast_forward=t
-fast_forward_only=
-allow_trivial_merge=t
-squash= no_commit= log_arg= rr_arg=
-
-dropsave() {
-       rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" \
-                "$GIT_DIR/MERGE_STASH" "$GIT_DIR/MERGE_MODE" || exit 1
-}
-
-savestate() {
-       # Stash away any local modifications.
-       git stash create >"$GIT_DIR/MERGE_STASH"
-}
-
-restorestate() {
-        if test -f "$GIT_DIR/MERGE_STASH"
-       then
-               git reset --hard $head >/dev/null
-               git stash apply $(cat "$GIT_DIR/MERGE_STASH")
-               git update-index --refresh >/dev/null
-       fi
-}
-
-finish_up_to_date () {
-       case "$squash" in
-       t)
-               echo "$1 (nothing to squash)" ;;
-       '')
-               echo "$1" ;;
-       esac
-       dropsave
-}
-
-squash_message () {
-       echo Squashed commit of the following:
-       echo
-       git log --no-merges --pretty=medium ^"$head" $remoteheads
-}
-
-finish () {
-       if test '' = "$2"
-       then
-               rlogm="$GIT_REFLOG_ACTION"
-       else
-               echo "$2"
-               rlogm="$GIT_REFLOG_ACTION: $2"
-       fi
-       case "$squash" in
-       t)
-               echo "Squash commit -- not updating HEAD"
-               squash_message >"$GIT_DIR/SQUASH_MSG"
-               ;;
-       '')
-               case "$merge_msg" in
-               '')
-                       echo "No merge message -- not updating HEAD"
-                       ;;
-               *)
-                       git update-ref -m "$rlogm" HEAD "$1" "$head" || exit 1
-                       git gc --auto
-                       ;;
-               esac
-               ;;
-       esac
-       case "$1" in
-       '')
-               ;;
-       ?*)
-               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
-
-       # Run a post-merge hook
-        if test -x "$GIT_DIR"/hooks/post-merge
-        then
-           case "$squash" in
-           t)
-                "$GIT_DIR"/hooks/post-merge 1
-               ;;
-           '')
-                "$GIT_DIR"/hooks/post-merge 0
-               ;;
-           esac
-        fi
-}
-
-merge_name () {
-       remote="$1"
-       rh=$(git rev-parse --verify "$remote^0" 2>/dev/null) || return
-       if truname=$(expr "$remote" : '\(.*\)~[0-9]*$') &&
-               git show-ref -q --verify "refs/heads/$truname" 2>/dev/null
-       then
-               echo "$rh               branch '$truname' (early part) of ."
-               return
-       fi
-       if found_ref=$(git rev-parse --symbolic-full-name --verify \
-                                                       "$remote" 2>/dev/null)
-       then
-               expanded=$(git check-ref-format --branch "$remote") ||
-                       exit
-               if test "${found_ref#refs/heads/}" != "$found_ref"
-               then
-                       echo "$rh               branch '$expanded' of ."
-                       return
-               elif test "${found_ref#refs/remotes/}" != "$found_ref"
-               then
-                       echo "$rh               remote branch '$expanded' of ."
-                       return
-               fi
-       fi
-       if test "$remote" = "FETCH_HEAD" && test -r "$GIT_DIR/FETCH_HEAD"
-       then
-               sed -e 's/      not-for-merge   /               /' -e 1q \
-                       "$GIT_DIR/FETCH_HEAD"
-               return
-       fi
-       echo "$rh               commit '$remote'"
-}
-
-parse_config () {
-       while test $# != 0; do
-               case "$1" in
-               -n|--no-stat|--no-summary)
-                       show_diffstat=false ;;
-               --stat|--summary)
-                       show_diffstat=t ;;
-               --log|--no-log)
-                       log_arg=$1 ;;
-               --squash)
-                       test "$allow_fast_forward" = t ||
-                               die "You cannot combine --squash with --no-ff."
-                       squash=t no_commit=t ;;
-               --no-squash)
-                       squash= no_commit= ;;
-               --commit)
-                       no_commit= ;;
-               --no-commit)
-                       no_commit=t ;;
-               --ff)
-                       allow_fast_forward=t ;;
-               --no-ff)
-                       test "$squash" != t ||
-                               die "You cannot combine --squash with --no-ff."
-                       test "$fast_forward_only" != t ||
-                               die "You cannot combine --ff-only with --no-ff."
-                       allow_fast_forward=f ;;
-               --ff-only)
-                       test "$allow_fast_forward" != f ||
-                               die "You cannot combine --ff-only with --no-ff."
-                       fast_forward_only=t ;;
-               --rerere-autoupdate|--no-rerere-autoupdate)
-                       rr_arg=$1 ;;
-               -s|--strategy)
-                       shift
-                       case " $all_strategies " in
-                       *" $1 "*)
-                               use_strategies="$use_strategies$1 "
-                               ;;
-                       *)
-                               case " $not_strategies " in
-                               *" $1 "*)
-                                       false
-                               esac &&
-                               type "git-merge-$1" >/dev/null 2>&1 ||
-                                       die "available strategies are: $all_strategies"
-                               use_strategies="$use_strategies$1 "
-                               ;;
-                       esac
-                       ;;
-               -X)
-                       shift
-                       xopt="${xopt:+$xopt }$(git rev-parse --sq-quote "--$1")"
-                       ;;
-               -m|--message)
-                       shift
-                       merge_msg="$1"
-                       have_message=t
-                       ;;
-               --)
-                       shift
-                       break ;;
-               *)      usage ;;
-               esac
-               shift
-       done
-       args_left=$#
-}
-
-test $# != 0 || usage
-
-have_message=
-
-if branch=$(git-symbolic-ref -q HEAD)
-then
-       mergeopts=$(git config "branch.${branch#refs/heads/}.mergeoptions")
-       if test -n "$mergeopts"
-       then
-               parse_config $mergeopts --
-       fi
-fi
-
-parse_config "$@"
-while test $args_left -lt $#; do shift; done
-
-if test -z "$show_diffstat"; then
-    test "$(git config --bool merge.diffstat)" = false && show_diffstat=false
-    test "$(git config --bool merge.stat)" = 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 commit-ish that
-# is the same as HEAD there instead.  Traditional format never would
-# have "-m" so it is an additional safety measure to check for it.
-
-if test -z "$have_message" &&
-       second_token=$(git rev-parse --verify "$2^0" 2>/dev/null) &&
-       head_commit=$(git rev-parse --verify "HEAD" 2>/dev/null) &&
-       test "$second_token" = "$head_commit"
-then
-       merge_msg="$1"
-       shift
-       head_arg="$1"
-       shift
-elif ! git rev-parse --verify HEAD >/dev/null 2>&1
-then
-       # If the merged head is a valid one there is no reason to
-       # forbid "git merge" into a branch yet to be born.  We do
-       # the same for "git pull".
-       if test 1 -ne $#
-       then
-               echo >&2 "Can merge only exactly one commit into empty head"
-               exit 1
-       fi
-
-       test "$squash" != t ||
-               die "Squash commit into empty head not supported yet"
-       test "$allow_fast_forward" = t ||
-               die "Non-fast-forward into an empty head does not make sense"
-       rh=$(git rev-parse --verify "$1^0") ||
-               die "$1 - not something we can merge"
-
-       git update-ref -m "initial pull" HEAD "$rh" "" &&
-       git read-tree --reset -u HEAD
-       exit
-
-else
-       # We are invoked directly as the first-class UI.
-       head_arg=HEAD
-
-       # All the rest are the commits being merged; prepare
-       # the standard merge summary message to be appended to
-       # the given message.  If remote is invalid we will die
-       # later in the common codepath so we discard the error
-       # in this loop.
-       merge_msg="$(
-               for remote
-               do
-                       merge_name "$remote"
-               done |
-               if test "$have_message" = t
-               then
-                       git fmt-merge-msg -m "$merge_msg" $log_arg
-               else
-                       git fmt-merge-msg $log_arg
-               fi
-       )"
-fi
-head=$(git rev-parse --verify "$head_arg"^0) || usage
-
-# All the rest are remote heads
-test "$#" = 0 && usage ;# we need at least one remote head.
-set_reflog_action "merge $*"
-
-remoteheads=
-for remote
-do
-       remotehead=$(git rev-parse --verify "$remote"^0 2>/dev/null) ||
-           die "$remote - not something we can merge"
-       remoteheads="${remoteheads}$remotehead "
-       eval GITHEAD_$remotehead='"$remote"'
-       export GITHEAD_$remotehead
-done
-set x $remoteheads ; shift
-
-case "$use_strategies" in
-'')
-       case "$#" in
-       1)
-               var="$(git config --get pull.twohead)"
-               if test -n "$var"
-               then
-                       use_strategies="$var"
-               else
-                       use_strategies="$default_twohead_strategies"
-               fi ;;
-       *)
-               var="$(git config --get pull.octopus)"
-               if test -n "$var"
-               then
-                       use_strategies="$var"
-               else
-                       use_strategies="$default_octopus_strategies"
-               fi ;;
-       esac
-       ;;
-esac
-
-for s in $use_strategies
-do
-       for ss in $no_fast_forward_strategies
-       do
-               case " $s " in
-               *" $ss "*)
-                       allow_fast_forward=f
-                       break
-                       ;;
-               esac
-       done
-       for ss in $no_trivial_strategies
-       do
-               case " $s " in
-               *" $ss "*)
-                       allow_trivial_merge=f
-                       break
-                       ;;
-               esac
-       done
-done
-
-case "$#" in
-1)
-       common=$(git merge-base --all $head "$@")
-       ;;
-*)
-       common=$(git merge-base --all --octopus $head "$@")
-       ;;
-esac
-echo "$head" >"$GIT_DIR/ORIG_HEAD"
-
-case "$allow_fast_forward,$#,$common,$no_commit" in
-?,*,'',*)
-       # No common ancestors found. We need a real merge.
-       ;;
-?,1,"$1",*)
-       # If head can reach all the merge then we are up to date.
-       # but first the most common case of merging one remote.
-       finish_up_to_date "Already up to date."
-       exit 0
-       ;;
-t,1,"$head",*)
-       # Again the most common case of merging one remote.
-       echo "Updating $(git rev-parse --short $head)..$(git rev-parse --short $1)"
-       git update-index --refresh 2>/dev/null
-       msg="Fast-forward"
-       if test -n "$have_message"
-       then
-               msg="$msg (no commit created; -m option ignored)"
-       fi
-       new_head=$(git rev-parse --verify "$1^0") &&
-       git read-tree -v -m -u --exclude-per-directory=.gitignore $head "$new_head" &&
-       finish "$new_head" "$msg" || exit
-       dropsave
-       exit 0
-       ;;
-?,1,?*"$LF"?*,*)
-       # We are not doing octopus and not fast-forward.  Need a
-       # real merge.
-       ;;
-?,1,*,)
-       # We are not doing octopus, not fast-forward, and have only
-       # one common.
-       git update-index --refresh 2>/dev/null
-       case "$allow_trivial_merge,$fast_forward_only" in
-       t,)
-               # See if it is really trivial.
-               git var GIT_COMMITTER_IDENT >/dev/null || exit
-               echo "Trying really trivial in-index merge..."
-               if git read-tree --trivial -m -u -v $common $head "$1" &&
-                  result_tree=$(git write-tree)
-               then
-                       echo "Wonderful."
-                       result_commit=$(
-                               printf '%s\n' "$merge_msg" |
-                               git commit-tree $result_tree -p HEAD -p "$1"
-                       ) || exit
-                       finish "$result_commit" "In-index merge"
-                       dropsave
-                       exit 0
-               fi
-               echo "Nope."
-       esac
-       ;;
-*)
-       # An octopus.  If we can reach all the remote we are up to date.
-       up_to_date=t
-       for remote
-       do
-               common_one=$(git merge-base --all $head $remote)
-               if test "$common_one" != "$remote"
-               then
-                       up_to_date=f
-                       break
-               fi
-       done
-       if test "$up_to_date" = t
-       then
-               finish_up_to_date "Already up to date. Yeeah!"
-               exit 0
-       fi
-       ;;
-esac
-
-if test "$fast_forward_only" = t
-then
-       die "Not possible to fast-forward, aborting."
-fi
-
-# We are going to make a new commit.
-git var GIT_COMMITTER_IDENT >/dev/null || exit
-
-# At this point, we need a real merge.  No matter what strategy
-# we use, it would operate on the index, possibly affecting the
-# working tree, and when resolved cleanly, have the desired tree
-# in the index -- this means that the index must be in sync with
-# the $head commit.  The strategies are responsible to ensure this.
-
-case "$use_strategies" in
-?*' '?*)
-    # Stash away the local changes so that we can try more than one.
-    savestate
-    single_strategy=no
-    ;;
-*)
-    rm -f "$GIT_DIR/MERGE_STASH"
-    single_strategy=yes
-    ;;
-esac
-
-result_tree= best_cnt=-1 best_strategy= wt_strategy=
-merge_was_ok=
-for strategy in $use_strategies
-do
-    test "$wt_strategy" = '' || {
-       echo "Rewinding the tree to pristine..."
-       restorestate
-    }
-    case "$single_strategy" in
-    no)
-       echo "Trying merge strategy $strategy..."
-       ;;
-    esac
-
-    # Remember which strategy left the state in the working tree
-    wt_strategy=$strategy
-
-    eval 'git-merge-$strategy '"$xopt"' $common -- "$head_arg" "$@"'
-    exit=$?
-    if test "$no_commit" = t && test "$exit" = 0
-    then
-        merge_was_ok=t
-       exit=1 ;# pretend it left conflicts.
-    fi
-
-    test "$exit" = 0 || {
-
-       # The backend exits with 1 when conflicts are left to be resolved,
-       # with 2 when it does not handle the given merge at all.
-
-       if test "$exit" -eq 1
-       then
-           cnt=$({
-               git diff-files --name-only
-               git ls-files --unmerged
-           } | wc -l)
-           if test $best_cnt -le 0 || test $cnt -le $best_cnt
-           then
-               best_strategy=$strategy
-               best_cnt=$cnt
-           fi
-       fi
-       continue
-    }
-
-    # Automerge succeeded.
-    result_tree=$(git write-tree) && break
-done
-
-# If we have a resulting tree, that means the strategy module
-# auto resolved the merge cleanly.
-if test '' != "$result_tree"
-then
-    if test "$allow_fast_forward" = "t"
-    then
-       parents=$(git merge-base --independent "$head" "$@")
-    else
-       parents=$(git rev-parse "$head" "$@")
-    fi
-    parents=$(echo "$parents" | sed -e 's/^/-p /')
-    result_commit=$(printf '%s\n' "$merge_msg" | git commit-tree $result_tree $parents) || exit
-    finish "$result_commit" "Merge made by $wt_strategy."
-    dropsave
-    exit 0
-fi
-
-# Pick the result from the best strategy and have the user fix it up.
-case "$best_strategy" in
-'')
-       restorestate
-       case "$use_strategies" in
-       ?*' '?*)
-               echo >&2 "No merge strategy handled the merge."
-               ;;
-       *)
-               echo >&2 "Merge with strategy $use_strategies failed."
-               ;;
-       esac
-       exit 2
-       ;;
-"$wt_strategy")
-       # We already have its result in the working tree.
-       ;;
-*)
-       echo "Rewinding the tree to pristine..."
-       restorestate
-       echo "Using the $best_strategy to prepare resolving by hand."
-       git-merge-$best_strategy $common -- "$head_arg" "$@"
-       ;;
-esac
-
-if test "$squash" = t
-then
-       finish
-else
-       for remote
-       do
-               echo $remote
-       done >"$GIT_DIR/MERGE_HEAD"
-       printf '%s\n' "$merge_msg" >"$GIT_DIR/MERGE_MSG" ||
-               die "Could not write to $GIT_DIR/MERGE_MSG"
-       if test "$allow_fast_forward" != t
-       then
-               printf "%s" no-ff
-       else
-               :
-       fi >"$GIT_DIR/MERGE_MODE" ||
-               die "Could not write to $GIT_DIR/MERGE_MODE"
-fi
-
-if test "$merge_was_ok" = t
-then
-       echo >&2 \
-       "Automatic merge went well; stopped before committing as requested"
-       exit 0
-else
-       {
-           echo '
-Conflicts:
-'
-               git ls-files --unmerged |
-               sed -e 's/^[^   ]*      /       /' |
-               uniq
-       } >>"$GIT_DIR/MERGE_MSG"
-       git rerere $rr_arg
-       die "Automatic merge failed; fix conflicts and then commit the result."
-fi
diff --git a/contrib/examples/git-notes.sh b/contrib/examples/git-notes.sh
deleted file mode 100755 (executable)
index e642e47..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-#!/bin/sh
-
-USAGE="(edit [-F <file> | -m <msg>] | show) [commit]"
-. git-sh-setup
-
-test -z "$1" && usage
-ACTION="$1"; shift
-
-test -z "$GIT_NOTES_REF" && GIT_NOTES_REF="$(git config core.notesref)"
-test -z "$GIT_NOTES_REF" && GIT_NOTES_REF="refs/notes/commits"
-
-MESSAGE=
-while test $# != 0
-do
-       case "$1" in
-       -m)
-               test "$ACTION" = "edit" || usage
-               shift
-               if test "$#" = "0"; then
-                       die "error: option -m needs an argument"
-               else
-                       if [ -z "$MESSAGE" ]; then
-                               MESSAGE="$1"
-                       else
-                               MESSAGE="$MESSAGE
-
-$1"
-                       fi
-                       shift
-               fi
-               ;;
-       -F)
-               test "$ACTION" = "edit" || usage
-               shift
-               if test "$#" = "0"; then
-                       die "error: option -F needs an argument"
-               else
-                       if [ -z "$MESSAGE" ]; then
-                               MESSAGE="$(cat "$1")"
-                       else
-                               MESSAGE="$MESSAGE
-
-$(cat "$1")"
-                       fi
-                       shift
-               fi
-               ;;
-       -*)
-               usage
-               ;;
-       *)
-               break
-               ;;
-       esac
-done
-
-COMMIT=$(git rev-parse --verify --default HEAD "$@") ||
-die "Invalid commit: $@"
-
-case "$ACTION" in
-edit)
-       if [ "${GIT_NOTES_REF#refs/notes/}" = "$GIT_NOTES_REF" ]; then
-               die "Refusing to edit notes in $GIT_NOTES_REF (outside of refs/notes/)"
-       fi
-
-       MSG_FILE="$GIT_DIR/new-notes-$COMMIT"
-       GIT_INDEX_FILE="$MSG_FILE.idx"
-       export GIT_INDEX_FILE
-
-       trap '
-               test -f "$MSG_FILE" && rm "$MSG_FILE"
-               test -f "$GIT_INDEX_FILE" && rm "$GIT_INDEX_FILE"
-       ' 0
-
-       CURRENT_HEAD=$(git show-ref "$GIT_NOTES_REF" | cut -f 1 -d ' ')
-       if [ -z "$CURRENT_HEAD" ]; then
-               PARENT=
-       else
-               PARENT="-p $CURRENT_HEAD"
-               git read-tree "$GIT_NOTES_REF" || die "Could not read index"
-       fi
-
-       if [ -z "$MESSAGE" ]; then
-               GIT_NOTES_REF= git log -1 $COMMIT | sed "s/^/#/" > "$MSG_FILE"
-               if [ ! -z "$CURRENT_HEAD" ]; then
-                       git cat-file blob :$COMMIT >> "$MSG_FILE" 2> /dev/null
-               fi
-               core_editor="$(git config core.editor)"
-               ${GIT_EDITOR:-${core_editor:-${VISUAL:-${EDITOR:-vi}}}} "$MSG_FILE"
-       else
-               echo "$MESSAGE" > "$MSG_FILE"
-       fi
-
-       grep -v ^# < "$MSG_FILE" | git stripspace > "$MSG_FILE".processed
-       mv "$MSG_FILE".processed "$MSG_FILE"
-       if [ -s "$MSG_FILE" ]; then
-               BLOB=$(git hash-object -w "$MSG_FILE") ||
-                       die "Could not write into object database"
-               git update-index --add --cacheinfo 0644 $BLOB $COMMIT ||
-                       die "Could not write index"
-       else
-               test -z "$CURRENT_HEAD" &&
-                       die "Will not initialise with empty tree"
-               git update-index --force-remove $COMMIT ||
-                       die "Could not update index"
-       fi
-
-       TREE=$(git write-tree) || die "Could not write tree"
-       NEW_HEAD=$(echo Annotate $COMMIT | git commit-tree $TREE $PARENT) ||
-               die "Could not annotate"
-       git update-ref -m "Annotate $COMMIT" \
-               "$GIT_NOTES_REF" $NEW_HEAD $CURRENT_HEAD
-;;
-show)
-       git rev-parse -q --verify "$GIT_NOTES_REF":$COMMIT > /dev/null ||
-               die "No note for commit $COMMIT."
-       git show "$GIT_NOTES_REF":$COMMIT
-;;
-*)
-       usage
-esac
diff --git a/contrib/examples/git-pull.sh b/contrib/examples/git-pull.sh
deleted file mode 100755 (executable)
index 6b3a03f..0000000
+++ /dev/null
@@ -1,381 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005 Junio C Hamano
-#
-# Fetch one or more remote refs and merge it/them into the current HEAD.
-
-SUBDIRECTORY_OK=Yes
-OPTIONS_KEEPDASHDASH=
-OPTIONS_STUCKLONG=Yes
-OPTIONS_SPEC="\
-git pull [options] [<repository> [<refspec>...]]
-
-Fetch one or more remote refs and integrate it/them with the current HEAD.
---
-v,verbose                  be more verbose
-q,quiet                    be more quiet
-progress                   force progress reporting
-
-  Options related to merging
-r,rebase?false|true|preserve incorporate changes by rebasing rather than merging
-n!                         do not show a diffstat at the end of the merge
-stat                       show a diffstat at the end of the merge
-summary                    (synonym to --stat)
-log?n                      add (at most <n>) entries from shortlog to merge commit message
-squash                     create a single commit instead of doing a merge
-commit                     perform a commit if the merge succeeds (default)
-e,edit                       edit message before committing
-ff                         allow fast-forward
-ff-only!                   abort if fast-forward is not possible
-verify-signatures          verify that the named commit has a valid GPG signature
-s,strategy=strategy        merge strategy to use
-X,strategy-option=option   option for selected merge strategy
-S,gpg-sign?key-id          GPG sign commit
-
-  Options related to fetching
-all                        fetch from all remotes
-a,append                   append to .git/FETCH_HEAD instead of overwriting
-upload-pack=path           path to upload pack on remote end
-f,force                    force overwrite of local branch
-t,tags                     fetch all tags and associated objects
-p,prune                    prune remote-tracking branches no longer on remote
-recurse-submodules?on-demand control recursive fetching of submodules
-dry-run                    dry run
-k,keep                     keep downloaded pack
-depth=depth                deepen history of shallow clone
-unshallow                  convert to a complete repository
-update-shallow             accept refs that update .git/shallow
-refmap=refmap              specify fetch refmap
-"
-test $# -gt 0 && args="$*"
-. git-sh-setup
-. git-sh-i18n
-set_reflog_action "pull${args+ $args}"
-require_work_tree_exists
-cd_to_toplevel
-
-
-die_conflict () {
-    git diff-index --cached --name-status -r --ignore-submodules HEAD --
-    if [ $(git config --bool --get advice.resolveConflict || echo true) = "true" ]; then
-       die "$(gettext "Pull is not possible because you have unmerged files.
-Please, fix them up in the work tree, and then use 'git add/rm <file>'
-as appropriate to mark resolution and make a commit.")"
-    else
-       die "$(gettext "Pull is not possible because you have unmerged files.")"
-    fi
-}
-
-die_merge () {
-    if [ $(git config --bool --get advice.resolveConflict || echo true) = "true" ]; then
-       die "$(gettext "You have not concluded your merge (MERGE_HEAD exists).
-Please, commit your changes before merging.")"
-    else
-       die "$(gettext "You have not concluded your merge (MERGE_HEAD exists).")"
-    fi
-}
-
-test -z "$(git ls-files -u)" || die_conflict
-test -f "$GIT_DIR/MERGE_HEAD" && die_merge
-
-bool_or_string_config () {
-       git config --bool "$1" 2>/dev/null || git config "$1"
-}
-
-strategy_args= diffstat= no_commit= squash= no_ff= ff_only=
-log_arg= verbosity= progress= recurse_submodules= verify_signatures=
-merge_args= edit= rebase_args= all= append= upload_pack= force= tags= prune=
-keep= depth= unshallow= update_shallow= refmap=
-curr_branch=$(git symbolic-ref -q HEAD)
-curr_branch_short="${curr_branch#refs/heads/}"
-rebase=$(bool_or_string_config branch.$curr_branch_short.rebase)
-if test -z "$rebase"
-then
-       rebase=$(bool_or_string_config pull.rebase)
-fi
-
-# Setup default fast-forward options via `pull.ff`
-pull_ff=$(bool_or_string_config pull.ff)
-case "$pull_ff" in
-true)
-       no_ff=--ff
-       ;;
-false)
-       no_ff=--no-ff
-       ;;
-only)
-       ff_only=--ff-only
-       ;;
-esac
-
-
-dry_run=
-while :
-do
-       case "$1" in
-       -q|--quiet)
-               verbosity="$verbosity -q" ;;
-       -v|--verbose)
-               verbosity="$verbosity -v" ;;
-       --progress)
-               progress=--progress ;;
-       --no-progress)
-               progress=--no-progress ;;
-       -n|--no-stat|--no-summary)
-               diffstat=--no-stat ;;
-       --stat|--summary)
-               diffstat=--stat ;;
-       --log|--log=*|--no-log)
-               log_arg="$1" ;;
-       --no-commit)
-               no_commit=--no-commit ;;
-       --commit)
-               no_commit=--commit ;;
-       -e|--edit)
-               edit=--edit ;;
-       --no-edit)
-               edit=--no-edit ;;
-       --squash)
-               squash=--squash ;;
-       --no-squash)
-               squash=--no-squash ;;
-       --ff)
-               no_ff=--ff ;;
-       --no-ff)
-               no_ff=--no-ff ;;
-       --ff-only)
-               ff_only=--ff-only ;;
-       -s*|--strategy=*)
-               strategy_args="$strategy_args $1"
-               ;;
-       -X*|--strategy-option=*)
-               merge_args="$merge_args $(git rev-parse --sq-quote "$1")"
-               ;;
-       -r*|--rebase=*)
-               rebase="${1#*=}"
-               ;;
-       --rebase)
-               rebase=true
-               ;;
-       --no-rebase)
-               rebase=false
-               ;;
-       --recurse-submodules)
-               recurse_submodules=--recurse-submodules
-               ;;
-       --recurse-submodules=*)
-               recurse_submodules="$1"
-               ;;
-       --no-recurse-submodules)
-               recurse_submodules=--no-recurse-submodules
-               ;;
-       --verify-signatures)
-               verify_signatures=--verify-signatures
-               ;;
-       --no-verify-signatures)
-               verify_signatures=--no-verify-signatures
-               ;;
-       --gpg-sign|-S)
-               gpg_sign_args=-S
-               ;;
-       --gpg-sign=*)
-               gpg_sign_args=$(git rev-parse --sq-quote "-S${1#--gpg-sign=}")
-               ;;
-       -S*)
-               gpg_sign_args=$(git rev-parse --sq-quote "$1")
-               ;;
-       --dry-run)
-               dry_run=--dry-run
-               ;;
-       --all|--no-all)
-               all=$1 ;;
-       -a|--append|--no-append)
-               append=$1 ;;
-       --upload-pack=*|--no-upload-pack)
-               upload_pack=$1 ;;
-       -f|--force|--no-force)
-               force="$force $1" ;;
-       -t|--tags|--no-tags)
-               tags=$1 ;;
-       -p|--prune|--no-prune)
-               prune=$1 ;;
-       -k|--keep|--no-keep)
-               keep=$1 ;;
-       --depth=*|--no-depth)
-               depth=$1 ;;
-       --unshallow|--no-unshallow)
-               unshallow=$1 ;;
-       --update-shallow|--no-update-shallow)
-               update_shallow=$1 ;;
-       --refmap=*|--no-refmap)
-               refmap=$1 ;;
-       -h|--help-all)
-               usage
-               ;;
-       --)
-               shift
-               break
-               ;;
-       *)
-               usage
-               ;;
-       esac
-       shift
-done
-
-case "$rebase" in
-preserve)
-       rebase=true
-       rebase_args=--preserve-merges
-       ;;
-true|false|'')
-       ;;
-*)
-       echo "Invalid value for --rebase, should be true, false, or preserve"
-       usage
-       exit 1
-       ;;
-esac
-
-error_on_no_merge_candidates () {
-       exec >&2
-
-       if test true = "$rebase"
-       then
-               op_type=rebase
-               op_prep=against
-       else
-               op_type=merge
-               op_prep=with
-       fi
-
-       upstream=$(git config "branch.$curr_branch_short.merge")
-       remote=$(git config "branch.$curr_branch_short.remote")
-
-       if [ $# -gt 1 ]; then
-               if [ "$rebase" = true ]; then
-                       printf "There is no candidate for rebasing against "
-               else
-                       printf "There are no candidates for merging "
-               fi
-               echo "among the refs that you just fetched."
-               echo "Generally this means that you provided a wildcard refspec which had no"
-               echo "matches on the remote end."
-       elif [ $# -gt 0 ] && [ "$1" != "$remote" ]; then
-               echo "You asked to pull from the remote '$1', but did not specify"
-               echo "a branch. Because this is not the default configured remote"
-               echo "for your current branch, you must specify a branch on the command line."
-       elif [ -z "$curr_branch" -o -z "$upstream" ]; then
-               . git-parse-remote
-               error_on_missing_default_upstream "pull" $op_type $op_prep \
-                       "git pull <remote> <branch>"
-       else
-               echo "Your configuration specifies to $op_type $op_prep the ref '${upstream#refs/heads/}'"
-               echo "from the remote, but no such ref was fetched."
-       fi
-       exit 1
-}
-
-test true = "$rebase" && {
-       if ! git rev-parse -q --verify HEAD >/dev/null
-       then
-               # On an unborn branch
-               if test -f "$(git rev-parse --git-path index)"
-               then
-                       die "$(gettext "updating an unborn branch with changes added to the index")"
-               fi
-       else
-               require_clean_work_tree "pull with rebase" "Please commit or stash them."
-       fi
-       oldremoteref= &&
-       test -n "$curr_branch" &&
-       . git-parse-remote &&
-       remoteref="$(get_remote_merge_branch "$@" 2>/dev/null)" &&
-       oldremoteref=$(git merge-base --fork-point "$remoteref" $curr_branch 2>/dev/null)
-}
-orig_head=$(git rev-parse -q --verify HEAD)
-git fetch $verbosity $progress $dry_run $recurse_submodules $all $append \
-${upload_pack:+"$upload_pack"} $force $tags $prune $keep $depth $unshallow $update_shallow \
-$refmap --update-head-ok "$@" || exit 1
-test -z "$dry_run" || exit 0
-
-curr_head=$(git rev-parse -q --verify HEAD)
-if test -n "$orig_head" && test "$curr_head" != "$orig_head"
-then
-       # The fetch involved updating the current branch.
-
-       # The working tree and the index file is still based on the
-       # $orig_head commit, but we are merging into $curr_head.
-       # First update the working tree to match $curr_head.
-
-       eval_gettextln "Warning: fetch updated the current branch head.
-Warning: fast-forwarding your working tree from
-Warning: commit \$orig_head." >&2
-       git update-index -q --refresh
-       git read-tree -u -m "$orig_head" "$curr_head" ||
-               die "$(eval_gettext "Cannot fast-forward your working tree.
-After making sure that you saved anything precious from
-$ git diff \$orig_head
-output, run
-$ git reset --hard
-to recover.")"
-
-fi
-
-merge_head=$(sed -e '/ not-for-merge   /d' \
-       -e 's/  .*//' "$GIT_DIR"/FETCH_HEAD | \
-       tr '\012' ' ')
-
-case "$merge_head" in
-'')
-       error_on_no_merge_candidates "$@"
-       ;;
-?*' '?*)
-       if test -z "$orig_head"
-       then
-               die "$(gettext "Cannot merge multiple branches into empty head")"
-       fi
-       if test true = "$rebase"
-       then
-               die "$(gettext "Cannot rebase onto multiple branches")"
-       fi
-       ;;
-esac
-
-# Pulling into unborn branch: a shorthand for branching off
-# FETCH_HEAD, for lazy typers.
-if test -z "$orig_head"
-then
-       # Two-way merge: we claim the index is based on an empty tree,
-       # and try to fast-forward to HEAD.  This ensures we will not
-       # lose index/worktree changes that the user already made on
-       # the unborn branch.
-       empty_tree=4b825dc642cb6eb9a060e54bf8d69288fbee4904
-       git read-tree -m -u $empty_tree $merge_head &&
-       git update-ref -m "initial pull" HEAD $merge_head "$curr_head"
-       exit
-fi
-
-if test true = "$rebase"
-then
-       o=$(git show-branch --merge-base $curr_branch $merge_head $oldremoteref)
-       if test "$oldremoteref" = "$o"
-       then
-               unset oldremoteref
-       fi
-fi
-
-case "$rebase" in
-true)
-       eval="git-rebase $diffstat $strategy_args $merge_args $rebase_args $verbosity"
-       eval="$eval $gpg_sign_args"
-       eval="$eval --onto $merge_head ${oldremoteref:-$merge_head}"
-       ;;
-*)
-       eval="git-merge $diffstat $no_commit $verify_signatures $edit $squash $no_ff $ff_only"
-       eval="$eval $log_arg $strategy_args $merge_args $verbosity $progress"
-       eval="$eval $gpg_sign_args"
-       eval="$eval FETCH_HEAD"
-       ;;
-esac
-eval "exec $eval"
diff --git a/contrib/examples/git-remote.perl b/contrib/examples/git-remote.perl
deleted file mode 100755 (executable)
index d42df7b..0000000
+++ /dev/null
@@ -1,474 +0,0 @@
-#!/usr/bin/perl -w
-
-use strict;
-use Git;
-my $git = Git->repository();
-
-sub add_remote_config {
-       my ($hash, $name, $what, $value) = @_;
-       if ($what eq 'url') {
-               # Having more than one is Ok -- it is used for push.
-               if (! exists $hash->{'URL'}) {
-                       $hash->{$name}{'URL'} = $value;
-               }
-       }
-       elsif ($what eq 'fetch') {
-               $hash->{$name}{'FETCH'} ||= [];
-               push @{$hash->{$name}{'FETCH'}}, $value;
-       }
-       elsif ($what eq 'push') {
-               $hash->{$name}{'PUSH'} ||= [];
-               push @{$hash->{$name}{'PUSH'}}, $value;
-       }
-       if (!exists $hash->{$name}{'SOURCE'}) {
-               $hash->{$name}{'SOURCE'} = 'config';
-       }
-}
-
-sub add_remote_remotes {
-       my ($hash, $file, $name) = @_;
-
-       if (exists $hash->{$name}) {
-               $hash->{$name}{'WARNING'} = 'ignored due to config';
-               return;
-       }
-
-       my $fh;
-       if (!open($fh, '<', $file)) {
-               print STDERR "Warning: cannot open $file\n";
-               return;
-       }
-       my $it = { 'SOURCE' => 'remotes' };
-       $hash->{$name} = $it;
-       while (<$fh>) {
-               chomp;
-               if (/^URL:\s*(.*)$/) {
-                       # Having more than one is Ok -- it is used for push.
-                       if (! exists $it->{'URL'}) {
-                               $it->{'URL'} = $1;
-                       }
-               }
-               elsif (/^Push:\s*(.*)$/) {
-                       $it->{'PUSH'} ||= [];
-                       push @{$it->{'PUSH'}}, $1;
-               }
-               elsif (/^Pull:\s*(.*)$/) {
-                       $it->{'FETCH'} ||= [];
-                       push @{$it->{'FETCH'}}, $1;
-               }
-               elsif (/^\#/) {
-                       ; # ignore
-               }
-               else {
-                       print STDERR "Warning: funny line in $file: $_\n";
-               }
-       }
-       close($fh);
-}
-
-sub list_remote {
-       my ($git) = @_;
-       my %seen = ();
-       my @remotes = eval {
-               $git->command(qw(config --get-regexp), '^remote\.');
-       };
-       for (@remotes) {
-               if (/^remote\.(\S+?)\.([^.\s]+)\s+(.*)$/) {
-                       add_remote_config(\%seen, $1, $2, $3);
-               }
-       }
-
-       my $dir = $git->repo_path() . "/remotes";
-       if (opendir(my $dh, $dir)) {
-               local $_;
-               while ($_ = readdir($dh)) {
-                       chomp;
-                       next if (! -f "$dir/$_" || ! -r _);
-                       add_remote_remotes(\%seen, "$dir/$_", $_);
-               }
-       }
-
-       return \%seen;
-}
-
-sub add_branch_config {
-       my ($hash, $name, $what, $value) = @_;
-       if ($what eq 'remote') {
-               if (exists $hash->{$name}{'REMOTE'}) {
-                       print STDERR "Warning: more than one branch.$name.remote\n";
-               }
-               $hash->{$name}{'REMOTE'} = $value;
-       }
-       elsif ($what eq 'merge') {
-               $hash->{$name}{'MERGE'} ||= [];
-               push @{$hash->{$name}{'MERGE'}}, $value;
-       }
-}
-
-sub list_branch {
-       my ($git) = @_;
-       my %seen = ();
-       my @branches = eval {
-               $git->command(qw(config --get-regexp), '^branch\.');
-       };
-       for (@branches) {
-               if (/^branch\.([^.]*)\.(\S*)\s+(.*)$/) {
-                       add_branch_config(\%seen, $1, $2, $3);
-               }
-       }
-
-       return \%seen;
-}
-
-my $remote = list_remote($git);
-my $branch = list_branch($git);
-
-sub update_ls_remote {
-       my ($harder, $info) = @_;
-
-       return if (($harder == 0) ||
-                  (($harder == 1) && exists $info->{'LS_REMOTE'}));
-
-       my @ref = map { s|refs/heads/||; $_; } keys %{$git->remote_refs($info->{'URL'}, [ 'heads' ])};
-       $info->{'LS_REMOTE'} = \@ref;
-}
-
-sub list_wildcard_mapping {
-       my ($forced, $ours, $ls) = @_;
-       my %refs;
-       for (@$ls) {
-               $refs{$_} = 01; # bit #0 to say "they have"
-       }
-       for ($git->command('for-each-ref', "refs/remotes/$ours")) {
-               chomp;
-               next unless (s|^[0-9a-f]{40}\s[a-z]+\srefs/remotes/$ours/||);
-               next if ($_ eq 'HEAD');
-               $refs{$_} ||= 0;
-               $refs{$_} |= 02; # bit #1 to say "we have"
-       }
-       my (@new, @stale, @tracked);
-       for (sort keys %refs) {
-               my $have = $refs{$_};
-               if ($have == 1) {
-                       push @new, $_;
-               }
-               elsif ($have == 2) {
-                       push @stale, $_;
-               }
-               elsif ($have == 3) {
-                       push @tracked, $_;
-               }
-       }
-       return \@new, \@stale, \@tracked;
-}
-
-sub list_mapping {
-       my ($name, $info) = @_;
-       my $fetch = $info->{'FETCH'};
-       my $ls = $info->{'LS_REMOTE'};
-       my (@new, @stale, @tracked);
-
-       for (@$fetch) {
-               next unless (/(\+)?([^:]+):(.*)/);
-               my ($forced, $theirs, $ours) = ($1, $2, $3);
-               if ($theirs eq 'refs/heads/*' &&
-                   $ours =~ /^refs\/remotes\/(.*)\/\*$/) {
-                       # wildcard mapping
-                       my ($w_new, $w_stale, $w_tracked)
-                               = list_wildcard_mapping($forced, $1, $ls);
-                       push @new, @$w_new;
-                       push @stale, @$w_stale;
-                       push @tracked, @$w_tracked;
-               }
-               elsif ($theirs =~ /\*/ || $ours =~ /\*/) {
-                       print STDERR "Warning: unrecognized mapping in remotes.$name.fetch: $_\n";
-               }
-               elsif ($theirs =~ s|^refs/heads/||) {
-                       if (!grep { $_ eq $theirs } @$ls) {
-                               push @stale, $theirs;
-                       }
-                       elsif ($ours ne '') {
-                               push @tracked, $theirs;
-                       }
-               }
-       }
-       return \@new, \@stale, \@tracked;
-}
-
-sub show_mapping {
-       my ($name, $info) = @_;
-       my ($new, $stale, $tracked) = list_mapping($name, $info);
-       if (@$new) {
-               print "  New remote branches (next fetch will store in remotes/$name)\n";
-               print "    @$new\n";
-       }
-       if (@$stale) {
-               print "  Stale tracking branches in remotes/$name (use 'git remote prune')\n";
-               print "    @$stale\n";
-       }
-       if (@$tracked) {
-               print "  Tracked remote branches\n";
-               print "    @$tracked\n";
-       }
-}
-
-sub prune_remote {
-       my ($name, $ls_remote) = @_;
-       if (!exists $remote->{$name}) {
-               print STDERR "No such remote $name\n";
-               return 1;
-       }
-       my $info = $remote->{$name};
-       update_ls_remote($ls_remote, $info);
-
-       my ($new, $stale, $tracked) = list_mapping($name, $info);
-       my $prefix = "refs/remotes/$name";
-       foreach my $to_prune (@$stale) {
-               my @v = $git->command(qw(rev-parse --verify), "$prefix/$to_prune");
-               $git->command(qw(update-ref -d), "$prefix/$to_prune", $v[0]);
-       }
-       return 0;
-}
-
-sub show_remote {
-       my ($name, $ls_remote) = @_;
-       if (!exists $remote->{$name}) {
-               print STDERR "No such remote $name\n";
-               return 1;
-       }
-       my $info = $remote->{$name};
-       update_ls_remote($ls_remote, $info);
-
-       print "* remote $name\n";
-       print "  URL: $info->{'URL'}\n";
-       for my $branchname (sort keys %$branch) {
-               next unless (defined $branch->{$branchname}{'REMOTE'} &&
-                            $branch->{$branchname}{'REMOTE'} eq $name);
-               my @merged = map {
-                       s|^refs/heads/||;
-                       $_;
-               } split(' ',"@{$branch->{$branchname}{'MERGE'}}");
-               next unless (@merged);
-               print "  Remote branch(es) merged with 'git pull' while on branch $branchname\n";
-               print "    @merged\n";
-       }
-       if ($info->{'LS_REMOTE'}) {
-               show_mapping($name, $info);
-       }
-       if ($info->{'PUSH'}) {
-               my @pushed = map {
-                       s|^refs/heads/||;
-                       s|^\+refs/heads/|+|;
-                       s|:refs/heads/|:|;
-                       $_;
-               } @{$info->{'PUSH'}};
-               print "  Local branch(es) pushed with 'git push'\n";
-               print "    @pushed\n";
-       }
-       return 0;
-}
-
-sub add_remote {
-       my ($name, $url, $opts) = @_;
-       if (exists $remote->{$name}) {
-               print STDERR "remote $name already exists.\n";
-               exit(1);
-       }
-       $git->command('config', "remote.$name.url", $url);
-       my $track = $opts->{'track'} || ["*"];
-
-       for (@$track) {
-               $git->command('config', '--add', "remote.$name.fetch",
-                               $opts->{'mirror'} ?
-                               "+refs/$_:refs/$_" :
-                               "+refs/heads/$_:refs/remotes/$name/$_");
-       }
-       if ($opts->{'fetch'}) {
-               $git->command('fetch', $name);
-       }
-       if (exists $opts->{'master'}) {
-               $git->command('symbolic-ref', "refs/remotes/$name/HEAD",
-                             "refs/remotes/$name/$opts->{'master'}");
-       }
-}
-
-sub update_remote {
-       my ($name) = @_;
-       my @remotes;
-
-        my $conf = $git->config("remotes." . $name);
-       if (defined($conf)) {
-               @remotes = split(' ', $conf);
-       } elsif ($name eq 'default') {
-               @remotes = ();
-               for (sort keys %$remote) {
-                       my $do_fetch = $git->config_bool("remote." . $_ .
-                                                   ".skipDefaultUpdate");
-                       unless ($do_fetch) {
-                               push @remotes, $_;
-                       }
-               }
-       } else {
-               print STDERR "Remote group $name does not exist.\n";
-               exit(1);
-       }
-       for (@remotes) {
-               print "Updating $_\n";
-               $git->command('fetch', "$_");
-       }
-}
-
-sub rm_remote {
-       my ($name) = @_;
-       if (!exists $remote->{$name}) {
-               print STDERR "No such remote $name\n";
-               return 1;
-       }
-
-       $git->command('config', '--remove-section', "remote.$name");
-
-       eval {
-           my @trackers = $git->command('config', '--get-regexp',
-                       'branch.*.remote', $name);
-               for (@trackers) {
-                       /^branch\.(.*)?\.remote/;
-                       $git->config('--unset', "branch.$1.remote");
-                       $git->config('--unset', "branch.$1.merge");
-               }
-       };
-
-       my @refs = $git->command('for-each-ref',
-               '--format=%(refname) %(objectname)', "refs/remotes/$name");
-       for (@refs) {
-               my ($ref, $object) = split;
-               $git->command(qw(update-ref -d), $ref, $object);
-       }
-       return 0;
-}
-
-sub add_usage {
-       print STDERR "usage: git remote add [-f] [-t track]* [-m master] <name> <url>\n";
-       exit(1);
-}
-
-my $VERBOSE = 0;
-@ARGV = grep {
-       if ($_ eq '-v' or $_ eq '--verbose') {
-               $VERBOSE=1;
-               0
-       } else {
-               1
-       }
-} @ARGV;
-
-if (!@ARGV) {
-       for (sort keys %$remote) {
-               print "$_";
-               print "\t$remote->{$_}->{URL}" if $VERBOSE;
-               print "\n";
-       }
-}
-elsif ($ARGV[0] eq 'show') {
-       my $ls_remote = 1;
-       my $i;
-       for ($i = 1; $i < @ARGV; $i++) {
-               if ($ARGV[$i] eq '-n') {
-                       $ls_remote = 0;
-               }
-               else {
-                       last;
-               }
-       }
-       if ($i >= @ARGV) {
-               print STDERR "usage: git remote show <remote>\n";
-               exit(1);
-       }
-       my $status = 0;
-       for (; $i < @ARGV; $i++) {
-               $status |= show_remote($ARGV[$i], $ls_remote);
-       }
-       exit($status);
-}
-elsif ($ARGV[0] eq 'update') {
-       if (@ARGV <= 1) {
-               update_remote("default");
-               exit(1);
-       }
-       for (my $i = 1; $i < @ARGV; $i++) {
-               update_remote($ARGV[$i]);
-       }
-}
-elsif ($ARGV[0] eq 'prune') {
-       my $ls_remote = 1;
-       my $i;
-       for ($i = 1; $i < @ARGV; $i++) {
-               if ($ARGV[$i] eq '-n') {
-                       $ls_remote = 0;
-               }
-               else {
-                       last;
-               }
-       }
-       if ($i >= @ARGV) {
-               print STDERR "usage: git remote prune <remote>\n";
-               exit(1);
-       }
-       my $status = 0;
-       for (; $i < @ARGV; $i++) {
-               $status |= prune_remote($ARGV[$i], $ls_remote);
-       }
-        exit($status);
-}
-elsif ($ARGV[0] eq 'add') {
-       my %opts = ();
-       while (1 < @ARGV && $ARGV[1] =~ /^-/) {
-               my $opt = $ARGV[1];
-               shift @ARGV;
-               if ($opt eq '-f' || $opt eq '--fetch') {
-                       $opts{'fetch'} = 1;
-                       next;
-               }
-               if ($opt eq '-t' || $opt eq '--track') {
-                       if (@ARGV < 1) {
-                               add_usage();
-                       }
-                       $opts{'track'} ||= [];
-                       push @{$opts{'track'}}, $ARGV[1];
-                       shift @ARGV;
-                       next;
-               }
-               if ($opt eq '-m' || $opt eq '--master') {
-                       if ((@ARGV < 1) || exists $opts{'master'}) {
-                               add_usage();
-                       }
-                       $opts{'master'} = $ARGV[1];
-                       shift @ARGV;
-                       next;
-               }
-               if ($opt eq '--mirror') {
-                       $opts{'mirror'} = 1;
-                       next;
-               }
-               add_usage();
-       }
-       if (@ARGV != 3) {
-               add_usage();
-       }
-       add_remote($ARGV[1], $ARGV[2], \%opts);
-}
-elsif ($ARGV[0] eq 'rm') {
-       if (@ARGV <= 1) {
-               print STDERR "usage: git remote rm <remote>\n";
-               exit(1);
-       }
-       exit(rm_remote($ARGV[1]));
-}
-else {
-       print STDERR "usage: git remote\n";
-       print STDERR "       git remote add <name> <url>\n";
-       print STDERR "       git remote rm <name>\n";
-       print STDERR "       git remote show <name>\n";
-       print STDERR "       git remote prune <name>\n";
-       print STDERR "       git remote update [group]\n";
-       exit(1);
-}
diff --git a/contrib/examples/git-repack.sh b/contrib/examples/git-repack.sh
deleted file mode 100755 (executable)
index 672af93..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005 Linus Torvalds
-#
-
-OPTIONS_KEEPDASHDASH=
-OPTIONS_SPEC="\
-git repack [options]
---
-a               pack everything in a single pack
-A               same as -a, and turn unreachable objects loose
-d               remove redundant packs, and run git-prune-packed
-f               pass --no-reuse-delta to git-pack-objects
-F               pass --no-reuse-object to git-pack-objects
-n               do not run git-update-server-info
-q,quiet         be quiet
-l               pass --local to git-pack-objects
-unpack-unreachable=  with -A, do not loosen objects older than this
- Packing constraints
-window=         size of the window used for delta compression
-window-memory=  same as the above, but limit memory size instead of entries count
-depth=          limits the maximum delta depth
-max-pack-size=  maximum size of each packfile
-"
-SUBDIRECTORY_OK='Yes'
-. git-sh-setup
-
-no_update_info= all_into_one= remove_redundant= unpack_unreachable=
-local= no_reuse= extra=
-while test $# != 0
-do
-       case "$1" in
-       -n)     no_update_info=t ;;
-       -a)     all_into_one=t ;;
-       -A)     all_into_one=t
-               unpack_unreachable=--unpack-unreachable ;;
-       --unpack-unreachable)
-               unpack_unreachable="--unpack-unreachable=$2"; shift ;;
-       -d)     remove_redundant=t ;;
-       -q)     GIT_QUIET=t ;;
-       -f)     no_reuse=--no-reuse-delta ;;
-       -F)     no_reuse=--no-reuse-object ;;
-       -l)     local=--local ;;
-       --max-pack-size|--window|--window-memory|--depth)
-               extra="$extra $1=$2"; shift ;;
-       --) shift; break;;
-       *)      usage ;;
-       esac
-       shift
-done
-
-case "$(git config --bool repack.usedeltabaseoffset || echo true)" in
-true)
-       extra="$extra --delta-base-offset" ;;
-esac
-
-PACKDIR="$GIT_OBJECT_DIRECTORY/pack"
-PACKTMP="$PACKDIR/.tmp-$$-pack"
-rm -f "$PACKTMP"-*
-trap 'rm -f "$PACKTMP"-*' 0 1 2 3 15
-
-# There will be more repacking strategies to come...
-case ",$all_into_one," in
-,,)
-       args='--unpacked --incremental'
-       ;;
-,t,)
-       args= existing=
-       if [ -d "$PACKDIR" ]; then
-               for e in $(cd "$PACKDIR" && find . -type f -name '*.pack' \
-                       | sed -e 's/^\.\///' -e 's/\.pack$//')
-               do
-                       if [ -e "$PACKDIR/$e.keep" ]; then
-                               : keep
-                       else
-                               existing="$existing $e"
-                       fi
-               done
-               if test -n "$existing" && test -n "$unpack_unreachable" && \
-                       test -n "$remove_redundant"
-               then
-                       # This may have arbitrary user arguments, so we
-                       # have to protect it against whitespace splitting
-                       # when it gets run as "pack-objects $args" later.
-                       # Fortunately, we know it's an approxidate, so we
-                       # can just use dots instead.
-                       args="$args $(echo "$unpack_unreachable" | tr ' ' .)"
-               fi
-       fi
-       ;;
-esac
-
-mkdir -p "$PACKDIR" || exit
-
-args="$args $local ${GIT_QUIET:+-q} $no_reuse$extra"
-names=$(git pack-objects --keep-true-parents --honor-pack-keep --non-empty --all --reflog $args </dev/null "$PACKTMP") ||
-       exit 1
-if [ -z "$names" ]; then
-       say Nothing new to pack.
-fi
-
-# Ok we have prepared all new packfiles.
-
-# First see if there are packs of the same name and if so
-# if we can move them out of the way (this can happen if we
-# repacked immediately after packing fully.
-rollback=
-failed=
-for name in $names
-do
-       for sfx in pack idx
-       do
-               file=pack-$name.$sfx
-               test -f "$PACKDIR/$file" || continue
-               rm -f "$PACKDIR/old-$file" &&
-               mv "$PACKDIR/$file" "$PACKDIR/old-$file" || {
-                       failed=t
-                       break
-               }
-               rollback="$rollback $file"
-       done
-       test -z "$failed" || break
-done
-
-# If renaming failed for any of them, roll the ones we have
-# already renamed back to their original names.
-if test -n "$failed"
-then
-       rollback_failure=
-       for file in $rollback
-       do
-               mv "$PACKDIR/old-$file" "$PACKDIR/$file" ||
-               rollback_failure="$rollback_failure $file"
-       done
-       if test -n "$rollback_failure"
-       then
-               echo >&2 "WARNING: Some packs in use have been renamed by"
-               echo >&2 "WARNING: prefixing old- to their name, in order to"
-               echo >&2 "WARNING: replace them with the new version of the"
-               echo >&2 "WARNING: file.  But the operation failed, and"
-               echo >&2 "WARNING: attempt to rename them back to their"
-               echo >&2 "WARNING: original names also failed."
-               echo >&2 "WARNING: Please rename them in $PACKDIR manually:"
-               for file in $rollback_failure
-               do
-                       echo >&2 "WARNING:   old-$file -> $file"
-               done
-       fi
-       exit 1
-fi
-
-# Now the ones with the same name are out of the way...
-fullbases=
-for name in $names
-do
-       fullbases="$fullbases pack-$name"
-       chmod a-w "$PACKTMP-$name.pack"
-       chmod a-w "$PACKTMP-$name.idx"
-       mv -f "$PACKTMP-$name.pack" "$PACKDIR/pack-$name.pack" &&
-       mv -f "$PACKTMP-$name.idx"  "$PACKDIR/pack-$name.idx" ||
-       exit
-done
-
-# Remove the "old-" files
-for name in $names
-do
-       rm -f "$PACKDIR/old-pack-$name.idx"
-       rm -f "$PACKDIR/old-pack-$name.pack"
-done
-
-# End of pack replacement.
-
-if test "$remove_redundant" = t
-then
-       # We know $existing are all redundant.
-       if [ -n "$existing" ]
-       then
-               ( cd "$PACKDIR" &&
-                 for e in $existing
-                 do
-                       case " $fullbases " in
-                       *" $e "*) ;;
-                       *)      rm -f "$e.pack" "$e.idx" "$e.keep" ;;
-                       esac
-                 done
-               )
-       fi
-       git prune-packed ${GIT_QUIET:+-q}
-fi
-
-case "$no_update_info" in
-t) : ;;
-*) git update-server-info ;;
-esac
diff --git a/contrib/examples/git-rerere.perl b/contrib/examples/git-rerere.perl
deleted file mode 100755 (executable)
index 4f69209..0000000
+++ /dev/null
@@ -1,284 +0,0 @@
-#!/usr/bin/perl
-#
-# REuse REcorded REsolve.  This tool records a conflicted automerge
-# result and its hand resolution, and helps to resolve future
-# automerge that results in the same conflict.
-#
-# To enable this feature, create a directory 'rr-cache' under your
-# .git/ directory.
-
-use Digest;
-use File::Path;
-use File::Copy;
-
-my $git_dir = $::ENV{GIT_DIR} || ".git";
-my $rr_dir = "$git_dir/rr-cache";
-my $merge_rr = "$git_dir/rr-cache/MERGE_RR";
-
-my %merge_rr = ();
-
-sub read_rr {
-       if (!-f $merge_rr) {
-               %merge_rr = ();
-               return;
-       }
-       my $in;
-       local $/ = "\0";
-       open $in, "<$merge_rr" or die "$!: $merge_rr";
-       while (<$in>) {
-               chomp;
-               my ($name, $path) = /^([0-9a-f]{40})\t(.*)$/s;
-               $merge_rr{$path} = $name;
-       }
-       close $in;
-}
-
-sub write_rr {
-       my $out;
-       open $out, ">$merge_rr" or die "$!: $merge_rr";
-       for my $path (sort keys %merge_rr) {
-               my $name = $merge_rr{$path};
-               print $out "$name\t$path\0";
-       }
-       close $out;
-}
-
-sub compute_conflict_name {
-       my ($path) = @_;
-       my @side = ();
-       my $in;
-       open $in, "<$path"  or die "$!: $path";
-
-       my $sha1 = Digest->new("SHA-1");
-       my $hunk = 0;
-       while (<$in>) {
-               if (/^<<<<<<< .*/) {
-                       $hunk++;
-                       @side = ([], undef);
-               }
-               elsif (/^=======$/) {
-                       $side[1] = [];
-               }
-               elsif (/^>>>>>>> .*/) {
-                       my ($one, $two);
-                       $one = join('', @{$side[0]});
-                       $two = join('', @{$side[1]});
-                       if ($two le $one) {
-                               ($one, $two) = ($two, $one);
-                       }
-                       $sha1->add($one);
-                       $sha1->add("\0");
-                       $sha1->add($two);
-                       $sha1->add("\0");
-                       @side = ();
-               }
-               elsif (@side == 0) {
-                       next;
-               }
-               elsif (defined $side[1]) {
-                       push @{$side[1]}, $_;
-               }
-               else {
-                       push @{$side[0]}, $_;
-               }
-       }
-       close $in;
-       return ($sha1->hexdigest, $hunk);
-}
-
-sub record_preimage {
-       my ($path, $name) = @_;
-       my @side = ();
-       my ($in, $out);
-       open $in, "<$path"  or die "$!: $path";
-       open $out, ">$name" or die "$!: $name";
-
-       while (<$in>) {
-               if (/^<<<<<<< .*/) {
-                       @side = ([], undef);
-               }
-               elsif (/^=======$/) {
-                       $side[1] = [];
-               }
-               elsif (/^>>>>>>> .*/) {
-                       my ($one, $two);
-                       $one = join('', @{$side[0]});
-                       $two = join('', @{$side[1]});
-                       if ($two le $one) {
-                               ($one, $two) = ($two, $one);
-                       }
-                       print $out "<<<<<<<\n";
-                       print $out $one;
-                       print $out "=======\n";
-                       print $out $two;
-                       print $out ">>>>>>>\n";
-                       @side = ();
-               }
-               elsif (@side == 0) {
-                       print $out $_;
-               }
-               elsif (defined $side[1]) {
-                       push @{$side[1]}, $_;
-               }
-               else {
-                       push @{$side[0]}, $_;
-               }
-       }
-       close $out;
-       close $in;
-}
-
-sub find_conflict {
-       my $in;
-       local $/ = "\0";
-       my $pid = open($in, '-|');
-       die "$!" unless defined $pid;
-       if (!$pid) {
-               exec(qw(git ls-files -z -u)) or die "$!: ls-files";
-       }
-       my %path = ();
-       my @path = ();
-       while (<$in>) {
-               chomp;
-               my ($mode, $sha1, $stage, $path) =
-                   /^([0-7]+) ([0-9a-f]{40}) ([123])\t(.*)$/s;
-               $path{$path} |= (1 << $stage);
-       }
-       close $in;
-       while (my ($path, $status) = each %path) {
-               if ($status == 14) { push @path, $path; }
-       }
-       return @path;
-}
-
-sub merge {
-       my ($name, $path) = @_;
-       record_preimage($path, "$rr_dir/$name/thisimage");
-       unless (system('git', 'merge-file', map { "$rr_dir/$name/${_}image" }
-                      qw(this pre post))) {
-               my $in;
-               open $in, "<$rr_dir/$name/thisimage" or
-                   die "$!: $name/thisimage";
-               my $out;
-               open $out, ">$path" or die "$!: $path";
-               while (<$in>) { print $out $_; }
-               close $in;
-               close $out;
-               return 1;
-       }
-       return 0;
-}
-
-sub garbage_collect_rerere {
-       # We should allow specifying these from the command line and
-       # that is why the caller gives @ARGV to us, but I am lazy.
-
-       my $cutoff_noresolve = 15; # two weeks
-       my $cutoff_resolve = 60; # two months
-       my @to_remove;
-       while (<$rr_dir/*/preimage>) {
-               my ($dir) = /^(.*)\/preimage$/;
-               my $cutoff = ((-f "$dir/postimage")
-                             ? $cutoff_resolve
-                             : $cutoff_noresolve);
-               my $age = -M "$_";
-               if ($cutoff <= $age) {
-                       push @to_remove, $dir;
-               }
-       }
-       if (@to_remove) {
-               rmtree(\@to_remove);
-       }
-}
-
--d "$rr_dir" || exit(0);
-
-read_rr();
-
-if (@ARGV) {
-       my $arg = shift @ARGV;
-       if ($arg eq 'clear') {
-               for my $path (keys %merge_rr) {
-                       my $name = $merge_rr{$path};
-                       if (-d "$rr_dir/$name" &&
-                           ! -f "$rr_dir/$name/postimage") {
-                               rmtree(["$rr_dir/$name"]);
-                       }
-               }
-               unlink $merge_rr;
-       }
-       elsif ($arg eq 'status') {
-               for my $path (keys %merge_rr) {
-                       print $path, "\n";
-               }
-       }
-       elsif ($arg eq 'diff') {
-               for my $path (keys %merge_rr) {
-                       my $name = $merge_rr{$path};
-                       system('diff', ((@ARGV == 0) ? ('-u') : @ARGV),
-                               '-L', "a/$path", '-L', "b/$path",
-                               "$rr_dir/$name/preimage", $path);
-               }
-       }
-       elsif ($arg eq 'gc') {
-               garbage_collect_rerere(@ARGV);
-       }
-       else {
-               die "$0 unknown command: $arg\n";
-       }
-       exit 0;
-}
-
-my %conflict = map { $_ => 1 } find_conflict();
-
-# MERGE_RR records paths with conflicts immediately after merge
-# failed.  Some of the conflicted paths might have been hand resolved
-# in the working tree since then, but the initial run would catch all
-# and register their preimages.
-
-for my $path (keys %conflict) {
-       # This path has conflict.  If it is not recorded yet,
-       # record the pre-image.
-       if (!exists $merge_rr{$path}) {
-               my ($name, $hunk) = compute_conflict_name($path);
-               next unless ($hunk);
-               $merge_rr{$path} = $name;
-               if (! -d "$rr_dir/$name") {
-                       mkpath("$rr_dir/$name", 0, 0777);
-                       print STDERR "Recorded preimage for '$path'\n";
-                       record_preimage($path, "$rr_dir/$name/preimage");
-               }
-       }
-}
-
-# Now some of the paths that had conflicts earlier might have been
-# hand resolved.  Others may be similar to a conflict already that
-# was resolved before.
-
-for my $path (keys %merge_rr) {
-       my $name = $merge_rr{$path};
-
-       # We could resolve this automatically if we have images.
-       if (-f "$rr_dir/$name/preimage" &&
-           -f "$rr_dir/$name/postimage") {
-               if (merge($name, $path)) {
-                       print STDERR "Resolved '$path' using previous resolution.\n";
-                       # Then we do not have to worry about this path
-                       # anymore.
-                       delete $merge_rr{$path};
-                       next;
-               }
-       }
-
-       # Let's see if we have resolved it.
-       (undef, my $hunk) = compute_conflict_name($path);
-       next if ($hunk);
-
-       print STDERR "Recorded resolution for '$path'.\n";
-       copy($path, "$rr_dir/$name/postimage");
-       # And we do not have to worry about this path anymore.
-       delete $merge_rr{$path};
-}
-
-# Write out the rest.
-write_rr();
diff --git a/contrib/examples/git-reset.sh b/contrib/examples/git-reset.sh
deleted file mode 100755 (executable)
index cb1bbf3..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005, 2006 Linus Torvalds and Junio C Hamano
-#
-USAGE='[--mixed | --soft | --hard]  [<commit-ish>] [ [--] <paths>...]'
-SUBDIRECTORY_OK=Yes
-. git-sh-setup
-set_reflog_action "reset $*"
-require_work_tree
-
-update= reset_type=--mixed
-unset rev
-
-while test $# != 0
-do
-       case "$1" in
-       --mixed | --soft | --hard)
-               reset_type="$1"
-               ;;
-       --)
-               break
-               ;;
-       -*)
-               usage
-               ;;
-       *)
-               rev=$(git rev-parse --verify "$1") || exit
-               shift
-               break
-               ;;
-       esac
-       shift
-done
-
-: ${rev=HEAD}
-rev=$(git rev-parse --verify $rev^0) || exit
-
-# Skip -- in "git reset HEAD -- foo" and "git reset -- foo".
-case "$1" in --) shift ;; esac
-
-# git reset --mixed tree [--] paths... can be used to
-# load chosen paths from the tree into the index without
-# affecting the working tree or HEAD.
-if test $# != 0
-then
-       test "$reset_type" = "--mixed" ||
-               die "Cannot do partial $reset_type reset."
-
-       git diff-index --cached $rev -- "$@" |
-       sed -e 's/^:\([0-7][0-7]*\) [0-7][0-7]* \([0-9a-f][0-9a-f]*\) [0-9a-f][0-9a-f]* [A-Z]   \(.*\)$/\1 \2   \3/' |
-       git update-index --add --remove --index-info || exit
-       git update-index --refresh
-       exit
-fi
-
-cd_to_toplevel
-
-if test "$reset_type" = "--hard"
-then
-       update=-u
-fi
-
-# Soft reset does not touch the index file or the working tree
-# at all, but requires them in a good order.  Other resets reset
-# the index file to the tree object we are switching to.
-if test "$reset_type" = "--soft"
-then
-       if test -f "$GIT_DIR/MERGE_HEAD" ||
-          test "" != "$(git ls-files --unmerged)"
-       then
-               die "Cannot do a soft reset in the middle of a merge."
-       fi
-else
-       git read-tree -v --reset $update "$rev" || exit
-fi
-
-# Any resets update HEAD to the head being switched to.
-if orig=$(git rev-parse --verify HEAD 2>/dev/null)
-then
-       echo "$orig" >"$GIT_DIR/ORIG_HEAD"
-else
-       rm -f "$GIT_DIR/ORIG_HEAD"
-fi
-git update-ref -m "$GIT_REFLOG_ACTION" HEAD "$rev"
-update_ref_status=$?
-
-case "$reset_type" in
---hard )
-       test $update_ref_status = 0 && {
-               printf "HEAD is now at "
-               GIT_PAGER= git log --max-count=1 --pretty=oneline \
-                       --abbrev-commit HEAD
-       }
-       ;;
---soft )
-       ;; # Nothing else to do
---mixed )
-       # Report what has not been updated.
-       git update-index --refresh
-       ;;
-esac
-
-rm -f "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/rr-cache/MERGE_RR" \
-       "$GIT_DIR/SQUASH_MSG" "$GIT_DIR/MERGE_MSG"
-
-exit $update_ref_status
diff --git a/contrib/examples/git-resolve.sh b/contrib/examples/git-resolve.sh
deleted file mode 100755 (executable)
index 3099dc8..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005 Linus Torvalds
-#
-# Resolve two trees.
-#
-
-echo 'WARNING: This command is DEPRECATED and will be removed very soon.' >&2
-echo 'WARNING: Please use git-merge or git-pull instead.' >&2
-sleep 2
-
-USAGE='<head> <remote> <merge-message>'
-. git-sh-setup
-
-dropheads() {
-       rm -f -- "$GIT_DIR/MERGE_HEAD" \
-               "$GIT_DIR/LAST_MERGE" || exit 1
-}
-
-head=$(git rev-parse --verify "$1"^0) &&
-merge=$(git rev-parse --verify "$2"^0) &&
-merge_name="$2" &&
-merge_msg="$3" || usage
-
-#
-# The remote name is just used for the message,
-# but we do want it.
-#
-if [ -z "$head" -o -z "$merge" -o -z "$merge_msg" ]; then
-       usage
-fi
-
-dropheads
-echo $head > "$GIT_DIR"/ORIG_HEAD
-echo $merge > "$GIT_DIR"/LAST_MERGE
-
-common=$(git merge-base $head $merge)
-if [ -z "$common" ]; then
-       die "Unable to find common commit between" $merge $head
-fi
-
-case "$common" in
-"$merge")
-       echo "Already up to date. Yeeah!"
-       dropheads
-       exit 0
-       ;;
-"$head")
-       echo "Updating $(git rev-parse --short $head)..$(git rev-parse --short $merge)"
-       git read-tree -u -m $head $merge || exit 1
-       git update-ref -m "resolve $merge_name: Fast-forward" \
-               HEAD "$merge" "$head"
-       git diff-tree -p $head $merge | git apply --stat
-       dropheads
-       exit 0
-       ;;
-esac
-
-# We are going to make a new commit.
-git var GIT_COMMITTER_IDENT >/dev/null || exit
-
-# Find an optimum merge base if there are more than one candidates.
-LF='
-'
-common=$(git merge-base -a $head $merge)
-case "$common" in
-?*"$LF"?*)
-       echo "Trying to find the optimum merge base."
-       G=.tmp-index$$
-       best=
-       best_cnt=-1
-       for c in $common
-       do
-               rm -f $G
-               GIT_INDEX_FILE=$G git read-tree -m $c $head $merge \
-                       2>/dev/null || continue
-               # Count the paths that are unmerged.
-               cnt=$(GIT_INDEX_FILE=$G git ls-files --unmerged | wc -l)
-               if test $best_cnt -le 0 || test $cnt -le $best_cnt
-               then
-                       best=$c
-                       best_cnt=$cnt
-                       if test "$best_cnt" -eq 0
-                       then
-                               # Cannot do any better than all trivial merge.
-                               break
-                       fi
-               fi
-       done
-       rm -f $G
-       common="$best"
-esac
-
-echo "Trying to merge $merge into $head using $common."
-git update-index --refresh 2>/dev/null
-git read-tree -u -m $common $head $merge || exit 1
-result_tree=$(git write-tree  2> /dev/null)
-if [ $? -ne 0 ]; then
-       echo "Simple merge failed, trying Automatic merge"
-       git-merge-index -o git-merge-one-file -a
-       if [ $? -ne 0 ]; then
-               echo $merge > "$GIT_DIR"/MERGE_HEAD
-               die "Automatic merge failed, fix up by hand"
-       fi
-       result_tree=$(git write-tree) || exit 1
-fi
-result_commit=$(echo "$merge_msg" | git commit-tree $result_tree -p $head -p $merge)
-echo "Committed merge $result_commit"
-git update-ref -m "resolve $merge_name: In-index merge" \
-       HEAD "$result_commit" "$head"
-git diff-tree -p $head $result_commit | git apply --stat
-dropheads
diff --git a/contrib/examples/git-revert.sh b/contrib/examples/git-revert.sh
deleted file mode 100755 (executable)
index 197838d..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005 Linus Torvalds
-# Copyright (c) 2005 Junio C Hamano
-#
-
-case "$0" in
-*-revert* )
-       test -t 0 && edit=-e
-       replay=
-       me=revert
-       USAGE='[--edit | --no-edit] [-n] <commit-ish>' ;;
-*-cherry-pick* )
-       replay=t
-       edit=
-       me=cherry-pick
-       USAGE='[--edit] [-n] [-r] [-x] <commit-ish>'  ;;
-* )
-       echo >&2 "What are you talking about?"
-       exit 1 ;;
-esac
-
-SUBDIRECTORY_OK=Yes ;# we will cd up
-. git-sh-setup
-require_work_tree
-cd_to_toplevel
-
-no_commit=
-xopt=
-while case "$#" in 0) break ;; esac
-do
-       case "$1" in
-       -n|--n|--no|--no-|--no-c|--no-co|--no-com|--no-comm|\
-           --no-commi|--no-commit)
-               no_commit=t
-               ;;
-       -e|--e|--ed|--edi|--edit)
-               edit=-e
-               ;;
-       --n|--no|--no-|--no-e|--no-ed|--no-edi|--no-edit)
-               edit=
-               ;;
-       -r)
-               : no-op ;;
-       -x|--i-really-want-to-expose-my-private-commit-object-name)
-               replay=
-               ;;
-       -X?*)
-               xopt="$xopt$(git rev-parse --sq-quote "--${1#-X}")"
-               ;;
-       --strategy-option=*)
-               xopt="$xopt$(git rev-parse --sq-quote "--${1#--strategy-option=}")"
-               ;;
-       -X|--strategy-option)
-               shift
-               xopt="$xopt$(git rev-parse --sq-quote "--$1")"
-               ;;
-       -*)
-               usage
-               ;;
-       *)
-               break
-               ;;
-       esac
-       shift
-done
-
-set_reflog_action "$me"
-
-test "$me,$replay" = "revert,t" && usage
-
-case "$no_commit" in
-t)
-       # We do not intend to commit immediately.  We just want to
-       # merge the differences in.
-       head=$(git-write-tree) ||
-               die "Your index file is unmerged."
-       ;;
-*)
-       head=$(git-rev-parse --verify HEAD) ||
-               die "You do not have a valid HEAD"
-       files=$(git-diff-index --cached --name-only $head) || exit
-       if [ "$files" ]; then
-               die "Dirty index: cannot $me (dirty: $files)"
-       fi
-       ;;
-esac
-
-rev=$(git-rev-parse --verify "$@") &&
-commit=$(git-rev-parse --verify "$rev^0") ||
-       die "Not a single commit $@"
-prev=$(git-rev-parse --verify "$commit^1" 2>/dev/null) ||
-       die "Cannot run $me a root commit"
-git-rev-parse --verify "$commit^2" >/dev/null 2>&1 &&
-       die "Cannot run $me a multi-parent commit."
-
-encoding=$(git config i18n.commitencoding || echo UTF-8)
-
-# "commit" is an existing commit.  We would want to apply
-# the difference it introduces since its first parent "prev"
-# on top of the current HEAD if we are cherry-pick.  Or the
-# reverse of it if we are revert.
-
-case "$me" in
-revert)
-       git show -s --pretty=oneline --encoding="$encoding" $commit |
-       sed -e '
-               s/^[^ ]* /Revert "/
-               s/$/"/
-       '
-       echo
-       echo "This reverts commit $commit."
-       test "$rev" = "$commit" ||
-       echo "(original 'git revert' arguments: $@)"
-       base=$commit next=$prev
-       ;;
-
-cherry-pick)
-       pick_author_script='
-       /^author /{
-               s/'\''/'\''\\'\'\''/g
-               h
-               s/^author \([^<]*\) <[^>]*> .*$/\1/
-               s/'\''/'\''\'\'\''/g
-               s/.*/GIT_AUTHOR_NAME='\''&'\''/p
-
-               g
-               s/^author [^<]* <\([^>]*\)> .*$/\1/
-               s/'\''/'\''\'\'\''/g
-               s/.*/GIT_AUTHOR_EMAIL='\''&'\''/p
-
-               g
-               s/^author [^<]* <[^>]*> \(.*\)$/\1/
-               s/'\''/'\''\'\'\''/g
-               s/.*/GIT_AUTHOR_DATE='\''&'\''/p
-
-               q
-       }'
-
-       logmsg=$(git show -s --pretty=raw --encoding="$encoding" "$commit")
-       set_author_env=$(echo "$logmsg" |
-       LANG=C LC_ALL=C sed -ne "$pick_author_script")
-       eval "$set_author_env"
-       export GIT_AUTHOR_NAME
-       export GIT_AUTHOR_EMAIL
-       export GIT_AUTHOR_DATE
-
-       echo "$logmsg" |
-       sed -e '1,/^$/d' -e 's/^    //'
-       case "$replay" in
-       '')
-               echo "(cherry picked from commit $commit)"
-               test "$rev" = "$commit" ||
-               echo "(original 'git cherry-pick' arguments: $@)"
-               ;;
-       esac
-       base=$prev next=$commit
-       ;;
-
-esac >.msg
-
-eval GITHEAD_$head=HEAD
-eval GITHEAD_$next='$(git show -s \
-       --pretty=oneline --encoding="$encoding" "$commit" |
-       sed -e "s/^[^ ]* //")'
-export GITHEAD_$head GITHEAD_$next
-
-# This three way merge is an interesting one.  We are at
-# $head, and would want to apply the change between $commit
-# and $prev on top of us (when reverting), or the change between
-# $prev and $commit on top of us (when cherry-picking or replaying).
-
-eval "git merge-recursive $xopt $base -- $head $next" &&
-result=$(git-write-tree 2>/dev/null) || {
-       mv -f .msg "$GIT_DIR/MERGE_MSG"
-       {
-           echo '
-Conflicts:
-'
-               git ls-files --unmerged |
-               sed -e 's/^[^   ]*      /       /' |
-               uniq
-       } >>"$GIT_DIR/MERGE_MSG"
-       echo >&2 "Automatic $me failed.  After resolving the conflicts,"
-       echo >&2 "mark the corrected paths with 'git-add <paths>'"
-       echo >&2 "and commit the result."
-       case "$me" in
-       cherry-pick)
-               echo >&2 "You may choose to use the following when making"
-               echo >&2 "the commit:"
-               echo >&2 "$set_author_env"
-       esac
-       exit 1
-}
-
-# If we are cherry-pick, and if the merge did not result in
-# hand-editing, we will hit this commit and inherit the original
-# author date and name.
-# If we are revert, or if our cherry-pick results in a hand merge,
-# we had better say that the current user is responsible for that.
-
-case "$no_commit" in
-'')
-       git-commit -n -F .msg $edit
-       rm -f .msg
-       ;;
-esac
diff --git a/contrib/examples/git-svnimport.perl b/contrib/examples/git-svnimport.perl
deleted file mode 100755 (executable)
index 75a43e2..0000000
+++ /dev/null
@@ -1,976 +0,0 @@
-#!/usr/bin/perl
-
-# This tool is copyright (c) 2005, Matthias Urlichs.
-# It is released under the Gnu Public License, version 2.
-#
-# The basic idea is to pull and analyze SVN changes.
-#
-# Checking out the files is done by a single long-running SVN connection.
-#
-# The head revision is on branch "origin" by default.
-# You can change that with the '-o' option.
-
-use strict;
-use warnings;
-use Getopt::Std;
-use File::Copy;
-use File::Spec;
-use File::Temp qw(tempfile);
-use File::Path qw(mkpath);
-use File::Basename qw(basename dirname);
-use Time::Local;
-use IO::Pipe;
-use POSIX qw(strftime dup2);
-use IPC::Open2;
-use SVN::Core;
-use SVN::Ra;
-
-die "Need SVN:Core 1.2.1 or better" if $SVN::Core::VERSION lt "1.2.1";
-
-$SIG{'PIPE'}="IGNORE";
-$ENV{'TZ'}="UTC";
-
-our($opt_h,$opt_o,$opt_v,$opt_u,$opt_C,$opt_i,$opt_m,$opt_M,$opt_t,$opt_T,
-    $opt_b,$opt_r,$opt_I,$opt_A,$opt_s,$opt_l,$opt_d,$opt_D,$opt_S,$opt_F,
-    $opt_P,$opt_R);
-
-sub usage() {
-       print STDERR <<END;
-usage: ${\basename $0}     # fetch/update GIT from SVN
-       [-o branch-for-HEAD] [-h] [-v] [-l max_rev] [-R repack_each_revs]
-       [-C GIT_repository] [-t tagname] [-T trunkname] [-b branchname]
-       [-d|-D] [-i] [-u] [-r] [-I ignorefilename] [-s start_chg]
-       [-m] [-M regex] [-A author_file] [-S] [-F] [-P project_name] [SVN_URL]
-END
-       exit(1);
-}
-
-getopts("A:b:C:dDFhiI:l:mM:o:rs:t:T:SP:R:uv") or usage();
-usage if $opt_h;
-
-my $tag_name = $opt_t || "tags";
-my $trunk_name = defined $opt_T ? $opt_T : "trunk";
-my $branch_name = $opt_b || "branches";
-my $project_name = $opt_P || "";
-$project_name = "/" . $project_name if ($project_name);
-my $repack_after = $opt_R || 1000;
-my $root_pool = SVN::Pool->new_default;
-
-@ARGV == 1 or @ARGV == 2 or usage();
-
-$opt_o ||= "origin";
-$opt_s ||= 1;
-my $git_tree = $opt_C;
-$git_tree ||= ".";
-
-my $svn_url = $ARGV[0];
-my $svn_dir = $ARGV[1];
-
-our @mergerx = ();
-if ($opt_m) {
-       my $branch_esc = quotemeta ($branch_name);
-       my $trunk_esc  = quotemeta ($trunk_name);
-       @mergerx =
-       (
-               qr!\b(?:merg(?:ed?|ing))\b.*?\b((?:(?<=$branch_esc/)[\w\.\-]+)|(?:$trunk_esc))\b!i,
-               qr!\b(?:from|of)\W+((?:(?<=$branch_esc/)[\w\.\-]+)|(?:$trunk_esc))\b!i,
-               qr!\b(?:from|of)\W+(?:the )?([\w\.\-]+)[-\s]branch\b!i
-       );
-}
-if ($opt_M) {
-       unshift (@mergerx, qr/$opt_M/);
-}
-
-# Absolutize filename now, since we will have chdir'ed by the time we
-# get around to opening it.
-$opt_A = File::Spec->rel2abs($opt_A) if $opt_A;
-
-our %users = ();
-our $users_file = undef;
-sub read_users($) {
-       $users_file = File::Spec->rel2abs(@_);
-       die "Cannot open $users_file\n" unless -f $users_file;
-       open(my $authors,$users_file);
-       while(<$authors>) {
-               chomp;
-               next unless /^(\S+?)\s*=\s*(.+?)\s*<(.+)>\s*$/;
-               (my $user,my $name,my $email) = ($1,$2,$3);
-               $users{$user} = [$name,$email];
-       }
-       close($authors);
-}
-
-select(STDERR); $|=1; select(STDOUT);
-
-
-package SVNconn;
-# Basic SVN connection.
-# We're only interested in connecting and downloading, so ...
-
-use File::Spec;
-use File::Temp qw(tempfile);
-use POSIX qw(strftime dup2);
-use Fcntl qw(SEEK_SET);
-
-sub new {
-       my($what,$repo) = @_;
-       $what=ref($what) if ref($what);
-
-       my $self = {};
-       $self->{'buffer'} = "";
-       bless($self,$what);
-
-       $repo =~ s#/+$##;
-       $self->{'fullrep'} = $repo;
-       $self->conn();
-
-       return $self;
-}
-
-sub conn {
-       my $self = shift;
-       my $repo = $self->{'fullrep'};
-       my $auth = SVN::Core::auth_open ([SVN::Client::get_simple_provider,
-                         SVN::Client::get_ssl_server_trust_file_provider,
-                         SVN::Client::get_username_provider]);
-       my $s = SVN::Ra->new(url => $repo, auth => $auth, pool => $root_pool);
-       die "SVN connection to $repo: $!\n" unless defined $s;
-       $self->{'svn'} = $s;
-       $self->{'repo'} = $repo;
-       $self->{'maxrev'} = $s->get_latest_revnum();
-}
-
-sub file {
-       my($self,$path,$rev) = @_;
-
-       my ($fh, $name) = tempfile('gitsvn.XXXXXX',
-                   DIR => File::Spec->tmpdir(), UNLINK => 1);
-
-       print "... $rev $path ...\n" if $opt_v;
-       my (undef, $properties);
-       $path =~ s#^/*##;
-       my $subpool = SVN::Pool::new_default_sub;
-       eval { (undef, $properties)
-                  = $self->{'svn'}->get_file($path,$rev,$fh); };
-       if($@) {
-               return undef if $@ =~ /Attempted to get checksum/;
-               die $@;
-       }
-       my $mode;
-       if (exists $properties->{'svn:executable'}) {
-               $mode = '100755';
-       } elsif (exists $properties->{'svn:special'}) {
-               my ($special_content, $filesize);
-               $filesize = tell $fh;
-               seek $fh, 0, SEEK_SET;
-               read $fh, $special_content, $filesize;
-               if ($special_content =~ s/^link //) {
-                       $mode = '120000';
-                       seek $fh, 0, SEEK_SET;
-                       truncate $fh, 0;
-                       print $fh $special_content;
-               } else {
-                       die "unexpected svn:special file encountered";
-               }
-       } else {
-               $mode = '100644';
-       }
-       close ($fh);
-
-       return ($name, $mode);
-}
-
-sub ignore {
-       my($self,$path,$rev) = @_;
-
-       print "... $rev $path ...\n" if $opt_v;
-       $path =~ s#^/*##;
-       my $subpool = SVN::Pool::new_default_sub;
-       my (undef,undef,$properties)
-           = $self->{'svn'}->get_dir($path,$rev,undef);
-       if (exists $properties->{'svn:ignore'}) {
-               my ($fh, $name) = tempfile('gitsvn.XXXXXX',
-                                          DIR => File::Spec->tmpdir(),
-                                          UNLINK => 1);
-               print $fh $properties->{'svn:ignore'};
-               close($fh);
-               return $name;
-       } else {
-               return undef;
-       }
-}
-
-sub dir_list {
-       my($self,$path,$rev) = @_;
-       $path =~ s#^/*##;
-       my $subpool = SVN::Pool::new_default_sub;
-       my ($dirents,undef,$properties)
-           = $self->{'svn'}->get_dir($path,$rev,undef);
-       return $dirents;
-}
-
-package main;
-use URI;
-
-our $svn = $svn_url;
-$svn .= "/$svn_dir" if defined $svn_dir;
-my $svn2 = SVNconn->new($svn);
-$svn = SVNconn->new($svn);
-
-my $lwp_ua;
-if($opt_d or $opt_D) {
-       $svn_url = URI->new($svn_url)->canonical;
-       if($opt_D) {
-               $svn_dir =~ s#/*$#/#;
-       } else {
-               $svn_dir = "";
-       }
-       if ($svn_url->scheme eq "http") {
-               use LWP::UserAgent;
-               $lwp_ua = LWP::UserAgent->new(keep_alive => 1, requests_redirectable => []);
-       } else {
-               print STDERR "Warning: not HTTP; turning off direct file access\n";
-               $opt_d=0;
-       }
-}
-
-sub pdate($) {
-       my($d) = @_;
-       $d =~ m#(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)#
-               or die "Unparseable date: $d\n";
-       my $y=$1; $y+=1900 if $y<1000;
-       return timegm($6||0,$5,$4,$3,$2-1,$y);
-}
-
-sub getwd() {
-       my $pwd = `pwd`;
-       chomp $pwd;
-       return $pwd;
-}
-
-
-sub get_headref($$) {
-    my $name    = shift;
-    my $git_dir = shift;
-    my $sha;
-
-    if (open(C,"$git_dir/refs/heads/$name")) {
-       chomp($sha = <C>);
-       close(C);
-       length($sha) == 40
-           or die "Cannot get head id for $name ($sha): $!\n";
-    }
-    return $sha;
-}
-
-
--d $git_tree
-       or mkdir($git_tree,0777)
-       or die "Could not create $git_tree: $!";
-chdir($git_tree);
-
-my $orig_branch = "";
-my $forward_master = 0;
-my %branches;
-
-my $git_dir = $ENV{"GIT_DIR"} || ".git";
-$git_dir = getwd()."/".$git_dir unless $git_dir =~ m#^/#;
-$ENV{"GIT_DIR"} = $git_dir;
-my $orig_git_index;
-$orig_git_index = $ENV{GIT_INDEX_FILE} if exists $ENV{GIT_INDEX_FILE};
-my ($git_ih, $git_index) = tempfile('gitXXXXXX', SUFFIX => '.idx',
-                                   DIR => File::Spec->tmpdir());
-close ($git_ih);
-$ENV{GIT_INDEX_FILE} = $git_index;
-my $maxnum = 0;
-my $last_rev = "";
-my $last_branch;
-my $current_rev = $opt_s || 1;
-unless(-d $git_dir) {
-       system("git init");
-       die "Cannot init the GIT db at $git_tree: $?\n" if $?;
-       system("git read-tree --empty");
-       die "Cannot init an empty tree: $?\n" if $?;
-
-       $last_branch = $opt_o;
-       $orig_branch = "";
-} else {
-       -f "$git_dir/refs/heads/$opt_o"
-               or die "Branch '$opt_o' does not exist.\n".
-                      "Either use the correct '-o branch' option,\n".
-                      "or import to a new repository.\n";
-
-       -f "$git_dir/svn2git"
-               or die "'$git_dir/svn2git' does not exist.\n".
-                      "You need that file for incremental imports.\n";
-       open(F, "git symbolic-ref HEAD |") or
-               die "Cannot run git-symbolic-ref: $!\n";
-       chomp ($last_branch = <F>);
-       $last_branch = basename($last_branch);
-       close(F);
-       unless($last_branch) {
-               warn "Cannot read the last branch name: $! -- assuming 'master'\n";
-               $last_branch = "master";
-       }
-       $orig_branch = $last_branch;
-       $last_rev = get_headref($orig_branch, $git_dir);
-       if (-f "$git_dir/SVN2GIT_HEAD") {
-               die <<EOM;
-SVN2GIT_HEAD exists.
-Make sure your working directory corresponds to HEAD and remove SVN2GIT_HEAD.
-You may need to run
-
-    git-read-tree -m -u SVN2GIT_HEAD HEAD
-EOM
-       }
-       system('cp', "$git_dir/HEAD", "$git_dir/SVN2GIT_HEAD");
-
-       $forward_master =
-           $opt_o ne 'master' && -f "$git_dir/refs/heads/master" &&
-           system('cmp', '-s', "$git_dir/refs/heads/master",
-                               "$git_dir/refs/heads/$opt_o") == 0;
-
-       # populate index
-       system('git', 'read-tree', $last_rev);
-       die "read-tree failed: $?\n" if $?;
-
-       # Get the last import timestamps
-       open my $B,"<", "$git_dir/svn2git";
-       while(<$B>) {
-               chomp;
-               my($num,$branch,$ref) = split;
-               $branches{$branch}{$num} = $ref;
-               $branches{$branch}{"LAST"} = $ref;
-               $current_rev = $num+1 if $current_rev <= $num;
-       }
-       close($B);
-}
--d $git_dir
-       or die "Could not create git subdir ($git_dir).\n";
-
-my $default_authors = "$git_dir/svn-authors";
-if ($opt_A) {
-       read_users($opt_A);
-       copy($opt_A,$default_authors) or die "Copy failed: $!";
-} else {
-       read_users($default_authors) if -f $default_authors;
-}
-
-open BRANCHES,">>", "$git_dir/svn2git";
-
-sub node_kind($$) {
-       my ($svnpath, $revision) = @_;
-       $svnpath =~ s#^/*##;
-       my $subpool = SVN::Pool::new_default_sub;
-       my $kind = $svn->{'svn'}->check_path($svnpath,$revision);
-       return $kind;
-}
-
-sub get_file($$$) {
-       my($svnpath,$rev,$path) = @_;
-
-       # now get it
-       my ($name,$mode);
-       if($opt_d) {
-               my($req,$res);
-
-               # /svn/!svn/bc/2/django/trunk/django-docs/build.py
-               my $url=$svn_url->clone();
-               $url->path($url->path."/!svn/bc/$rev/$svn_dir$svnpath");
-               print "... $path...\n" if $opt_v;
-               $req = HTTP::Request->new(GET => $url);
-               $res = $lwp_ua->request($req);
-               if ($res->is_success) {
-                       my $fh;
-                       ($fh, $name) = tempfile('gitsvn.XXXXXX',
-                       DIR => File::Spec->tmpdir(), UNLINK => 1);
-                       print $fh $res->content;
-                       close($fh) or die "Could not write $name: $!\n";
-               } else {
-                       return undef if $res->code == 301; # directory?
-                       die $res->status_line." at $url\n";
-               }
-               $mode = '0644'; # can't obtain mode via direct http request?
-       } else {
-               ($name,$mode) = $svn->file("$svnpath",$rev);
-               return undef unless defined $name;
-       }
-
-       my $pid = open(my $F, '-|');
-       die $! unless defined $pid;
-       if (!$pid) {
-           exec("git", "hash-object", "-w", $name)
-               or die "Cannot create object: $!\n";
-       }
-       my $sha = <$F>;
-       chomp $sha;
-       close $F;
-       unlink $name;
-       return [$mode, $sha, $path];
-}
-
-sub get_ignore($$$$$) {
-       my($new,$old,$rev,$path,$svnpath) = @_;
-
-       return unless $opt_I;
-       my $name = $svn->ignore("$svnpath",$rev);
-       if ($path eq '/') {
-               $path = $opt_I;
-       } else {
-               $path = File::Spec->catfile($path,$opt_I);
-       }
-       if (defined $name) {
-               my $pid = open(my $F, '-|');
-               die $! unless defined $pid;
-               if (!$pid) {
-                       exec("git", "hash-object", "-w", $name)
-                           or die "Cannot create object: $!\n";
-               }
-               my $sha = <$F>;
-               chomp $sha;
-               close $F;
-               unlink $name;
-               push(@$new,['0644',$sha,$path]);
-       } elsif (defined $old) {
-               push(@$old,$path);
-       }
-}
-
-sub project_path($$)
-{
-       my ($path, $project) = @_;
-
-       $path = "/".$path unless ($path =~ m#^\/#) ;
-       return $1 if ($path =~ m#^$project\/(.*)$#);
-
-       $path =~ s#\.#\\\.#g;
-       $path =~ s#\+#\\\+#g;
-       return "/" if ($project =~ m#^$path.*$#);
-
-       return undef;
-}
-
-sub split_path($$) {
-       my($rev,$path) = @_;
-       my $branch;
-
-       if($path =~ s#^/\Q$tag_name\E/([^/]+)/?##) {
-               $branch = "/$1";
-       } elsif($path =~ s#^/\Q$trunk_name\E/?##) {
-               $branch = "/";
-       } elsif($path =~ s#^/\Q$branch_name\E/([^/]+)/?##) {
-               $branch = $1;
-       } else {
-               my %no_error = (
-                       "/" => 1,
-                       "/$tag_name" => 1,
-                       "/$branch_name" => 1
-               );
-               print STDERR "$rev: Unrecognized path: $path\n" unless (defined $no_error{$path});
-               return ()
-       }
-       if ($path eq "") {
-               $path = "/";
-       } elsif ($project_name) {
-               $path = project_path($path, $project_name);
-       }
-       return ($branch,$path);
-}
-
-sub branch_rev($$) {
-
-       my ($srcbranch,$uptorev) = @_;
-
-       my $bbranches = $branches{$srcbranch};
-       my @revs = reverse sort { ($a eq 'LAST' ? 0 : $a) <=> ($b eq 'LAST' ? 0 : $b) } keys %$bbranches;
-       my $therev;
-       foreach my $arev(@revs) {
-               next if  ($arev eq 'LAST');
-               if ($arev <= $uptorev) {
-                       $therev = $arev;
-                       last;
-               }
-       }
-       return $therev;
-}
-
-sub expand_svndir($$$);
-
-sub expand_svndir($$$)
-{
-       my ($svnpath, $rev, $path) = @_;
-       my @list;
-       get_ignore(\@list, undef, $rev, $path, $svnpath);
-       my $dirents = $svn->dir_list($svnpath, $rev);
-       foreach my $p(keys %$dirents) {
-               my $kind = node_kind($svnpath.'/'.$p, $rev);
-               if ($kind eq $SVN::Node::file) {
-                       my $f = get_file($svnpath.'/'.$p, $rev, $path.'/'.$p);
-                       push(@list, $f) if $f;
-               } elsif ($kind eq $SVN::Node::dir) {
-                       push(@list,
-                            expand_svndir($svnpath.'/'.$p, $rev, $path.'/'.$p));
-               }
-       }
-       return @list;
-}
-
-sub copy_path($$$$$$$$) {
-       # Somebody copied a whole subdirectory.
-       # We need to find the index entries from the old version which the
-       # SVN log entry points to, and add them to the new place.
-
-       my($newrev,$newbranch,$path,$oldpath,$rev,$node_kind,$new,$parents) = @_;
-
-       my($srcbranch,$srcpath) = split_path($rev,$oldpath);
-       unless(defined $srcbranch && defined $srcpath) {
-               print "Path not found when copying from $oldpath @ $rev.\n".
-                       "Will try to copy from original SVN location...\n"
-                       if $opt_v;
-               push (@$new, expand_svndir($oldpath, $rev, $path));
-               return;
-       }
-       my $therev = branch_rev($srcbranch, $rev);
-       my $gitrev = $branches{$srcbranch}{$therev};
-       unless($gitrev) {
-               print STDERR "$newrev:$newbranch: could not find $oldpath \@ $rev\n";
-               return;
-       }
-       if ($srcbranch ne $newbranch) {
-               push(@$parents, $branches{$srcbranch}{'LAST'});
-       }
-       print "$newrev:$newbranch:$path: copying from $srcbranch:$srcpath @ $rev\n" if $opt_v;
-       if ($node_kind eq $SVN::Node::dir) {
-               $srcpath =~ s#/*$#/#;
-       }
-
-       my $pid = open my $f,'-|';
-       die $! unless defined $pid;
-       if (!$pid) {
-               exec("git","ls-tree","-r","-z",$gitrev,$srcpath)
-                       or die $!;
-       }
-       local $/ = "\0";
-       while(<$f>) {
-               chomp;
-               my($m,$p) = split(/\t/,$_,2);
-               my($mode,$type,$sha1) = split(/ /,$m);
-               next if $type ne "blob";
-               if ($node_kind eq $SVN::Node::dir) {
-                       $p = $path . substr($p,length($srcpath)-1);
-               } else {
-                       $p = $path;
-               }
-               push(@$new,[$mode,$sha1,$p]);
-       }
-       close($f) or
-               print STDERR "$newrev:$newbranch: could not list files in $oldpath \@ $rev\n";
-}
-
-sub commit {
-       my($branch, $changed_paths, $revision, $author, $date, $message) = @_;
-       my($committer_name,$committer_email,$dest);
-       my($author_name,$author_email);
-       my(@old,@new,@parents);
-
-       if (not defined $author or $author eq "") {
-               $committer_name = $committer_email = "unknown";
-       } elsif (defined $users_file) {
-               die "User $author is not listed in $users_file\n"
-                   unless exists $users{$author};
-               ($committer_name,$committer_email) = @{$users{$author}};
-       } elsif ($author =~ /^(.*?)\s+<(.*)>$/) {
-               ($committer_name, $committer_email) = ($1, $2);
-       } else {
-               $author =~ s/^<(.*)>$/$1/;
-               $committer_name = $committer_email = $author;
-       }
-
-       if ($opt_F && $message =~ /From:\s+(.*?)\s+<(.*)>\s*\n/) {
-               ($author_name, $author_email) = ($1, $2);
-               print "Author from From: $1 <$2>\n" if ($opt_v);;
-       } elsif ($opt_S && $message =~ /Signed-off-by:\s+(.*?)\s+<(.*)>\s*\n/) {
-               ($author_name, $author_email) = ($1, $2);
-               print "Author from Signed-off-by: $1 <$2>\n" if ($opt_v);;
-       } else {
-               $author_name = $committer_name;
-               $author_email = $committer_email;
-       }
-
-       $date = pdate($date);
-
-       my $tag;
-       my $parent;
-       if($branch eq "/") { # trunk
-               $parent = $opt_o;
-       } elsif($branch =~ m#^/(.+)#) { # tag
-               $tag = 1;
-               $parent = $1;
-       } else { # "normal" branch
-               # nothing to do
-               $parent = $branch;
-       }
-       $dest = $parent;
-
-       my $prev = $changed_paths->{"/"};
-       if($prev and $prev->[0] eq "A") {
-               delete $changed_paths->{"/"};
-               my $oldpath = $prev->[1];
-               my $rev;
-               if(defined $oldpath) {
-                       my $p;
-                       ($parent,$p) = split_path($revision,$oldpath);
-                       if(defined $parent) {
-                               if($parent eq "/") {
-                                       $parent = $opt_o;
-                               } else {
-                                       $parent =~ s#^/##; # if it's a tag
-                               }
-                       }
-               } else {
-                       $parent = undef;
-               }
-       }
-
-       my $rev;
-       if($revision > $opt_s and defined $parent) {
-               open(H,'-|',"git","rev-parse","--verify",$parent);
-               $rev = <H>;
-               close(H) or do {
-                       print STDERR "$revision: cannot find commit '$parent'!\n";
-                       return;
-               };
-               chop $rev;
-               if(length($rev) != 40) {
-                       print STDERR "$revision: cannot find commit '$parent'!\n";
-                       return;
-               }
-               $rev = $branches{($parent eq $opt_o) ? "/" : $parent}{"LAST"};
-               if($revision != $opt_s and not $rev) {
-                       print STDERR "$revision: do not know ancestor for '$parent'!\n";
-                       return;
-               }
-       } else {
-               $rev = undef;
-       }
-
-#      if($prev and $prev->[0] eq "A") {
-#              if(not $tag) {
-#                      unless(open(H,"> $git_dir/refs/heads/$branch")) {
-#                              print STDERR "$revision: Could not create branch $branch: $!\n";
-#                              $state=11;
-#                              next;
-#                      }
-#                      print H "$rev\n"
-#                              or die "Could not write branch $branch: $!";
-#                      close(H)
-#                              or die "Could not write branch $branch: $!";
-#              }
-#      }
-       if(not defined $rev) {
-               unlink($git_index);
-       } elsif ($rev ne $last_rev) {
-               print "Switching from $last_rev to $rev ($branch)\n" if $opt_v;
-               system("git", "read-tree", $rev);
-               die "read-tree failed for $rev: $?\n" if $?;
-               $last_rev = $rev;
-       }
-
-       push (@parents, $rev) if defined $rev;
-
-       my $cid;
-       if($tag and not %$changed_paths) {
-               $cid = $rev;
-       } else {
-               my @paths = sort keys %$changed_paths;
-               foreach my $path(@paths) {
-                       my $action = $changed_paths->{$path};
-
-                       if ($action->[0] eq "R") {
-                               # refer to a file/tree in an earlier commit
-                               push(@old,$path); # remove any old stuff
-                       }
-                       if(($action->[0] eq "A") || ($action->[0] eq "R")) {
-                               my $node_kind = node_kind($action->[3], $revision);
-                               if ($node_kind eq $SVN::Node::file) {
-                                       my $f = get_file($action->[3],
-                                                        $revision, $path);
-                                       if ($f) {
-                                               push(@new,$f) if $f;
-                                       } else {
-                                               my $opath = $action->[3];
-                                               print STDERR "$revision: $branch: could not fetch '$opath'\n";
-                                       }
-                               } elsif ($node_kind eq $SVN::Node::dir) {
-                                       if($action->[1]) {
-                                               copy_path($revision, $branch,
-                                                         $path, $action->[1],
-                                                         $action->[2], $node_kind,
-                                                         \@new, \@parents);
-                                       } else {
-                                               get_ignore(\@new, \@old, $revision,
-                                                          $path, $action->[3]);
-                                       }
-                               }
-                       } elsif ($action->[0] eq "D") {
-                               push(@old,$path);
-                       } elsif ($action->[0] eq "M") {
-                               my $node_kind = node_kind($action->[3], $revision);
-                               if ($node_kind eq $SVN::Node::file) {
-                                       my $f = get_file($action->[3],
-                                                        $revision, $path);
-                                       push(@new,$f) if $f;
-                               } elsif ($node_kind eq $SVN::Node::dir) {
-                                       get_ignore(\@new, \@old, $revision,
-                                                  $path, $action->[3]);
-                               }
-                       } else {
-                               die "$revision: unknown action '".$action->[0]."' for $path\n";
-                       }
-               }
-
-               while(@old) {
-                       my @o1;
-                       if(@old > 55) {
-                               @o1 = splice(@old,0,50);
-                       } else {
-                               @o1 = @old;
-                               @old = ();
-                       }
-                       my $pid = open my $F, "-|";
-                       die "$!" unless defined $pid;
-                       if (!$pid) {
-                               exec("git", "ls-files", "-z", @o1) or die $!;
-                       }
-                       @o1 = ();
-                       local $/ = "\0";
-                       while(<$F>) {
-                               chomp;
-                               push(@o1,$_);
-                       }
-                       close($F);
-
-                       while(@o1) {
-                               my @o2;
-                               if(@o1 > 55) {
-                                       @o2 = splice(@o1,0,50);
-                               } else {
-                                       @o2 = @o1;
-                                       @o1 = ();
-                               }
-                               system("git","update-index","--force-remove","--",@o2);
-                               die "Cannot remove files: $?\n" if $?;
-                       }
-               }
-               while(@new) {
-                       my @n2;
-                       if(@new > 12) {
-                               @n2 = splice(@new,0,10);
-                       } else {
-                               @n2 = @new;
-                               @new = ();
-                       }
-                       system("git","update-index","--add",
-                               (map { ('--cacheinfo', @$_) } @n2));
-                       die "Cannot add files: $?\n" if $?;
-               }
-
-               my $pid = open(C,"-|");
-               die "Cannot fork: $!" unless defined $pid;
-               unless($pid) {
-                       exec("git","write-tree");
-                       die "Cannot exec git-write-tree: $!\n";
-               }
-               chomp(my $tree = <C>);
-               length($tree) == 40
-                       or die "Cannot get tree id ($tree): $!\n";
-               close(C)
-                       or die "Error running git-write-tree: $?\n";
-               print "Tree ID $tree\n" if $opt_v;
-
-               my $pr = IO::Pipe->new() or die "Cannot open pipe: $!\n";
-               my $pw = IO::Pipe->new() or die "Cannot open pipe: $!\n";
-               $pid = fork();
-               die "Fork: $!\n" unless defined $pid;
-               unless($pid) {
-                       $pr->writer();
-                       $pw->reader();
-                       open(OUT,">&STDOUT");
-                       dup2($pw->fileno(),0);
-                       dup2($pr->fileno(),1);
-                       $pr->close();
-                       $pw->close();
-
-                       my @par = ();
-
-                       # loose detection of merges
-                       # based on the commit msg
-                       foreach my $rx (@mergerx) {
-                               if ($message =~ $rx) {
-                                       my $mparent = $1;
-                                       if ($mparent eq 'HEAD') { $mparent = $opt_o };
-                                       if ( -e "$git_dir/refs/heads/$mparent") {
-                                               $mparent = get_headref($mparent, $git_dir);
-                                               push (@parents, $mparent);
-                                               print OUT "Merge parent branch: $mparent\n" if $opt_v;
-                                       }
-                               }
-                       }
-                       my %seen_parents = ();
-                       my @unique_parents = grep { ! $seen_parents{$_} ++ } @parents;
-                       foreach my $bparent (@unique_parents) {
-                               push @par, '-p', $bparent;
-                               print OUT "Merge parent branch: $bparent\n" if $opt_v;
-                       }
-
-                       exec("env",
-                               "GIT_AUTHOR_NAME=$author_name",
-                               "GIT_AUTHOR_EMAIL=$author_email",
-                               "GIT_AUTHOR_DATE=".strftime("+0000 %Y-%m-%d %H:%M:%S",gmtime($date)),
-                               "GIT_COMMITTER_NAME=$committer_name",
-                               "GIT_COMMITTER_EMAIL=$committer_email",
-                               "GIT_COMMITTER_DATE=".strftime("+0000 %Y-%m-%d %H:%M:%S",gmtime($date)),
-                               "git", "commit-tree", $tree,@par);
-                       die "Cannot exec git-commit-tree: $!\n";
-               }
-               $pw->writer();
-               $pr->reader();
-
-               $message =~ s/[\s\n]+\z//;
-               $message = "r$revision: $message" if $opt_r;
-
-               print $pw "$message\n"
-                       or die "Error writing to git-commit-tree: $!\n";
-               $pw->close();
-
-               print "Committed change $revision:$branch ".strftime("%Y-%m-%d %H:%M:%S",gmtime($date)).")\n" if $opt_v;
-               chomp($cid = <$pr>);
-               length($cid) == 40
-                       or die "Cannot get commit id ($cid): $!\n";
-               print "Commit ID $cid\n" if $opt_v;
-               $pr->close();
-
-               waitpid($pid,0);
-               die "Error running git-commit-tree: $?\n" if $?;
-       }
-
-       if (not defined $cid) {
-               $cid = $branches{"/"}{"LAST"};
-       }
-
-       if(not defined $dest) {
-               print "... no known parent\n" if $opt_v;
-       } elsif(not $tag) {
-               print "Writing to refs/heads/$dest\n" if $opt_v;
-               open(C,">$git_dir/refs/heads/$dest") and
-               print C ("$cid\n") and
-               close(C)
-                       or die "Cannot write branch $dest for update: $!\n";
-       }
-
-       if ($tag) {
-               $last_rev = "-" if %$changed_paths;
-               # the tag was 'complex', i.e. did not refer to a "real" revision
-
-               $dest =~ tr/_/\./ if $opt_u;
-
-               system('git', 'tag', '-f', $dest, $cid) == 0
-                       or die "Cannot create tag $dest: $!\n";
-
-               print "Created tag '$dest' on '$branch'\n" if $opt_v;
-       }
-       $branches{$branch}{"LAST"} = $cid;
-       $branches{$branch}{$revision} = $cid;
-       $last_rev = $cid;
-       print BRANCHES "$revision $branch $cid\n";
-       print "DONE: $revision $dest $cid\n" if $opt_v;
-}
-
-sub commit_all {
-       # Recursive use of the SVN connection does not work
-       local $svn = $svn2;
-
-       my ($changed_paths, $revision, $author, $date, $message) = @_;
-       my %p;
-       while(my($path,$action) = each %$changed_paths) {
-               $p{$path} = [ $action->action,$action->copyfrom_path, $action->copyfrom_rev, $path ];
-       }
-       $changed_paths = \%p;
-
-       my %done;
-       my @col;
-       my $pref;
-       my $branch;
-
-       while(my($path,$action) = each %$changed_paths) {
-               ($branch,$path) = split_path($revision,$path);
-               next if not defined $branch;
-               next if not defined $path;
-               $done{$branch}{$path} = $action;
-       }
-       while(($branch,$changed_paths) = each %done) {
-               commit($branch, $changed_paths, $revision, $author, $date, $message);
-       }
-}
-
-$opt_l = $svn->{'maxrev'} if not defined $opt_l or $opt_l > $svn->{'maxrev'};
-
-if ($opt_l < $current_rev) {
-    print "Up to date: no new revisions to fetch!\n" if $opt_v;
-    unlink("$git_dir/SVN2GIT_HEAD");
-    exit;
-}
-
-print "Processing from $current_rev to $opt_l ...\n" if $opt_v;
-
-my $from_rev;
-my $to_rev = $current_rev - 1;
-
-my $subpool = SVN::Pool::new_default_sub;
-while ($to_rev < $opt_l) {
-       $subpool->clear;
-       $from_rev = $to_rev + 1;
-       $to_rev = $from_rev + $repack_after;
-       $to_rev = $opt_l if $opt_l < $to_rev;
-       print "Fetching from $from_rev to $to_rev ...\n" if $opt_v;
-       $svn->{'svn'}->get_log("",$from_rev,$to_rev,0,1,1,\&commit_all);
-       my $pid = fork();
-       die "Fork: $!\n" unless defined $pid;
-       unless($pid) {
-               exec("git", "repack", "-d")
-                       or die "Cannot repack: $!\n";
-       }
-       waitpid($pid, 0);
-}
-
-
-unlink($git_index);
-
-if (defined $orig_git_index) {
-       $ENV{GIT_INDEX_FILE} = $orig_git_index;
-} else {
-       delete $ENV{GIT_INDEX_FILE};
-}
-
-# Now switch back to the branch we were in before all of this happened
-if($orig_branch) {
-       print "DONE\n" if $opt_v and (not defined $opt_l or $opt_l > 0);
-       system("cp","$git_dir/refs/heads/$opt_o","$git_dir/refs/heads/master")
-               if $forward_master;
-       unless ($opt_i) {
-               system('git', 'read-tree', '-m', '-u', 'SVN2GIT_HEAD', 'HEAD');
-               die "read-tree failed: $?\n" if $?;
-       }
-} else {
-       $orig_branch = "master";
-       print "DONE; creating $orig_branch branch\n" if $opt_v and (not defined $opt_l or $opt_l > 0);
-       system("cp","$git_dir/refs/heads/$opt_o","$git_dir/refs/heads/master")
-               unless -f "$git_dir/refs/heads/master";
-       system('git', 'update-ref', 'HEAD', "$orig_branch");
-       unless ($opt_i) {
-               system('git checkout');
-               die "checkout failed: $?\n" if $?;
-       }
-}
-unlink("$git_dir/SVN2GIT_HEAD");
-close(BRANCHES);
diff --git a/contrib/examples/git-svnimport.txt b/contrib/examples/git-svnimport.txt
deleted file mode 100644 (file)
index 3f0a9c3..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-git-svnimport(1)
-================
-v0.1, July 2005
-
-NAME
-----
-git-svnimport - Import a SVN repository into git
-
-
-SYNOPSIS
---------
-[verse]
-'git-svnimport' [ -o <branch-for-HEAD> ] [ -h ] [ -v ] [ -d | -D ]
-               [ -C <GIT_repository> ] [ -i ] [ -u ] [-l limit_rev]
-               [ -b branch_subdir ] [ -T trunk_subdir ] [ -t tag_subdir ]
-               [ -s start_chg ] [ -m ] [ -r ] [ -M regex ]
-               [ -I <ignorefile_name> ] [ -A <author_file> ]
-               [ -R <repack_each_revs>] [ -P <path_from_trunk> ]
-               <SVN_repository_URL> [ <path> ]
-
-
-DESCRIPTION
------------
-Imports a SVN repository into git. It will either create a new
-repository, or incrementally import into an existing one.
-
-SVN access is done by the SVN::Perl module.
-
-git-svnimport assumes that SVN repositories are organized into one
-"trunk" directory where the main development happens, "branches/FOO"
-directories for branches, and "/tags/FOO" directories for tags.
-Other subdirectories are ignored.
-
-git-svnimport creates a file ".git/svn2git", which is required for
-incremental SVN imports.
-
-OPTIONS
--------
--C <target-dir>::
-        The GIT repository to import to.  If the directory doesn't
-        exist, it will be created.  Default is the current directory.
-
--s <start_rev>::
-        Start importing at this SVN change number. The  default is 1.
-+
-When importing incrementally, you might need to edit the .git/svn2git file.
-
--i::
-       Import-only: don't perform a checkout after importing.  This option
-       ensures the working directory and index remain untouched and will
-       not create them if they do not exist.
-
--T <trunk_subdir>::
-       Name the SVN trunk. Default "trunk".
-
--t <tag_subdir>::
-       Name the SVN subdirectory for tags. Default "tags".
-
--b <branch_subdir>::
-       Name the SVN subdirectory for branches. Default "branches".
-
--o <branch-for-HEAD>::
-       The 'trunk' branch from SVN is imported to the 'origin' branch within
-       the git repository. Use this option if you want to import into a
-       different branch.
-
--r::
-       Prepend 'rX: ' to commit messages, where X is the imported
-       subversion revision.
-
--u::
-       Replace underscores in tag names with periods.
-
--I <ignorefile_name>::
-       Import the svn:ignore directory property to files with this
-       name in each directory. (The Subversion and GIT ignore
-       syntaxes are similar enough that using the Subversion patterns
-       directly with "-I .gitignore" will almost always just work.)
-
--A <author_file>::
-       Read a file with lines on the form
-+
-------
-       username = User's Full Name <email@addr.es>
-
-------
-+
-and use "User's Full Name <email@addr.es>" as the GIT
-author and committer for Subversion commits made by
-"username". If encountering a commit made by a user not in the
-list, abort.
-+
-For convenience, this data is saved to $GIT_DIR/svn-authors
-each time the -A option is provided, and read from that same
-file each time git-svnimport is run with an existing GIT
-repository without -A.
-
--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.
-
--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.
-
--l <max_rev>::
-       Specify a maximum revision number to pull.
-+
-Formerly, this option controlled how many revisions to pull,
-due to SVN memory leaks. (These have been worked around.)
-
--R <repack_each_revs>::
-       Specify how often git repository should be repacked.
-+
-The default value is 1000. git-svnimport will do imports in chunks of 1000
-revisions, after each chunk the git repository will be repacked. To disable
-this behavior specify some large value here which is greater than the number of
-revisions to import.
-
--P <path_from_trunk>::
-       Partial import of the SVN tree.
-+
-By default, the whole tree on the SVN trunk (/trunk) is imported.
-'-P my/proj' will import starting only from '/trunk/my/proj'.
-This option is useful when you want to import one project from a
-svn repo which hosts multiple projects under the same trunk.
-
--v::
-       Verbosity: let 'svnimport' report what it is doing.
-
--d::
-       Use direct HTTP requests if possible. The "<path>" argument is used
-       only for retrieving the SVN logs; the path to the contents is
-       included in the SVN log.
-
--D::
-       Use direct HTTP requests if possible. The "<path>" argument is used
-       for retrieving the logs, as well as for the contents.
-+
-There's no safe way to automatically find out which of these options to
-use, so you need to try both. Usually, the one that's wrong will die
-with a 40x error pretty quickly.
-
-<SVN_repository_URL>::
-       The URL of the SVN module you want to import. For local
-       repositories, use "file:///absolute/path".
-+
-If you're using the "-d" or "-D" option, this is the URL of the SVN
-repository itself; it usually ends in "/svn".
-
-<path>::
-       The path to the module you want to check out.
-
--h::
-       Print a short usage message and exit.
-
-OUTPUT
-------
-If '-v' is specified, the script reports what it is doing.
-
-Otherwise, success is indicated the Unix way, i.e. by simply exiting with
-a zero exit status.
-
-Author
-------
-Written by Matthias Urlichs <smurf@smurf.noris.de>, with help from
-various participants of the git-list <git@vger.kernel.org>.
-
-Based on a cvs2git script by the same author.
-
-Documentation
---------------
-Documentation by Matthias Urlichs <smurf@smurf.noris.de>.
-
-GIT
----
-Part of the linkgit:git[7] suite
diff --git a/contrib/examples/git-tag.sh b/contrib/examples/git-tag.sh
deleted file mode 100755 (executable)
index 1bd8f3c..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-#!/bin/sh
-# Copyright (c) 2005 Linus Torvalds
-
-USAGE='[-n [<num>]] -l [<pattern>] | [-a | -s | -u <key-id>] [-f | -d | -v] [-m <msg>] <tagname> [<head>]'
-SUBDIRECTORY_OK='Yes'
-. git-sh-setup
-
-message_given=
-annotate=
-signed=
-force=
-message=
-username=
-list=
-verify=
-LINES=0
-while test $# != 0
-do
-    case "$1" in
-    -a)
-       annotate=1
-       shift
-       ;;
-    -s)
-       annotate=1
-       signed=1
-       shift
-       ;;
-    -f)
-       force=1
-       shift
-       ;;
-    -n)
-        case "$#,$2" in
-       1,* | *,-*)
-               LINES=1         # no argument
-               ;;
-       *)      shift
-               LINES=$(expr "$1" : '\([0-9]*\)')
-               [ -z "$LINES" ] && LINES=1 # 1 line is default when -n is used
-               ;;
-       esac
-       shift
-       ;;
-    -l)
-       list=1
-       shift
-       case $# in
-       0)      PATTERN=
-               ;;
-       *)
-               PATTERN="$1"    # select tags by shell pattern, not re
-               shift
-               ;;
-       esac
-       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' |
-                               sed -n -e "
-                                       /^-----BEGIN PGP SIGNATURE-----\$/q
-                                       2,\$s/^/    /
-                                       p
-                                       ${LINES}q
-                               ")
-                       printf "%-15s %s\n" "$TAG" "$ANNOTATION"
-                       ;;
-               *)      echo "$TAG"
-                       ;;
-               esac
-           done
-       ;;
-    -m)
-       annotate=1
-       shift
-       message="$1"
-       if test "$#" = "0"; then
-           die "error: option -m needs an argument"
-       else
-           message="$1"
-           message_given=1
-           shift
-       fi
-       ;;
-    -F)
-       annotate=1
-       shift
-       if test "$#" = "0"; then
-           die "error: option -F needs an argument"
-       else
-           message="$(cat "$1")"
-           message_given=1
-           shift
-       fi
-       ;;
-    -u)
-       annotate=1
-       signed=1
-       shift
-       if test "$#" = "0"; then
-           die "error: option -u needs an argument"
-       else
-           username="$1"
-           shift
-       fi
-       ;;
-    -d)
-       shift
-       had_error=0
-       for tag
-       do
-               cur=$(git show-ref --verify --hash -- "refs/tags/$tag") || {
-                       echo >&2 "Seriously, what tag are you talking about?"
-                       had_error=1
-                       continue
-               }
-               git update-ref -m 'tag: delete' -d "refs/tags/$tag" "$cur" || {
-                       had_error=1
-                       continue
-               }
-               echo "Deleted tag $tag."
-       done
-       exit $had_error
-       ;;
-    -v)
-       shift
-       tag_name="$1"
-       tag=$(git show-ref --verify --hash -- "refs/tags/$tag_name") ||
-               die "Seriously, what tag are you talking about?"
-       git-verify-tag -v "$tag"
-       exit $?
-       ;;
-    -*)
-        usage
-       ;;
-    *)
-       break
-       ;;
-    esac
-done
-
-[ -n "$list" ] && exit 0
-
-name="$1"
-[ "$name" ] || usage
-prev=0000000000000000000000000000000000000000
-if git show-ref --verify --quiet -- "refs/tags/$name"
-then
-    test -n "$force" || die "tag '$name' already exists"
-    prev=$(git rev-parse "refs/tags/$name")
-fi
-shift
-git check-ref-format "tags/$name" ||
-       die "we do not like '$name' as a tag name."
-
-object=$(git rev-parse --verify --default HEAD "$@") || exit 1
-type=$(git cat-file -t $object) || exit 1
-tagger=$(git var GIT_COMMITTER_IDENT) || exit 1
-
-test -n "$username" ||
-       username=$(git config user.signingkey) ||
-       username=$(expr "z$tagger" : 'z\(.*>\)')
-
-trap 'rm -f "$GIT_DIR"/TAG_TMP* "$GIT_DIR"/TAG_FINALMSG "$GIT_DIR"/TAG_EDITMSG' 0
-
-if [ "$annotate" ]; then
-    if [ -z "$message_given" ]; then
-        ( echo "#"
-          echo "# Write a tag message"
-          echo "#" ) > "$GIT_DIR"/TAG_EDITMSG
-        git_editor "$GIT_DIR"/TAG_EDITMSG || exit
-    else
-        printf '%s\n' "$message" >"$GIT_DIR"/TAG_EDITMSG
-    fi
-
-    grep -v '^#' <"$GIT_DIR"/TAG_EDITMSG |
-    git stripspace >"$GIT_DIR"/TAG_FINALMSG
-
-    [ -s "$GIT_DIR"/TAG_FINALMSG -o -n "$message_given" ] || {
-       echo >&2 "No tag message?"
-       exit 1
-    }
-
-    ( printf 'object %s\ntype %s\ntag %s\ntagger %s\n\n' \
-       "$object" "$type" "$name" "$tagger";
-      cat "$GIT_DIR"/TAG_FINALMSG ) >"$GIT_DIR"/TAG_TMP
-    rm -f "$GIT_DIR"/TAG_TMP.asc "$GIT_DIR"/TAG_FINALMSG
-    if [ "$signed" ]; then
-       gpg -bsa -u "$username" "$GIT_DIR"/TAG_TMP &&
-       cat "$GIT_DIR"/TAG_TMP.asc >>"$GIT_DIR"/TAG_TMP ||
-       die "failed to sign the tag with GPG."
-    fi
-    object=$(git-mktag < "$GIT_DIR"/TAG_TMP)
-fi
-
-git update-ref "refs/tags/$name" "$object" "$prev"
diff --git a/contrib/examples/git-verify-tag.sh b/contrib/examples/git-verify-tag.sh
deleted file mode 100755 (executable)
index 0902a5c..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/sh
-
-USAGE='<tag>'
-SUBDIRECTORY_OK='Yes'
-. git-sh-setup
-
-verbose=
-while test $# != 0
-do
-       case "$1" in
-       -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
-               verbose=t ;;
-       *)
-               break ;;
-       esac
-       shift
-done
-
-if [ "$#" != "1" ]
-then
-       usage
-fi
-
-type="$(git cat-file -t "$1" 2>/dev/null)" ||
-       die "$1: no such object."
-
-test "$type" = tag ||
-       die "$1: cannot verify a non-tag object of type $type."
-
-case "$verbose" in
-t)
-       git cat-file -p "$1" |
-       sed -n -e '/^-----BEGIN PGP SIGNATURE-----/q' -e p
-       ;;
-esac
-
-trap 'rm -f "$GIT_DIR/.tmp-vtag"' 0
-
-git cat-file tag "$1" >"$GIT_DIR/.tmp-vtag" || exit 1
-sed -n -e '
-       /^-----BEGIN PGP SIGNATURE-----$/q
-       p
-' <"$GIT_DIR/.tmp-vtag" |
-gpg --verify "$GIT_DIR/.tmp-vtag" - || exit 1
-rm -f "$GIT_DIR/.tmp-vtag"
diff --git a/contrib/examples/git-whatchanged.sh b/contrib/examples/git-whatchanged.sh
deleted file mode 100755 (executable)
index 2edbdc6..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/sh
-
-USAGE='[-p] [--max-count=<n>] [<since>..<limit>] [--pretty=<format>] [-m] [git-diff-tree options] [git-rev-list options]'
-SUBDIRECTORY_OK='Yes'
-. git-sh-setup
-
-diff_tree_flags=$(git-rev-parse --sq --no-revs --flags "$@") || exit
-case "$0" in
-*whatchanged)
-       count=
-       test -z "$diff_tree_flags" &&
-               diff_tree_flags=$(git config --get whatchanged.difftree)
-       diff_tree_default_flags='-c -M --abbrev' ;;
-*show)
-       count=-n1
-       test -z "$diff_tree_flags" &&
-               diff_tree_flags=$(git config --get show.difftree)
-       diff_tree_default_flags='--cc --always' ;;
-esac
-test -z "$diff_tree_flags" &&
-       diff_tree_flags="$diff_tree_default_flags"
-
-rev_list_args=$(git-rev-parse --sq --default HEAD --revs-only "$@") &&
-diff_tree_args=$(git-rev-parse --sq --no-revs --no-flags "$@") &&
-
-eval "git-rev-list $count $rev_list_args" |
-eval "git-diff-tree --stdin --pretty -r $diff_tree_flags $diff_tree_args" |
-LESS="$LESS -S" ${PAGER:-less}
index cc562f65094cd696466f86c3184f61cd025c2117..c480097a2a0cb3d780bdeff252da912c1b8e63b7 100644 (file)
--- a/convert.c
+++ b/convert.c
@@ -914,7 +914,7 @@ static int ident_to_worktree(const char *path, const char *src, size_t len,
                to_free = strbuf_detach(buf, NULL);
        hash_object_file(src, len, "blob", &oid);
 
-       strbuf_grow(buf, len + cnt * 43);
+       strbuf_grow(buf, len + cnt * (the_hash_algo->hexsz + 3));
        for (;;) {
                /* step 1: run to the next '$' */
                dollar = memchr(src, '$', len);
@@ -1510,7 +1510,7 @@ struct ident_filter {
        struct stream_filter filter;
        struct strbuf left;
        int state;
-       char ident[45]; /* ": x40 $" */
+       char ident[GIT_MAX_HEXSZ + 5]; /* ": x40 $" */
 };
 
 static int is_foreign_ident(const char *str)
@@ -1635,12 +1635,12 @@ static struct stream_filter_vtbl ident_vtbl = {
        ident_free_fn,
 };
 
-static struct stream_filter *ident_filter(const unsigned char *sha1)
+static struct stream_filter *ident_filter(const struct object_id *oid)
 {
        struct ident_filter *ident = xmalloc(sizeof(*ident));
 
        xsnprintf(ident->ident, sizeof(ident->ident),
-                 ": %s $", sha1_to_hex(sha1));
+                 ": %s $", oid_to_hex(oid));
        strbuf_init(&ident->left, 0);
        ident->filter.vtbl = &ident_vtbl;
        ident->state = 0;
@@ -1655,7 +1655,7 @@ static struct stream_filter *ident_filter(const unsigned char *sha1)
  * Note that you would be crazy to set CRLF, smuge/clean or ident to a
  * large binary blob you would want us not to slurp into the memory!
  */
-struct stream_filter *get_stream_filter(const char *path, const unsigned char *sha1)
+struct stream_filter *get_stream_filter(const char *path, const struct object_id *oid)
 {
        struct conv_attrs ca;
        struct stream_filter *filter = NULL;
@@ -1668,7 +1668,7 @@ struct stream_filter *get_stream_filter(const char *path, const unsigned char *s
                return NULL;
 
        if (ca.ident)
-               filter = ident_filter(sha1);
+               filter = ident_filter(oid);
 
        if (output_eol(ca.crlf_action) == EOL_CRLF)
                filter = cascade_filter(filter, lf_to_crlf_filter());
index 65ab3e516745775b52f36a370ba7880a34c8b2a5..2e9b4f49cc0acc697bf0304306b96e0b50e30aab 100644 (file)
--- a/convert.h
+++ b/convert.h
@@ -93,7 +93,7 @@ extern int would_convert_to_git_filter_fd(const char *path);
 
 struct stream_filter; /* opaque */
 
-extern struct stream_filter *get_stream_filter(const char *path, const unsigned char *);
+extern struct stream_filter *get_stream_filter(const char *path, const struct object_id *);
 extern void free_stream_filter(struct stream_filter *);
 extern int is_null_stream_filter(struct stream_filter *);
 
index 9747f47b18bf2e622f11f41889faaa4b1845ac8d..62be651b03b55ee4d478706e51ea8606b10739f0 100644 (file)
@@ -5,6 +5,7 @@
 #include "run-command.h"
 #include "url.h"
 #include "prompt.h"
+#include "sigchain.h"
 
 void credential_init(struct credential *c)
 {
@@ -227,8 +228,10 @@ static int run_credential_helper(struct credential *c,
                return -1;
 
        fp = xfdopen(helper.in, "w");
+       sigchain_push(SIGPIPE, SIG_IGN);
        credential_write(c, fp);
        fclose(fp);
+       sigchain_pop(SIGPIPE);
 
        if (want_output) {
                int r;
index fe833ea7de7685968915c93950bb54768dd04586..9d2e0d20ef302aaeac02aaeba791509dd43a2712 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -1459,7 +1459,7 @@ int cmd_main(int argc, const char **argv)
                die("base-path '%s' does not exist or is not a directory",
                    base_path);
 
-       if (inetd_mode) {
+       if (log_destination != LOG_DESTINATION_STDERR) {
                if (!freopen("/dev/null", "w", stderr))
                        die_errno("failed to redirect stderr to /dev/null");
        }
diff --git a/diff.c b/diff.c
index 4c59f5f5d3d32286daefbeeb25ed5291070fe762..1289df4b1f9f395010e475073c2c5e5ce43976a7 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -3638,7 +3638,7 @@ int diff_populate_filespec(struct diff_filespec *s, unsigned int flags)
        else {
                enum object_type type;
                if (size_only || (flags & CHECK_BINARY)) {
-                       type = sha1_object_info(s->oid.hash, &s->size);
+                       type = oid_object_info(&s->oid, &s->size);
                        if (type < 0)
                                die("unable to read %s",
                                    oid_to_hex(&s->oid));
@@ -3649,7 +3649,7 @@ int diff_populate_filespec(struct diff_filespec *s, unsigned int flags)
                                return 0;
                        }
                }
-               s->data = read_sha1_file(s->oid.hash, &type, &s->size);
+               s->data = read_object_file(&s->oid, &type, &s->size);
                if (!s->data)
                        die("unable to read %s", oid_to_hex(&s->oid));
                s->should_free = 1;
@@ -3834,7 +3834,7 @@ static int similarity_index(struct diff_filepair *p)
 static const char *diff_abbrev_oid(const struct object_id *oid, int abbrev)
 {
        if (startup_info->have_repository)
-               return find_unique_abbrev(oid->hash, abbrev);
+               return find_unique_abbrev(oid, abbrev);
        else {
                char *hex = oid_to_hex(oid);
                if (abbrev < 0)
diff --git a/dir.c b/dir.c
index dedbf5d476f207e39c1b7853ec8c97553181e5fb..63a917be45db99c278cc86012ff74718043dc63d 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -243,7 +243,7 @@ static int do_read_blob(const struct object_id *oid, struct oid_stat *oid_stat,
        *size_out = 0;
        *data_out = NULL;
 
-       data = read_sha1_file(oid->hash, &type, &sz);
+       data = read_object_file(oid, &type, &sz);
        if (!data || type != OBJ_BLOB) {
                free(data);
                return -1;
diff --git a/entry.c b/entry.c
index 6c33112aea7dc8e584678bcb5e5ea292d29265a9..2101201a111785f449a65e785e9ed5b57b7aa196 100644 (file)
--- a/entry.c
+++ b/entry.c
@@ -85,7 +85,7 @@ static int create_file(const char *path, unsigned int mode)
 static void *read_blob_entry(const struct cache_entry *ce, unsigned long *size)
 {
        enum object_type type;
-       void *blob_data = read_sha1_file(ce->oid.hash, &type, size);
+       void *blob_data = read_object_file(&ce->oid, &type, size);
 
        if (blob_data) {
                if (type == OBJ_BLOB)
@@ -266,7 +266,7 @@ static int write_entry(struct cache_entry *ce,
 
        if (ce_mode_s_ifmt == S_IFREG) {
                struct stream_filter *filter = get_stream_filter(ce->name,
-                                                                ce->oid.hash);
+                                                                &ce->oid);
                if (filter &&
                    !streaming_write_entry(ce, path, filter,
                                           state, to_tempfile,
index d6dd64662ce4d09296b61708b020a71eef3488f6..fd970b81bdb682763fcb21528b9739171734bdba 100644 (file)
@@ -13,6 +13,9 @@
 #include "refs.h"
 #include "fmt-merge-msg.h"
 #include "commit.h"
+#include "argv-array.h"
+#include "object-store.h"
+#include "chdir-notify.h"
 
 int trust_executable_bit = 1;
 int trust_ctime = 1;
@@ -147,10 +150,35 @@ static char *expand_namespace(const char *raw_namespace)
        return strbuf_detach(&buf, NULL);
 }
 
-void setup_git_env(void)
+/*
+ * Wrapper of getenv() that returns a strdup value. This value is kept
+ * in argv to be freed later.
+ */
+static const char *getenv_safe(struct argv_array *argv, const char *name)
+{
+       const char *value = getenv(name);
+
+       if (!value)
+               return NULL;
+
+       argv_array_push(argv, value);
+       return argv->argv[argv->argc - 1];
+}
+
+void setup_git_env(const char *git_dir)
 {
        const char *shallow_file;
        const char *replace_ref_base;
+       struct set_gitdir_args args = { NULL };
+       struct argv_array to_free = ARGV_ARRAY_INIT;
+
+       args.commondir = getenv_safe(&to_free, GIT_COMMON_DIR_ENVIRONMENT);
+       args.object_dir = getenv_safe(&to_free, DB_ENVIRONMENT);
+       args.graft_file = getenv_safe(&to_free, GRAFT_ENVIRONMENT);
+       args.index_file = getenv_safe(&to_free, INDEX_ENVIRONMENT);
+       args.alternate_db = getenv_safe(&to_free, ALTERNATE_DB_ENVIRONMENT);
+       repo_set_gitdir(the_repository, git_dir, &args);
+       argv_array_clear(&to_free);
 
        if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT))
                check_replace_refs = 0;
@@ -244,9 +272,9 @@ const char *get_git_work_tree(void)
 
 char *get_object_directory(void)
 {
-       if (!the_repository->objectdir)
+       if (!the_repository->objects->objectdir)
                BUG("git environment hasn't been setup");
-       return the_repository->objectdir;
+       return the_repository->objects->objectdir;
 }
 
 int odb_mkstemp(struct strbuf *temp_filename, const char *pattern)
@@ -296,13 +324,31 @@ char *get_graft_file(void)
        return the_repository->graft_file;
 }
 
-int set_git_dir(const char *path)
+static void set_git_dir_1(const char *path)
 {
        if (setenv(GIT_DIR_ENVIRONMENT, path, 1))
-               return error("Could not set GIT_DIR to '%s'", path);
-       repo_set_gitdir(the_repository, path);
-       setup_git_env();
-       return 0;
+               die("could not set GIT_DIR to '%s'", path);
+       setup_git_env(path);
+}
+
+static void update_relative_gitdir(const char *name,
+                                  const char *old_cwd,
+                                  const char *new_cwd,
+                                  void *data)
+{
+       char *path = reparent_relative_path(old_cwd, new_cwd, get_git_dir());
+       trace_printf_key(&trace_setup_key,
+                        "setup: move $GIT_DIR to '%s'",
+                        path);
+       set_git_dir_1(path);
+       free(path);
+}
+
+void set_git_dir(const char *path)
+{
+       set_git_dir_1(path);
+       if (!is_absolute_path(path))
+               chdir_notify_register(NULL, update_relative_gitdir, NULL);
 }
 
 const char *get_log_output_encoding(void)
index b5db5d20b1b20c642cf97f990eb538ee6fbaa299..99f8f56e8c4fbd20b6e6186e26d89eda1baff0d0 100644 (file)
@@ -154,6 +154,7 @@ Format of STDIN stream:
 
 #include "builtin.h"
 #include "cache.h"
+#include "repository.h"
 #include "config.h"
 #include "lockfile.h"
 #include "object.h"
@@ -168,6 +169,7 @@ Format of STDIN stream:
 #include "dir.h"
 #include "run-command.h"
 #include "packfile.h"
+#include "object-store.h"
 
 #define PACK_ID_BITS 16
 #define MAX_PACK_ID ((1<<PACK_ID_BITS)-1)
@@ -1036,7 +1038,7 @@ static void end_packfile(void)
                if (!new_p)
                        die("core git rejected index %s", idx_name);
                all_packs[pack_id] = new_p;
-               install_packed_git(new_p);
+               install_packed_git(the_repository, new_p);
                free(idx_name);
 
                /* Print the boundary */
@@ -1110,7 +1112,8 @@ static int store_object(
        if (e->idx.offset) {
                duplicate_count_by_type[type]++;
                return 1;
-       } else if (find_sha1_pack(oid.hash, packed_git)) {
+       } else if (find_sha1_pack(oid.hash,
+                                 get_packed_git(the_repository))) {
                e->type = type;
                e->pack_id = MAX_PACK_ID;
                e->idx.offset = 1; /* just not zero! */
@@ -1307,7 +1310,8 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark)
                duplicate_count_by_type[OBJ_BLOB]++;
                truncate_pack(&checkpoint);
 
-       } else if (find_sha1_pack(oid.hash, packed_git)) {
+       } else if (find_sha1_pack(oid.hash,
+                                 get_packed_git(the_repository))) {
                e->type = OBJ_BLOB;
                e->pack_id = MAX_PACK_ID;
                e->idx.offset = 1; /* just not zero! */
@@ -1412,7 +1416,7 @@ static void load_tree(struct tree_entry *root)
                        die("Can't load tree %s", oid_to_hex(oid));
        } else {
                enum object_type type;
-               buf = read_sha1_file(oid->hash, &type, &size);
+               buf = read_object_file(oid, &type, &size);
                if (!buf || type != OBJ_TREE)
                        die("Can't load tree %s", oid_to_hex(oid));
        }
@@ -1913,7 +1917,7 @@ static void read_marks(void)
                        die("corrupt mark line: %s", line);
                e = find_object(&oid);
                if (!e) {
-                       enum object_type type = sha1_object_info(oid.hash, NULL);
+                       enum object_type type = oid_object_info(&oid, NULL);
                        if (type < 0)
                                die("object not found: %s", oid_to_hex(&oid));
                        e = insert_object(&oid);
@@ -2443,7 +2447,7 @@ static void file_change_m(const char *p, struct branch *b)
                enum object_type expected = S_ISDIR(mode) ?
                                                OBJ_TREE: OBJ_BLOB;
                enum object_type type = oe ? oe->type :
-                                       sha1_object_info(oid.hash, NULL);
+                                       oid_object_info(&oid, NULL);
                if (type < 0)
                        die("%s not found: %s",
                                        S_ISDIR(mode) ?  "Tree" : "Blob",
@@ -2583,8 +2587,9 @@ static void note_change_n(const char *p, struct branch *b, unsigned char *old_fa
                oidcpy(&commit_oid, &commit_oe->idx.oid);
        } else if (!get_oid(p, &commit_oid)) {
                unsigned long size;
-               char *buf = read_object_with_reference(commit_oid.hash,
-                       commit_type, &size, commit_oid.hash);
+               char *buf = read_object_with_reference(&commit_oid,
+                                                      commit_type, &size,
+                                                      &commit_oid);
                if (!buf || size < 46)
                        die("Not a valid commit: %s", p);
                free(buf);
@@ -2603,7 +2608,7 @@ static void note_change_n(const char *p, struct branch *b, unsigned char *old_fa
                        die("Not a blob (actually a %s): %s",
                                type_name(oe->type), command_buf.buf);
        } else if (!is_null_oid(&oid)) {
-               enum object_type type = sha1_object_info(oid.hash, NULL);
+               enum object_type type = oid_object_info(&oid, NULL);
                if (type < 0)
                        die("Blob not found: %s", command_buf.buf);
                if (type != OBJ_BLOB)
@@ -2653,9 +2658,8 @@ static void parse_from_existing(struct branch *b)
                unsigned long size;
                char *buf;
 
-               buf = read_object_with_reference(b->oid.hash,
-                                                commit_type, &size,
-                                                b->oid.hash);
+               buf = read_object_with_reference(&b->oid, commit_type, &size,
+                                                &b->oid);
                parse_from_commit(b, buf, size);
                free(buf);
        }
@@ -2732,8 +2736,9 @@ static struct hash_list *parse_merge(unsigned int *count)
                        oidcpy(&n->oid, &oe->idx.oid);
                } else if (!get_oid(from, &n->oid)) {
                        unsigned long size;
-                       char *buf = read_object_with_reference(n->oid.hash,
-                               commit_type, &size, n->oid.hash);
+                       char *buf = read_object_with_reference(&n->oid,
+                                                              commit_type,
+                                                              &size, &n->oid);
                        if (!buf || size < 46)
                                die("Not a valid commit: %s", from);
                        free(buf);
@@ -2890,7 +2895,7 @@ static void parse_new_tag(const char *arg)
        } else if (!get_oid(from, &oid)) {
                struct object_entry *oe = find_object(&oid);
                if (!oe) {
-                       type = sha1_object_info(oid.hash, NULL);
+                       type = oid_object_info(&oid, NULL);
                        if (type < 0)
                                die("Not a valid object: %s", from);
                } else
@@ -2966,7 +2971,7 @@ static void cat_blob(struct object_entry *oe, struct object_id *oid)
        char *buf;
 
        if (!oe || oe->pack_id == MAX_PACK_ID) {
-               buf = read_sha1_file(oid->hash, &type, &size);
+               buf = read_object_file(oid, &type, &size);
        } else {
                type = oe->type;
                buf = gfi_unpack_entry(oe, &size);
@@ -3048,7 +3053,7 @@ static struct object_entry *dereference(struct object_entry *oe,
        unsigned long size;
        char *buf = NULL;
        if (!oe) {
-               enum object_type type = sha1_object_info(oid->hash, NULL);
+               enum object_type type = oid_object_info(oid, NULL);
                if (type < 0)
                        die("object not found: %s", oid_to_hex(oid));
                /* cache it! */
@@ -3071,7 +3076,7 @@ static struct object_entry *dereference(struct object_entry *oe,
                buf = gfi_unpack_entry(oe, &size);
        } else {
                enum object_type unused;
-               buf = read_sha1_file(oid->hash, &unused, &size);
+               buf = read_object_file(oid, &unused, &size);
        }
        if (!buf)
                die("Can't load object %s", oid_to_hex(oid));
@@ -3471,7 +3476,6 @@ int cmd_main(int argc, const char **argv)
                rc_free[i].next = &rc_free[i + 1];
        rc_free[cmd_save - 1].next = NULL;
 
-       prepare_packed_git();
        start_packfile();
        set_die_routine(die_nicely);
        set_checkpoint_signal();
index 1d6117565c2067460efc50aa4e6ca2ecb167a976..adc1b68dd3ae87e6ff7501e6f3f3760c7b923d5e 100644 (file)
@@ -1,4 +1,5 @@
 #include "cache.h"
+#include "repository.h"
 #include "config.h"
 #include "lockfile.h"
 #include "refs.h"
@@ -711,6 +712,28 @@ static void mark_alternate_complete(struct object *obj)
        mark_complete(&obj->oid);
 }
 
+struct loose_object_iter {
+       struct oidset *loose_object_set;
+       struct ref *refs;
+};
+
+/*
+ *  If the number of refs is not larger than the number of loose objects,
+ *  this function stops inserting.
+ */
+static int add_loose_objects_to_set(const struct object_id *oid,
+                                   const char *path,
+                                   void *data)
+{
+       struct loose_object_iter *iter = data;
+       oidset_insert(iter->loose_object_set, oid);
+       if (iter->refs == NULL)
+               return 1;
+
+       iter->refs = iter->refs->next;
+       return 0;
+}
+
 static int everything_local(struct fetch_pack_args *args,
                            struct ref **refs,
                            struct ref **sought, int nr_sought)
@@ -719,16 +742,31 @@ static int everything_local(struct fetch_pack_args *args,
        int retval;
        int old_save_commit_buffer = save_commit_buffer;
        timestamp_t cutoff = 0;
+       struct oidset loose_oid_set = OIDSET_INIT;
+       int use_oidset = 0;
+       struct loose_object_iter iter = {&loose_oid_set, *refs};
+
+       /* Enumerate all loose objects or know refs are not so many. */
+       use_oidset = !for_each_loose_object(add_loose_objects_to_set,
+                                           &iter, 0);
 
        save_commit_buffer = 0;
 
        for (ref = *refs; ref; ref = ref->next) {
                struct object *o;
+               unsigned int flags = OBJECT_INFO_QUICK;
 
-               if (!has_object_file_with_flags(&ref->old_oid,
-                                               OBJECT_INFO_QUICK))
-                       continue;
+               if (use_oidset &&
+                   !oidset_contains(&loose_oid_set, &ref->old_oid)) {
+                       /*
+                        * I know this does not exist in the loose form,
+                        * so check if it exists in a non-loose form.
+                        */
+                       flags |= OBJECT_INFO_IGNORE_LOOSE;
+               }
 
+               if (!has_object_file_with_flags(&ref->old_oid, flags))
+                       continue;
                o = parse_object(&ref->old_oid);
                if (!o)
                        continue;
@@ -744,6 +782,8 @@ static int everything_local(struct fetch_pack_args *args,
                }
        }
 
+       oidset_clear(&loose_oid_set);
+
        if (!args->no_dependents) {
                if (!args->deepen) {
                        for_each_ref(mark_complete_oid, NULL);
@@ -1201,7 +1241,7 @@ struct ref *fetch_pack(struct fetch_pack_args *args,
        prepare_shallow_info(&si, shallow);
        ref_cpy = do_fetch_pack(args, fd, ref, sought, nr_sought,
                                &si, pack_lockfile);
-       reprepare_packed_git();
+       reprepare_packed_git(the_repository);
        update_shallow(args, sought, nr_sought, &si);
        clear_shallow_info(&si);
        return ref_cpy;
diff --git a/fsck.c b/fsck.c
index 5c8c12dde381912eccf59bbf3ed8c774344809b8..9218c2a643b83e68b9f59479bcc1be833ae8be96 100644 (file)
--- a/fsck.c
+++ b/fsck.c
@@ -811,7 +811,7 @@ static int fsck_tag_buffer(struct tag *tag, const char *data,
                enum object_type type;
 
                buffer = to_free =
-                       read_sha1_file(tag->object.oid.hash, &type, &size);
+                       read_object_file(&tag->object.oid, &type, &size);
                if (!buffer)
                        return report(options, &tag->object,
                                FSCK_MSG_MISSING_TAG_OBJECT,
index 98c76ec589b053c112ddc86b6821f2acf17b7ab0..64f21547c1ab99ef3ad98d57fe0fbadff9621838 100755 (executable)
@@ -251,8 +251,18 @@ done < "$tempdir"/backup-refs
 
 # The refs should be updated if their heads were rewritten
 git rev-parse --no-flags --revs-only --symbolic-full-name \
-       --default HEAD "$@" > "$tempdir"/raw-heads || exit
-sed -e '/^^/d' "$tempdir"/raw-heads >"$tempdir"/heads
+       --default HEAD "$@" > "$tempdir"/raw-refs || exit
+while read ref
+do
+       case "$ref" in ^?*) continue ;; esac
+
+       if git rev-parse --verify "$ref"^0 >/dev/null 2>&1
+       then
+               echo "$ref"
+       else
+               warn "WARNING: not rewriting '$ref' (not a committish)"
+       fi
+done >"$tempdir"/heads <"$tempdir"/raw-refs
 
 test -s "$tempdir"/heads ||
        die "You must specify a ref to rewrite."
@@ -310,7 +320,7 @@ git rev-list --reverse --topo-order --default HEAD \
        die "Could not get the commits"
 commits=$(wc -l <../revs | tr -d " ")
 
-test $commits -eq 0 && die "Found nothing to rewrite"
+test $commits -eq 0 && die_with_status 2 "Found nothing to rewrite"
 
 # Rewrite the commits
 report_progress ()
index 91c00e6489305a56faed6d4e89150709ba7f2aeb..6de74ce639cec90fcf7ba1797825526df675547a 100755 (executable)
@@ -3867,6 +3867,7 @@ bind .   <$M1B-Key-equal> {show_more_context;break}
 bind .   <$M1B-Key-plus> {show_more_context;break}
 bind .   <$M1B-Key-KP_Add> {show_more_context;break}
 bind .   <$M1B-Key-Return> do_commit
+bind .   <$M1B-Key-KP_Enter> do_commit
 foreach i [list $ui_index $ui_workdir] {
        bind $i <Button-1>       { toggle_or_diff click %W %x %y; break }
        bind $i <$M1B-Button-1>  { add_one_to_selection %W %x %y; break }
index aa6457bbb5f1b0d64d6e04f27394912483250117..589ff8f78aba8273651b33005c6f6abd1db2fa27 100644 (file)
@@ -2,7 +2,10 @@
 # Copyright (C) 2006, 2007 Shawn Pearce
 
 proc find_ssh_key {} {
-       foreach name {~/.ssh/id_dsa.pub ~/.ssh/id_rsa.pub ~/.ssh/identity.pub} {
+       foreach name {
+               ~/.ssh/id_dsa.pub ~/.ssh/id_ecdsa.pub ~/.ssh/id_ed25519.pub
+               ~/.ssh/id_rsa.pub ~/.ssh/identity.pub
+       } {
                if {[file exists $name]} {
                        set fh    [open $name r]
                        set cont  [read $fh]
index 351a712c8c503eb5a04466afb8aa5acd7f0259f5..88b3119a75068763cfee6d79ad4d53a83ad20a67 100644 (file)
@@ -1,6 +1,14 @@
 # Functions for supporting the use of themed Tk widgets in git-gui.
 # Copyright (C) 2009 Pat Thoyts <patthoyts@users.sourceforge.net>
 
+proc ttk_get_current_theme {} {
+       # Handle either current Tk or older versions of 8.5
+       if {[catch {set theme [ttk::style theme use]}]} {
+               set theme  $::ttk::currentTheme
+       }
+       return $theme
+}
+
 proc InitTheme {} {
        # Create a color label style (bg can be overridden by widget option)
        ttk::style layout Color.TLabel {
@@ -28,10 +36,7 @@ proc InitTheme {} {
                }
        }
 
-       # Handle either current Tk or older versions of 8.5
-       if {[catch {set theme [ttk::style theme use]}]} {
-               set theme  $::ttk::currentTheme
-       }
+       set theme [ttk_get_current_theme]
 
        if {[lsearch -exact {default alt classic clam} $theme] != -1} {
                # Simple override of standard ttk::entry to change the field
@@ -248,7 +253,7 @@ proc tspinbox {w args} {
 proc ttext {w args} {
        global use_ttk
        if {$use_ttk} {
-               switch -- [ttk::style theme use] {
+               switch -- [ttk_get_current_theme] {
                        "vista" - "xpnative" {
                                lappend args -highlightthickness 0 -borderwidth 0
                        }
index be3f068922c5a3ba0d1112f3b8b1cf1228567d2e..99b8c177875a7f26ae6c7f70be42c9d97231f7b9 100644 (file)
@@ -4,15 +4,6 @@
 # Copyright (c) 2010 Junio C Hamano.
 #
 
-# The whole contents of this file is run by dot-sourcing it from
-# inside a shell function.  It used to be that "return"s we see
-# below were not inside any function, and expected to return
-# to the function that dot-sourced us.
-#
-# However, older (9.x) versions of FreeBSD /bin/sh misbehave on such a
-# construct and continue to run the statements that follow such a "return".
-# As a work-around, we introduce an extra layer of a function
-# here, and immediately call it after defining it.
 git_rebase__am () {
 
 case "$action" in
@@ -41,60 +32,47 @@ else
 fi
 
 ret=0
-if test -n "$keep_empty"
-then
-       # we have to do this the hard way.  git format-patch completely squashes
-       # empty commits and even if it didn't the format doesn't really lend
-       # itself well to recording empty patches.  fortunately, cherry-pick
-       # makes this easy
-       git cherry-pick ${gpg_sign_opt:+"$gpg_sign_opt"} --allow-empty \
-               $allow_rerere_autoupdate --right-only "$revisions" \
-               $allow_empty_message \
-               ${restrict_revision+^$restrict_revision}
-       ret=$?
-else
-       rm -f "$GIT_DIR/rebased-patches"
+rm -f "$GIT_DIR/rebased-patches"
 
-       git format-patch -k --stdout --full-index --cherry-pick --right-only \
-               --src-prefix=a/ --dst-prefix=b/ --no-renames --no-cover-letter \
-               --pretty=mboxrd \
-               $git_format_patch_opt \
-               "$revisions" ${restrict_revision+^$restrict_revision} \
-               >"$GIT_DIR/rebased-patches"
-       ret=$?
+git format-patch -k --stdout --full-index --cherry-pick --right-only \
+       --src-prefix=a/ --dst-prefix=b/ --no-renames --no-cover-letter \
+       --pretty=mboxrd \
+       $git_format_patch_opt \
+       "$revisions" ${restrict_revision+^$restrict_revision} \
+       >"$GIT_DIR/rebased-patches"
+ret=$?
 
-       if test 0 != $ret
-       then
-               rm -f "$GIT_DIR/rebased-patches"
-               case "$head_name" in
-               refs/heads/*)
-                       git checkout -q "$head_name"
-                       ;;
-               *)
-                       git checkout -q "$orig_head"
-                       ;;
-               esac
+if test 0 != $ret
+then
+       rm -f "$GIT_DIR/rebased-patches"
+       case "$head_name" in
+       refs/heads/*)
+               git checkout -q "$head_name"
+               ;;
+       *)
+               git checkout -q "$orig_head"
+               ;;
+       esac
 
-               cat >&2 <<-EOF
+       cat >&2 <<-EOF
 
-               git encountered an error while preparing the patches to replay
-               these revisions:
+       git encountered an error while preparing the patches to replay
+       these revisions:
 
-                   $revisions
+           $revisions
 
-               As a result, git cannot rebase them.
-               EOF
-               return $ret
-       fi
+       As a result, git cannot rebase them.
+       EOF
+       return $ret
+fi
 
-       git am $git_am_opt --rebasing --resolvemsg="$resolvemsg" \
-               --patch-format=mboxrd \
-               $allow_rerere_autoupdate \
-               ${gpg_sign_opt:+"$gpg_sign_opt"} <"$GIT_DIR/rebased-patches"
-       ret=$?
+git am $git_am_opt --rebasing --resolvemsg="$resolvemsg" \
+       --patch-format=mboxrd \
+       $allow_rerere_autoupdate \
+       ${gpg_sign_opt:+"$gpg_sign_opt"} <"$GIT_DIR/rebased-patches"
+ret=$?
 
-       rm -f "$GIT_DIR/rebased-patches"
-fi
+rm -f "$GIT_DIR/rebased-patches"
 
 if test 0 != $ret
 then
@@ -105,5 +83,3 @@ fi
 move_to_original_branch
 
 }
-# ... and then we call the whole thing.
-git_rebase__am
index 331c8dfeac3cac2fd2d9d9287d5c487669fe80a0..9947e6265fe7c0bc4531fd928bbf2373a0ae7552 100644 (file)
@@ -285,7 +285,7 @@ pick_one () {
                pick_one_preserving_merges "$@" && return
        output eval git cherry-pick $allow_rerere_autoupdate $allow_empty_message \
                        ${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")} \
-                       "$strategy_args" $empty_args $ff "$@"
+                       $signoff "$strategy_args" $empty_args $ff "$@"
 
        # If cherry-pick dies it leaves the to-be-picked commit unrecorded. Reschedule
        # previous task so this commit is not lost.
@@ -307,17 +307,14 @@ pick_one_preserving_merges () {
        esac
        sha1=$(git rev-parse $sha1)
 
-       if test -f "$state_dir"/current-commit
+       if test -f "$state_dir"/current-commit && test "$fast_forward" = t
        then
-               if test "$fast_forward" = t
-               then
-                       while read current_commit
-                       do
-                               git rev-parse HEAD > "$rewritten"/$current_commit
-                       done <"$state_dir"/current-commit
-                       rm "$state_dir"/current-commit ||
-                               die "$(gettext "Cannot write current commit's replacement sha1")"
-               fi
+               while read current_commit
+               do
+                       git rev-parse HEAD > "$rewritten"/$current_commit
+               done <"$state_dir"/current-commit
+               rm "$state_dir"/current-commit ||
+                       die "$(gettext "Cannot write current commit's replacement sha1")"
        fi
 
        echo $sha1 >> "$state_dir"/current-commit
@@ -527,10 +524,10 @@ do_pick () {
                # resolve before manually running git commit --amend then git
                # rebase --continue.
                git commit --allow-empty --allow-empty-message --amend \
-                          --no-post-rewrite -n -q -C $sha1 &&
+                          --no-post-rewrite -n -q -C $sha1 $signoff &&
                        pick_one -n $sha1 &&
                        git commit --allow-empty --allow-empty-message \
-                                  --amend --no-post-rewrite -n -q -C $sha1 \
+                                  --amend --no-post-rewrite -n -q -C $sha1 $signoff \
                                   ${gpg_sign_opt:+"$gpg_sign_opt"} ||
                                   die_with_patch $sha1 "$(eval_gettext "Could not apply \$sha1... \$rest")"
        else
@@ -743,37 +740,39 @@ get_missing_commit_check_level () {
        printf '%s' "$check_level" | tr 'A-Z' 'a-z'
 }
 
-# The whole contents of this file is run by dot-sourcing it from
-# inside a shell function.  It used to be that "return"s we see
-# below were not inside any function, and expected to return
-# to the function that dot-sourced us.
+# Initiate an action. If the cannot be any
+# further action it  may exec a command
+# or exit and not return.
 #
-# However, older (9.x) versions of FreeBSD /bin/sh misbehave on such a
-# construct and continue to run the statements that follow such a "return".
-# As a work-around, we introduce an extra layer of a function
-# here, and immediately call it after defining it.
-git_rebase__interactive () {
-
-case "$action" in
-continue)
-       if test ! -d "$rewritten"
-       then
-               exec git rebase--helper ${force_rebase:+--no-ff} $allow_empty_message \
-                       --continue
-       fi
-       # do we have anything to commit?
-       if git diff-index --cached --quiet HEAD --
-       then
-               # Nothing to commit -- skip this commit
-
-               test ! -f "$GIT_DIR"/CHERRY_PICK_HEAD ||
-               rm "$GIT_DIR"/CHERRY_PICK_HEAD ||
-               die "$(gettext "Could not remove CHERRY_PICK_HEAD")"
-       else
-               if ! test -f "$author_script"
+# TODO: Consider a cleaner return model so it
+# never exits and always return 0 if process
+# is complete.
+#
+# Parameter 1 is the action to initiate.
+#
+# Returns 0 if the action was able to complete
+# and if 1 if further processing is required.
+initiate_action () {
+       case "$1" in
+       continue)
+               if test ! -d "$rewritten"
+               then
+                       exec git rebase--helper ${force_rebase:+--no-ff} $allow_empty_message \
+                               --continue
+               fi
+               # do we have anything to commit?
+               if git diff-index --cached --quiet HEAD --
                then
-                       gpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")}
-                       die "$(eval_gettext "\
+                       # Nothing to commit -- skip this commit
+
+                       test ! -f "$GIT_DIR"/CHERRY_PICK_HEAD ||
+                       rm "$GIT_DIR"/CHERRY_PICK_HEAD ||
+                       die "$(gettext "Could not remove CHERRY_PICK_HEAD")"
+               else
+                       if ! test -f "$author_script"
+                       then
+                               gpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")}
+                               die "$(eval_gettext "\
 You have staged changes in your working tree.
 If these changes are meant to be
 squashed into the previous commit, run:
@@ -788,88 +787,199 @@ In both cases, once you're done, continue with:
 
   git rebase --continue
 ")"
-               fi
-               . "$author_script" ||
-                       die "$(gettext "Error trying to find the author identity to amend commit")"
-               if test -f "$amend"
-               then
-                       current_head=$(git rev-parse --verify HEAD)
-                       test "$current_head" = $(cat "$amend") ||
-                       die "$(gettext "\
+                       fi
+                       . "$author_script" ||
+                               die "$(gettext "Error trying to find the author identity to amend commit")"
+                       if test -f "$amend"
+                       then
+                               current_head=$(git rev-parse --verify HEAD)
+                               test "$current_head" = $(cat "$amend") ||
+                               die "$(gettext "\
 You have uncommitted changes in your working tree. Please commit them
 first and then run 'git rebase --continue' again.")"
-                       do_with_author git commit --amend --no-verify -F "$msg" -e \
-                               ${gpg_sign_opt:+"$gpg_sign_opt"} $allow_empty_message ||
-                               die "$(gettext "Could not commit staged changes.")"
-               else
-                       do_with_author git commit --no-verify -F "$msg" -e \
-                               ${gpg_sign_opt:+"$gpg_sign_opt"} $allow_empty_message ||
-                               die "$(gettext "Could not commit staged changes.")"
+                               do_with_author git commit --amend --no-verify -F "$msg" -e \
+                                       ${gpg_sign_opt:+"$gpg_sign_opt"} $allow_empty_message ||
+                                       die "$(gettext "Could not commit staged changes.")"
+                       else
+                               do_with_author git commit --no-verify -F "$msg" -e \
+                                       ${gpg_sign_opt:+"$gpg_sign_opt"} $allow_empty_message ||
+                                       die "$(gettext "Could not commit staged changes.")"
+                       fi
                fi
-       fi
 
-       if test -r "$state_dir"/stopped-sha
+               if test -r "$state_dir"/stopped-sha
+               then
+                       record_in_rewritten "$(cat "$state_dir"/stopped-sha)"
+               fi
+
+               require_clean_work_tree "rebase"
+               do_rest
+               return 0
+               ;;
+       skip)
+               git rerere clear
+
+               if test ! -d "$rewritten"
+               then
+                       exec git rebase--helper ${force_rebase:+--no-ff} $allow_empty_message \
+                               --continue
+               fi
+               do_rest
+               return 0
+               ;;
+       edit-todo)
+               git stripspace --strip-comments <"$todo" >"$todo".new
+               mv -f "$todo".new "$todo"
+               collapse_todo_ids
+               append_todo_help
+               gettext "
+You are editing the todo file of an ongoing interactive rebase.
+To continue rebase after editing, run:
+    git rebase --continue
+
+" | git stripspace --comment-lines >>"$todo"
+
+               git_sequence_editor "$todo" ||
+                       die "$(gettext "Could not execute editor")"
+               expand_todo_ids
+
+               exit
+               ;;
+       show-current-patch)
+               exec git show REBASE_HEAD --
+               ;;
+       *)
+               return 1 # continue
+               ;;
+       esac
+}
+
+setup_reflog_action () {
+       comment_for_reflog start
+
+       if test ! -z "$switch_to"
        then
-               record_in_rewritten "$(cat "$state_dir"/stopped-sha)"
+               GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $switch_to"
+               output git checkout "$switch_to" -- ||
+                       die "$(eval_gettext "Could not checkout \$switch_to")"
+
+               comment_for_reflog start
        fi
+}
 
-       require_clean_work_tree "rebase"
-       do_rest
-       return 0
-       ;;
-skip)
-       git rerere clear
+init_basic_state () {
+       orig_head=$(git rev-parse --verify HEAD) || die "$(gettext "No HEAD?")"
+       mkdir -p "$state_dir" || die "$(eval_gettext "Could not create temporary \$state_dir")"
+       rm -f "$(git rev-parse --git-path REBASE_HEAD)"
 
-       if test ! -d "$rewritten"
+       : > "$state_dir"/interactive || die "$(gettext "Could not mark as interactive")"
+       write_basic_state
+}
+
+init_revisions_and_shortrevisions () {
+       shorthead=$(git rev-parse --short $orig_head)
+       shortonto=$(git rev-parse --short $onto)
+       if test -z "$rebase_root"
+               # this is now equivalent to ! -z "$upstream"
        then
-               exec git rebase--helper ${force_rebase:+--no-ff} $allow_empty_message \
-                       --continue
+               shortupstream=$(git rev-parse --short $upstream)
+               revisions=$upstream...$orig_head
+               shortrevisions=$shortupstream..$shorthead
+       else
+               revisions=$onto...$orig_head
+               shortrevisions=$shorthead
        fi
-       do_rest
-       return 0
-       ;;
-edit-todo)
-       git stripspace --strip-comments <"$todo" >"$todo".new
-       mv -f "$todo".new "$todo"
-       collapse_todo_ids
+}
+
+complete_action() {
+       test -s "$todo" || echo noop >> "$todo"
+       test -z "$autosquash" || git rebase--helper --rearrange-squash || exit
+       test -n "$cmd" && git rebase--helper --add-exec-commands "$cmd"
+
+       todocount=$(git stripspace --strip-comments <"$todo" | wc -l)
+       todocount=${todocount##* }
+
+cat >>"$todo" <<EOF
+
+$comment_char $(eval_ngettext \
+       "Rebase \$shortrevisions onto \$shortonto (\$todocount command)" \
+       "Rebase \$shortrevisions onto \$shortonto (\$todocount commands)" \
+       "$todocount")
+EOF
        append_todo_help
        gettext "
-You are editing the todo file of an ongoing interactive rebase.
-To continue rebase after editing, run:
-    git rebase --continue
+       However, if you remove everything, the rebase will be aborted.
+
+       " | git stripspace --comment-lines >>"$todo"
+
+       if test -z "$keep_empty"
+       then
+               printf '%s\n' "$comment_char $(gettext "Note that empty commits are commented out")" >>"$todo"
+       fi
 
-" | git stripspace --comment-lines >>"$todo"
 
+       has_action "$todo" ||
+               return 2
+
+       cp "$todo" "$todo".backup
+       collapse_todo_ids
        git_sequence_editor "$todo" ||
-               die "$(gettext "Could not execute editor")"
+               die_abort "$(gettext "Could not execute editor")"
+
+       has_action "$todo" ||
+               return 2
+
+       git rebase--helper --check-todo-list || {
+               ret=$?
+               checkout_onto
+               exit $ret
+       }
+
        expand_todo_ids
 
-       exit
-       ;;
-show-current-patch)
-       exec git show REBASE_HEAD --
-       ;;
-esac
+       test -d "$rewritten" || test -n "$force_rebase" ||
+       onto="$(git rebase--helper --skip-unnecessary-picks)" ||
+       die "Could not skip unnecessary pick commands"
 
-comment_for_reflog start
+       checkout_onto
+       if test -z "$rebase_root" && test ! -d "$rewritten"
+       then
+               require_clean_work_tree "rebase"
+               exec git rebase--helper ${force_rebase:+--no-ff} $allow_empty_message \
+                       --continue
+       fi
+       do_rest
+}
 
-if test ! -z "$switch_to"
-then
-       GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $switch_to"
-       output git checkout "$switch_to" -- ||
-               die "$(eval_gettext "Could not checkout \$switch_to")"
+git_rebase__interactive () {
+       initiate_action "$action"
+       ret=$?
+       if test $ret = 0; then
+               return 0
+       fi
 
-       comment_for_reflog start
-fi
+       setup_reflog_action
+       init_basic_state
 
-orig_head=$(git rev-parse --verify HEAD) || die "$(gettext "No HEAD?")"
-mkdir -p "$state_dir" || die "$(eval_gettext "Could not create temporary \$state_dir")"
-rm -f "$(git rev-parse --git-path REBASE_HEAD)"
+       init_revisions_and_shortrevisions
+
+       git rebase--helper --make-script ${keep_empty:+--keep-empty} \
+               $revisions ${restrict_revision+^$restrict_revision} >"$todo" ||
+       die "$(gettext "Could not generate todo list")"
+
+       complete_action
+}
+
+git_rebase__interactive__preserve_merges () {
+       initiate_action "$action"
+       ret=$?
+       if test $ret = 0; then
+               return 0
+       fi
+
+       setup_reflog_action
+       init_basic_state
 
-: > "$state_dir"/interactive || die "$(gettext "Could not mark as interactive")"
-write_basic_state
-if test t = "$preserve_merges"
-then
        if test -z "$rebase_root"
        then
                mkdir "$rewritten" &&
@@ -883,41 +993,17 @@ then
                echo $onto > "$rewritten"/root ||
                        die "$(gettext "Could not init rewritten commits")"
        fi
-       # No cherry-pick because our first pass is to determine
-       # parents to rewrite and skipping dropped commits would
-       # prematurely end our probe
-       merges_option=
-else
-       merges_option="--no-merges --cherry-pick"
-fi
-
-shorthead=$(git rev-parse --short $orig_head)
-shortonto=$(git rev-parse --short $onto)
-if test -z "$rebase_root"
-       # this is now equivalent to ! -z "$upstream"
-then
-       shortupstream=$(git rev-parse --short $upstream)
-       revisions=$upstream...$orig_head
-       shortrevisions=$shortupstream..$shorthead
-else
-       revisions=$onto...$orig_head
-       shortrevisions=$shorthead
-fi
-if test t != "$preserve_merges"
-then
-       git rebase--helper --make-script ${keep_empty:+--keep-empty} \
-               $revisions ${restrict_revision+^$restrict_revision} >"$todo" ||
-       die "$(gettext "Could not generate todo list")"
-else
+
+       init_revisions_and_shortrevisions
+
        format=$(git config --get rebase.instructionFormat)
        # the 'rev-list .. | sed' requires %m to parse; the instruction requires %H to parse
-       git rev-list $merges_option --format="%m%H ${format:-%s}" \
+       git rev-list --format="%m%H ${format:-%s}" \
                --reverse --left-right --topo-order \
                $revisions ${restrict_revision+^$restrict_revision} | \
                sed -n "s/^>//p" |
        while read -r sha1 rest
        do
-
                if test -z "$keep_empty" && is_empty_commit $sha1 && ! is_merge_commit $sha1
                then
                        comment_out="$comment_char "
@@ -944,11 +1030,8 @@ else
                        printf '%s\n' "${comment_out}pick $sha1 $rest" >>"$todo"
                fi
        done
-fi
 
-# Watch for commits that been dropped by --cherry-pick
-if test t = "$preserve_merges"
-then
+       # Watch for commits that been dropped by --cherry-pick
        mkdir "$dropped"
        # Save all non-cherry-picked changes
        git rev-list $revisions --left-right --cherry-pick | \
@@ -971,66 +1054,6 @@ then
                        rm "$rewritten"/$rev
                fi
        done
-fi
-
-test -s "$todo" || echo noop >> "$todo"
-test -z "$autosquash" || git rebase--helper --rearrange-squash || exit
-test -n "$cmd" && git rebase--helper --add-exec-commands "$cmd"
-
-todocount=$(git stripspace --strip-comments <"$todo" | wc -l)
-todocount=${todocount##* }
-
-cat >>"$todo" <<EOF
-
-$comment_char $(eval_ngettext \
-       "Rebase \$shortrevisions onto \$shortonto (\$todocount command)" \
-       "Rebase \$shortrevisions onto \$shortonto (\$todocount commands)" \
-       "$todocount")
-EOF
-append_todo_help
-gettext "
-However, if you remove everything, the rebase will be aborted.
-
-" | git stripspace --comment-lines >>"$todo"
-
-if test -z "$keep_empty"
-then
-       printf '%s\n' "$comment_char $(gettext "Note that empty commits are commented out")" >>"$todo"
-fi
-
-
-has_action "$todo" ||
-       return 2
-
-cp "$todo" "$todo".backup
-collapse_todo_ids
-git_sequence_editor "$todo" ||
-       die_abort "$(gettext "Could not execute editor")"
-
-has_action "$todo" ||
-       return 2
-
-git rebase--helper --check-todo-list || {
-       ret=$?
-       checkout_onto
-       exit $ret
-}
-
-expand_todo_ids
-
-test -d "$rewritten" || test -n "$force_rebase" ||
-onto="$(git rebase--helper --skip-unnecessary-picks)" ||
-die "Could not skip unnecessary pick commands"
-
-checkout_onto
-if test -z "$rebase_root" && test ! -d "$rewritten"
-then
-       require_clean_work_tree "rebase"
-       exec git rebase--helper ${force_rebase:+--no-ff} $allow_empty_message \
-               --continue
-fi
-do_rest
 
+       complete_action
 }
-# ... and then we call the whole thing.
-git_rebase__interactive
index ceb715453cc9eba0b6e91abfd2ea3863e74f3e05..cf4c0422148935906ad939c5351652a1531e5f0d 100644 (file)
@@ -27,7 +27,7 @@ continue_merge () {
        cmt=$(cat "$state_dir/current")
        if ! git diff-index --quiet --ignore-submodules HEAD --
        then
-               if ! git commit ${gpg_sign_opt:+"$gpg_sign_opt"} $allow_empty_message \
+               if ! git commit ${gpg_sign_opt:+"$gpg_sign_opt"} $signoff $allow_empty_message \
                        --no-verify -C "$cmt"
                then
                        echo "Commit failed, please do not call \"git commit\""
@@ -104,15 +104,6 @@ finish_rb_merge () {
        say All done.
 }
 
-# The whole contents of this file is run by dot-sourcing it from
-# inside a shell function.  It used to be that "return"s we see
-# below were not inside any function, and expected to return
-# to the function that dot-sourced us.
-#
-# However, older (9.x) versions of FreeBSD /bin/sh misbehave on such a
-# construct and continue to run the statements that follow such a "return".
-# As a work-around, we introduce an extra layer of a function
-# here, and immediately call it after defining it.
 git_rebase__merge () {
 
 case "$action" in
@@ -171,5 +162,3 @@ done
 finish_rb_merge
 
 }
-# ... and then we call the whole thing.
-git_rebase__merge
index a1f6e5de6a3ed1fe9a6217a136611682f3db6582..ded5de085a87505b244b7449b1977c3779650640 100755 (executable)
@@ -62,6 +62,7 @@ $(gettext 'Resolve all conflicts manually, mark them as resolved with
 You can instead skip this commit: run "git rebase --skip".
 To abort and get back to the state before "git rebase", run "git rebase --abort".')
 "
+squash_onto=
 unset onto
 unset restrict_revision
 cmd=
@@ -92,6 +93,7 @@ preserve_merges=
 autosquash=
 keep_empty=
 allow_empty_message=
+signoff=
 test "$(git config --bool rebase.autosquash)" = "true" && autosquash=t
 case "$(git config --bool commit.gpgsign)" in
 true)  gpg_sign_opt=-S ;;
@@ -121,6 +123,10 @@ read_basic_state () {
                allow_rerere_autoupdate="$(cat "$state_dir"/allow_rerere_autoupdate)"
        test -f "$state_dir"/gpg_sign_opt &&
                gpg_sign_opt="$(cat "$state_dir"/gpg_sign_opt)"
+       test -f "$state_dir"/signoff && {
+               signoff="$(cat "$state_dir"/signoff)"
+               force_rebase=t
+       }
 }
 
 write_basic_state () {
@@ -135,6 +141,7 @@ write_basic_state () {
        test -n "$allow_rerere_autoupdate" && echo "$allow_rerere_autoupdate" > \
                "$state_dir"/allow_rerere_autoupdate
        test -n "$gpg_sign_opt" && echo "$gpg_sign_opt" > "$state_dir"/gpg_sign_opt
+       test -n "$signoff" && echo "$signoff" >"$state_dir"/signoff
 }
 
 output () {
@@ -197,6 +204,7 @@ run_specific_rebase () {
                autosquash=
        fi
        . git-rebase--$type
+       git_rebase__$type${preserve_merges:+__preserve_merges}
        ret=$?
        if test $ret -eq 0
        then
@@ -269,6 +277,9 @@ do
        --allow-empty-message)
                allow_empty_message=--allow-empty-message
                ;;
+       --no-keep-empty)
+               keep_empty=
+               ;;
        --preserve-merges)
                preserve_merges=t
                test -z "$interactive_rebase" && interactive_rebase=implied
@@ -331,7 +342,13 @@ do
        --ignore-whitespace)
                git_am_opt="$git_am_opt $1"
                ;;
-       --committer-date-is-author-date|--ignore-date|--signoff|--no-signoff)
+       --signoff)
+               signoff=--signoff
+               ;;
+       --no-signoff)
+               signoff=
+               ;;
+       --committer-date-is-author-date|--ignore-date)
                git_am_opt="$git_am_opt $1"
                force_rebase=t
                ;;
@@ -447,6 +464,11 @@ then
        test -z "$interactive_rebase" && interactive_rebase=implied
 fi
 
+if test -n "$keep_empty"
+then
+       test -z "$interactive_rebase" && interactive_rebase=implied
+fi
+
 if test -n "$interactive_rebase"
 then
        type=interactive
@@ -465,6 +487,14 @@ then
        git_format_patch_opt="$git_format_patch_opt --progress"
 fi
 
+if test -n "$signoff"
+then
+       test -n "$preserve_merges" &&
+               die "$(gettext "error: cannot combine '--signoff' with '--preserve-merges'")"
+       git_am_opt="$git_am_opt $signoff"
+       force_rebase=t
+fi
+
 if test -z "$rebase_root"
 then
        case "$#" in
index fc8f8ae6401dddcceaa82f9e9c748f5c185536d6..94793c1a913abf569ff9101d935c355b9eb27648 100755 (executable)
@@ -39,7 +39,7 @@ fi
 no_changes () {
        git diff-index --quiet --cached HEAD --ignore-submodules -- "$@" &&
        git diff-files --quiet --ignore-submodules -- "$@" &&
-       (test -z "$untracked" || test -z "$(untracked_files)")
+       (test -z "$untracked" || test -z "$(untracked_files "$@")")
 }
 
 untracked_files () {
@@ -315,16 +315,18 @@ push_stash () {
        if test -z "$patch_mode"
        then
                test "$untracked" = "all" && CLEAN_X_OPTION=-x || CLEAN_X_OPTION=
-               if test -n "$untracked"
+               if test -n "$untracked" && test $# = 0
                then
-                       git clean --force --quiet -d $CLEAN_X_OPTION -- "$@"
+                       git clean --force --quiet -d $CLEAN_X_OPTION
                fi
 
                if test $# != 0
                then
-                       git add -u -- "$@" |
-                       git checkout-index -z --force --stdin
-                       git diff-index -p --cached --binary HEAD -- "$@" | git apply --index -R
+                       test -z "$untracked" && UPDATE_OPTION="-u" || UPDATE_OPTION=
+                       test "$untracked" = "all" && FORCE_OPTION="--force" || FORCE_OPTION=
+                       git add $UPDATE_OPTION $FORCE_OPTION -- "$@"
+                       git diff-index -p --cached --binary HEAD -- "$@" |
+                       git apply --index -R
                else
                        git reset --hard -q
                fi
index a6b6c3e40c180e58186f9ef8af5c6fd6fc654080..050f2a36f414f147f3bde3cc9f69639d5a36a975 100755 (executable)
@@ -374,7 +374,8 @@ sub term_init {
 usage(1) unless defined $cmd;
 load_authors() if $_authors;
 if (defined $_authors_prog) {
-       $_authors_prog = "'" . File::Spec->rel2abs($_authors_prog) . "'";
+       my $abs_file = File::Spec->rel2abs($_authors_prog);
+       $_authors_prog = "'" . $abs_file . "'" if -x $abs_file;
 }
 
 unless ($cmd =~ /^(?:clone|init|multi-init|commit-diff)$/) {
diff --git a/git.c b/git.c
index ceaa58ef40e536f1290cce3ad1223004063e41a6..3a89893712e6b327e714ad81d12d3e4ca354926c 100644 (file)
--- a/git.c
+++ b/git.c
@@ -4,6 +4,24 @@
 #include "help.h"
 #include "run-command.h"
 
+#define RUN_SETUP              (1<<0)
+#define RUN_SETUP_GENTLY       (1<<1)
+#define USE_PAGER              (1<<2)
+/*
+ * require working tree to be present -- anything uses this needs
+ * RUN_SETUP for reading from the configuration file.
+ */
+#define NEED_WORK_TREE         (1<<3)
+#define SUPPORT_SUPER_PREFIX   (1<<4)
+#define DELAY_PAGER_CONFIG     (1<<5)
+#define NO_PARSEOPT            (1<<6) /* parse-options is not used */
+
+struct cmd_struct {
+       const char *cmd;
+       int (*fn)(int, const char **, const char *);
+       unsigned int option;
+};
+
 const char git_usage_string[] =
        N_("git [--version] [--help] [-C <path>] [-c <name>=<value>]\n"
           "           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
@@ -18,7 +36,7 @@ const char git_more_info_string[] =
 
 static int use_pager = -1;
 
-static void list_builtins(void);
+static void list_builtins(unsigned int exclude_option, char sep);
 
 static void commit_pager_choice(void) {
        switch (use_pager) {
@@ -206,7 +224,10 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
                        (*argv)++;
                        (*argc)--;
                } else if (!strcmp(cmd, "--list-builtins")) {
-                       list_builtins();
+                       list_builtins(0, '\n');
+                       exit(0);
+               } else if (!strcmp(cmd, "--list-parseopt-builtins")) {
+                       list_builtins(NO_PARSEOPT, ' ');
                        exit(0);
                } else {
                        fprintf(stderr, _("unknown option: %s\n"), cmd);
@@ -288,23 +309,6 @@ static int handle_alias(int *argcp, const char ***argv)
        return ret;
 }
 
-#define RUN_SETUP              (1<<0)
-#define RUN_SETUP_GENTLY       (1<<1)
-#define USE_PAGER              (1<<2)
-/*
- * require working tree to be present -- anything uses this needs
- * RUN_SETUP for reading from the configuration file.
- */
-#define NEED_WORK_TREE         (1<<3)
-#define SUPPORT_SUPER_PREFIX   (1<<4)
-#define DELAY_PAGER_CONFIG     (1<<5)
-
-struct cmd_struct {
-       const char *cmd;
-       int (*fn)(int, const char **, const char *);
-       int option;
-};
-
 static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
 {
        int status, help;
@@ -367,18 +371,18 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
 static struct cmd_struct commands[] = {
        { "add", cmd_add, RUN_SETUP | NEED_WORK_TREE },
        { "am", cmd_am, RUN_SETUP | NEED_WORK_TREE },
-       { "annotate", cmd_annotate, RUN_SETUP },
+       { "annotate", cmd_annotate, RUN_SETUP | NO_PARSEOPT },
        { "apply", cmd_apply, RUN_SETUP_GENTLY },
        { "archive", cmd_archive, RUN_SETUP_GENTLY },
        { "bisect--helper", cmd_bisect__helper, RUN_SETUP },
        { "blame", cmd_blame, RUN_SETUP },
        { "branch", cmd_branch, RUN_SETUP | DELAY_PAGER_CONFIG },
-       { "bundle", cmd_bundle, RUN_SETUP_GENTLY },
+       { "bundle", cmd_bundle, RUN_SETUP_GENTLY | NO_PARSEOPT },
        { "cat-file", cmd_cat_file, RUN_SETUP },
        { "check-attr", cmd_check_attr, RUN_SETUP },
        { "check-ignore", cmd_check_ignore, RUN_SETUP | NEED_WORK_TREE },
        { "check-mailmap", cmd_check_mailmap, RUN_SETUP },
-       { "check-ref-format", cmd_check_ref_format },
+       { "check-ref-format", cmd_check_ref_format, NO_PARSEOPT  },
        { "checkout", cmd_checkout, RUN_SETUP | NEED_WORK_TREE },
        { "checkout-index", cmd_checkout_index,
                RUN_SETUP | NEED_WORK_TREE},
@@ -388,30 +392,30 @@ static struct cmd_struct commands[] = {
        { "clone", cmd_clone },
        { "column", cmd_column, RUN_SETUP_GENTLY },
        { "commit", cmd_commit, RUN_SETUP | NEED_WORK_TREE },
-       { "commit-tree", cmd_commit_tree, RUN_SETUP },
+       { "commit-tree", cmd_commit_tree, RUN_SETUP | NO_PARSEOPT },
        { "config", cmd_config, RUN_SETUP_GENTLY | DELAY_PAGER_CONFIG },
        { "count-objects", cmd_count_objects, RUN_SETUP },
-       { "credential", cmd_credential, RUN_SETUP_GENTLY },
+       { "credential", cmd_credential, RUN_SETUP_GENTLY | NO_PARSEOPT },
        { "describe", cmd_describe, RUN_SETUP },
-       { "diff", cmd_diff },
-       { "diff-files", cmd_diff_files, RUN_SETUP | NEED_WORK_TREE },
-       { "diff-index", cmd_diff_index, RUN_SETUP },
-       { "diff-tree", cmd_diff_tree, RUN_SETUP },
+       { "diff", cmd_diff, NO_PARSEOPT },
+       { "diff-files", cmd_diff_files, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT },
+       { "diff-index", cmd_diff_index, RUN_SETUP | NO_PARSEOPT },
+       { "diff-tree", cmd_diff_tree, RUN_SETUP | NO_PARSEOPT },
        { "difftool", cmd_difftool, RUN_SETUP | NEED_WORK_TREE },
        { "fast-export", cmd_fast_export, RUN_SETUP },
        { "fetch", cmd_fetch, RUN_SETUP },
-       { "fetch-pack", cmd_fetch_pack, RUN_SETUP },
+       { "fetch-pack", cmd_fetch_pack, RUN_SETUP | NO_PARSEOPT },
        { "fmt-merge-msg", cmd_fmt_merge_msg, RUN_SETUP },
        { "for-each-ref", cmd_for_each_ref, RUN_SETUP },
        { "format-patch", cmd_format_patch, RUN_SETUP },
        { "fsck", cmd_fsck, RUN_SETUP },
        { "fsck-objects", cmd_fsck, RUN_SETUP },
        { "gc", cmd_gc, RUN_SETUP },
-       { "get-tar-commit-id", cmd_get_tar_commit_id },
+       { "get-tar-commit-id", cmd_get_tar_commit_id, NO_PARSEOPT },
        { "grep", cmd_grep, RUN_SETUP_GENTLY },
        { "hash-object", cmd_hash_object },
        { "help", cmd_help },
-       { "index-pack", cmd_index_pack, RUN_SETUP_GENTLY },
+       { "index-pack", cmd_index_pack, RUN_SETUP_GENTLY | NO_PARSEOPT },
        { "init", cmd_init_db },
        { "init-db", cmd_init_db },
        { "interpret-trailers", cmd_interpret_trailers, RUN_SETUP_GENTLY },
@@ -419,27 +423,27 @@ static struct cmd_struct commands[] = {
        { "ls-files", cmd_ls_files, RUN_SETUP },
        { "ls-remote", cmd_ls_remote, RUN_SETUP_GENTLY },
        { "ls-tree", cmd_ls_tree, RUN_SETUP },
-       { "mailinfo", cmd_mailinfo, RUN_SETUP_GENTLY },
-       { "mailsplit", cmd_mailsplit },
+       { "mailinfo", cmd_mailinfo, RUN_SETUP_GENTLY | NO_PARSEOPT },
+       { "mailsplit", cmd_mailsplit, NO_PARSEOPT },
        { "merge", cmd_merge, RUN_SETUP | NEED_WORK_TREE },
        { "merge-base", cmd_merge_base, RUN_SETUP },
        { "merge-file", cmd_merge_file, RUN_SETUP_GENTLY },
-       { "merge-index", cmd_merge_index, RUN_SETUP },
-       { "merge-ours", cmd_merge_ours, RUN_SETUP },
-       { "merge-recursive", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE },
-       { "merge-recursive-ours", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE },
-       { "merge-recursive-theirs", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE },
-       { "merge-subtree", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE },
-       { "merge-tree", cmd_merge_tree, RUN_SETUP },
-       { "mktag", cmd_mktag, RUN_SETUP },
+       { "merge-index", cmd_merge_index, RUN_SETUP | NO_PARSEOPT },
+       { "merge-ours", cmd_merge_ours, RUN_SETUP | NO_PARSEOPT },
+       { "merge-recursive", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT },
+       { "merge-recursive-ours", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT },
+       { "merge-recursive-theirs", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT },
+       { "merge-subtree", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT },
+       { "merge-tree", cmd_merge_tree, RUN_SETUP | NO_PARSEOPT },
+       { "mktag", cmd_mktag, RUN_SETUP | NO_PARSEOPT },
        { "mktree", cmd_mktree, RUN_SETUP },
        { "mv", cmd_mv, RUN_SETUP | NEED_WORK_TREE },
        { "name-rev", cmd_name_rev, RUN_SETUP },
        { "notes", cmd_notes, RUN_SETUP },
        { "pack-objects", cmd_pack_objects, RUN_SETUP },
-       { "pack-redundant", cmd_pack_redundant, RUN_SETUP },
+       { "pack-redundant", cmd_pack_redundant, RUN_SETUP | NO_PARSEOPT },
        { "pack-refs", cmd_pack_refs, RUN_SETUP },
-       { "patch-id", cmd_patch_id, RUN_SETUP_GENTLY },
+       { "patch-id", cmd_patch_id, RUN_SETUP_GENTLY | NO_PARSEOPT },
        { "pickaxe", cmd_blame, RUN_SETUP },
        { "prune", cmd_prune, RUN_SETUP },
        { "prune-packed", cmd_prune_packed, RUN_SETUP },
@@ -450,14 +454,14 @@ static struct cmd_struct commands[] = {
        { "receive-pack", cmd_receive_pack },
        { "reflog", cmd_reflog, RUN_SETUP },
        { "remote", cmd_remote, RUN_SETUP },
-       { "remote-ext", cmd_remote_ext },
-       { "remote-fd", cmd_remote_fd },
+       { "remote-ext", cmd_remote_ext, NO_PARSEOPT },
+       { "remote-fd", cmd_remote_fd, NO_PARSEOPT },
        { "repack", cmd_repack, RUN_SETUP },
        { "replace", cmd_replace, RUN_SETUP },
        { "rerere", cmd_rerere, RUN_SETUP },
        { "reset", cmd_reset, RUN_SETUP },
-       { "rev-list", cmd_rev_list, RUN_SETUP },
-       { "rev-parse", cmd_rev_parse },
+       { "rev-list", cmd_rev_list, RUN_SETUP | NO_PARSEOPT },
+       { "rev-parse", cmd_rev_parse, NO_PARSEOPT },
        { "revert", cmd_revert, RUN_SETUP | NEED_WORK_TREE },
        { "rm", cmd_rm, RUN_SETUP },
        { "send-pack", cmd_send_pack, RUN_SETUP },
@@ -468,23 +472,23 @@ static struct cmd_struct commands[] = {
        { "stage", cmd_add, RUN_SETUP | NEED_WORK_TREE },
        { "status", cmd_status, RUN_SETUP | NEED_WORK_TREE },
        { "stripspace", cmd_stripspace },
-       { "submodule--helper", cmd_submodule__helper, RUN_SETUP | SUPPORT_SUPER_PREFIX},
+       { "submodule--helper", cmd_submodule__helper, RUN_SETUP | SUPPORT_SUPER_PREFIX | NO_PARSEOPT },
        { "symbolic-ref", cmd_symbolic_ref, RUN_SETUP },
        { "tag", cmd_tag, RUN_SETUP | DELAY_PAGER_CONFIG },
-       { "unpack-file", cmd_unpack_file, RUN_SETUP },
-       { "unpack-objects", cmd_unpack_objects, RUN_SETUP },
+       { "unpack-file", cmd_unpack_file, RUN_SETUP | NO_PARSEOPT },
+       { "unpack-objects", cmd_unpack_objects, RUN_SETUP | NO_PARSEOPT },
        { "update-index", cmd_update_index, RUN_SETUP },
        { "update-ref", cmd_update_ref, RUN_SETUP },
        { "update-server-info", cmd_update_server_info, RUN_SETUP },
-       { "upload-archive", cmd_upload_archive },
-       { "upload-archive--writer", cmd_upload_archive_writer },
-       { "var", cmd_var, RUN_SETUP_GENTLY },
+       { "upload-archive", cmd_upload_archive, NO_PARSEOPT },
+       { "upload-archive--writer", cmd_upload_archive_writer, NO_PARSEOPT },
+       { "var", cmd_var, RUN_SETUP_GENTLY | NO_PARSEOPT },
        { "verify-commit", cmd_verify_commit, RUN_SETUP },
        { "verify-pack", cmd_verify_pack },
        { "verify-tag", cmd_verify_tag, RUN_SETUP },
        { "version", cmd_version },
        { "whatchanged", cmd_whatchanged, RUN_SETUP },
-       { "worktree", cmd_worktree, RUN_SETUP },
+       { "worktree", cmd_worktree, RUN_SETUP | NO_PARSEOPT },
        { "write-tree", cmd_write_tree, RUN_SETUP },
 };
 
@@ -504,11 +508,15 @@ int is_builtin(const char *s)
        return !!get_builtin(s);
 }
 
-static void list_builtins(void)
+static void list_builtins(unsigned int exclude_option, char sep)
 {
        int i;
-       for (i = 0; i < ARRAY_SIZE(commands); i++)
-               printf("%s\n", commands[i].cmd);
+       for (i = 0; i < ARRAY_SIZE(commands); i++) {
+               if (exclude_option &&
+                   (commands[i].option & exclude_option))
+                       continue;
+               printf("%s%c", commands[i].cmd, sep);
+       }
 }
 
 #ifdef STRIP_EXTENSION
diff --git a/grep.c b/grep.c
index 834b8eb439297ff5af4a3da8b946a40ca68057f1..65b90c10a38c136d2ce9a42fee5c543cd7d4717d 100644 (file)
--- a/grep.c
+++ b/grep.c
@@ -2015,7 +2015,7 @@ static int grep_source_load_oid(struct grep_source *gs)
        enum object_type type;
 
        grep_read_lock();
-       gs->buf = read_sha1_file(gs->identifier, &type, &gs->size);
+       gs->buf = read_object_file(gs->identifier, &type, &gs->size);
        grep_read_unlock();
 
        if (!gs->buf)
index f3dc218b2a3d2662efda56fb6c8878a37a4e67a4..88d2a9bc40b4b02e96a6679e856e3a9d1a4a0359 100644 (file)
@@ -1,5 +1,6 @@
 #include "cache.h"
 #include "config.h"
+#include "repository.h"
 #include "refs.h"
 #include "pkt-line.h"
 #include "object.h"
@@ -10,6 +11,7 @@
 #include "url.h"
 #include "argv-array.h"
 #include "packfile.h"
+#include "object-store.h"
 
 static const char content_type[] = "Content-Type";
 static const char content_length[] = "Content-Length";
@@ -517,14 +519,13 @@ static void get_info_packs(struct strbuf *hdr, char *arg)
        size_t cnt = 0;
 
        select_getanyfile(hdr);
-       prepare_packed_git();
-       for (p = packed_git; p; p = p->next) {
+       for (p = get_packed_git(the_repository); p; p = p->next) {
                if (p->pack_local)
                        cnt++;
        }
 
        strbuf_grow(&buf, cnt * 53 + 2);
-       for (p = packed_git; p; p = p->next) {
+       for (p = get_packed_git(the_repository); p; p = p->next) {
                if (p->pack_local)
                        strbuf_addf(&buf, "P %s\n", p->pack_name + objdirlen + 6);
        }
index 7dcd9daf62cf07e1cc43022fde17607cef6dc147..c0998fd763b6178aa7c0d35603c9b56183d5157f 100644 (file)
@@ -12,6 +12,7 @@
 #include "sigchain.h"
 #include "argv-array.h"
 #include "packfile.h"
+#include "object-store.h"
 
 #ifdef EXPAT_NEEDS_XMLPARSE_H
 #include <xmlparse.h>
@@ -361,7 +362,7 @@ static void start_put(struct transfer_request *request)
        ssize_t size;
        git_zstream stream;
 
-       unpacked = read_sha1_file(request->obj->oid.hash, &type, &len);
+       unpacked = read_object_file(&request->obj->oid, &type, &len);
        hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %lu", type_name(type), len) + 1;
 
        /* Set it up */
index 07c2b1af826d3e24e2568e5bdef17806f355048f..7cdfb2f24c76d2f09b39ae2fa97685ecec2d1630 100644 (file)
@@ -1,10 +1,12 @@
 #include "cache.h"
+#include "repository.h"
 #include "commit.h"
 #include "walker.h"
 #include "http.h"
 #include "list.h"
 #include "transport.h"
 #include "packfile.h"
+#include "object-store.h"
 
 struct alt_base {
        char *base;
@@ -22,7 +24,7 @@ enum object_request_state {
 
 struct object_request {
        struct walker *walker;
-       unsigned char sha1[20];
+       struct object_id oid;
        struct alt_base *repo;
        enum object_request_state state;
        struct http_object_request *req;
@@ -56,7 +58,7 @@ static void start_object_request(struct walker *walker,
        struct active_request_slot *slot;
        struct http_object_request *req;
 
-       req = new_http_object_request(obj_req->repo->base, obj_req->sha1);
+       req = new_http_object_request(obj_req->repo->base, obj_req->oid.hash);
        if (req == NULL) {
                obj_req->state = ABORTED;
                return;
@@ -82,7 +84,7 @@ static void finish_object_request(struct object_request *obj_req)
                return;
 
        if (obj_req->req->rename == 0)
-               walker_say(obj_req->walker, "got %s\n", sha1_to_hex(obj_req->sha1));
+               walker_say(obj_req->walker, "got %s\n", oid_to_hex(&obj_req->oid));
 }
 
 static void process_object_response(void *callback_data)
@@ -129,7 +131,7 @@ static int fill_active_slot(struct walker *walker)
        list_for_each_safe(pos, tmp, head) {
                obj_req = list_entry(pos, struct object_request, node);
                if (obj_req->state == WAITING) {
-                       if (has_sha1_file(obj_req->sha1))
+                       if (has_sha1_file(obj_req->oid.hash))
                                obj_req->state = COMPLETE;
                        else {
                                start_object_request(walker, obj_req);
@@ -148,7 +150,7 @@ static void prefetch(struct walker *walker, unsigned char *sha1)
 
        newreq = xmalloc(sizeof(*newreq));
        newreq->walker = walker;
-       hashcpy(newreq->sha1, sha1);
+       hashcpy(newreq->oid.hash, sha1);
        newreq->repo = data->alt;
        newreq->state = WAITING;
        newreq->req = NULL;
@@ -481,13 +483,13 @@ static int fetch_object(struct walker *walker, unsigned char *sha1)
 
        list_for_each(pos, head) {
                obj_req = list_entry(pos, struct object_request, node);
-               if (!hashcmp(obj_req->sha1, sha1))
+               if (!hashcmp(obj_req->oid.hash, sha1))
                        break;
        }
        if (obj_req == NULL)
                return error("Couldn't find request for %s in the queue", hex);
 
-       if (has_sha1_file(obj_req->sha1)) {
+       if (has_sha1_file(obj_req->oid.hash)) {
                if (obj_req->req != NULL)
                        abort_http_object_request(obj_req->req);
                abort_object_request(obj_req);
@@ -541,11 +543,11 @@ static int fetch_object(struct walker *walker, unsigned char *sha1)
        } else if (req->zret != Z_STREAM_END) {
                walker->corrupt_object_found++;
                ret = error("File %s (%s) corrupt", hex, req->url);
-       } else if (hashcmp(obj_req->sha1, req->real_sha1)) {
+       } else if (hashcmp(obj_req->oid.hash, req->real_sha1)) {
                ret = error("File %s has bad hash", hex);
        } else if (req->rename < 0) {
                struct strbuf buf = STRBUF_INIT;
-               sha1_file_name(&buf, req->sha1);
+               sha1_file_name(the_repository, &buf, req->sha1);
                ret = error("unable to write sha1 filename %s", buf.buf);
                strbuf_release(&buf);
        }
diff --git a/http.c b/http.c
index a5bd5d62c22c054f82b9971fc1f320c643f1d6fb..3034d10b6804387bc267b27757e2eae2279415d5 100644 (file)
--- a/http.c
+++ b/http.c
@@ -14,6 +14,7 @@
 #include "packfile.h"
 #include "protocol.h"
 #include "string-list.h"
+#include "object-store.h"
 
 static struct trace_key trace_curl = TRACE_KEY_INIT(CURL);
 static int trace_curl_data = 1;
@@ -62,6 +63,9 @@ static struct {
        { "tlsv1.1", CURL_SSLVERSION_TLSv1_1 },
        { "tlsv1.2", CURL_SSLVERSION_TLSv1_2 },
 #endif
+#if LIBCURL_VERSION_NUM >= 0x073400
+       { "tlsv1.3", CURL_SSLVERSION_TLSv1_3 },
+#endif
 };
 #if LIBCURL_VERSION_NUM >= 0x070903
 static const char *ssl_key;
@@ -2135,7 +2139,7 @@ int finish_http_pack_request(struct http_pack_request *preq)
                return -1;
        }
 
-       install_packed_git(p);
+       install_packed_git(the_repository, p);
        free(tmp_idx);
        return 0;
 }
@@ -2248,7 +2252,7 @@ struct http_object_request *new_http_object_request(const char *base_url,
        hashcpy(freq->sha1, sha1);
        freq->localfile = -1;
 
-       sha1_file_name(&filename, sha1);
+       sha1_file_name(the_repository, &filename, sha1);
        snprintf(freq->tmpfile, sizeof(freq->tmpfile),
                 "%s.temp", filename.buf);
 
@@ -2397,8 +2401,7 @@ int finish_http_object_request(struct http_object_request *freq)
                unlink_or_warn(freq->tmpfile);
                return -1;
        }
-
-       sha1_file_name(&filename, freq->sha1);
+       sha1_file_name(the_repository, &filename, freq->sha1);
        freq->rename = finalize_object_file(freq->tmpfile, filename.buf);
        strbuf_release(&filename);
 
index cdc2257db56f7d68412bb456e91854a9e9aa5cd5..ecdce08c4be24cc14109796d9a7c165c53753a88 100644 (file)
@@ -501,8 +501,7 @@ static void fill_blob_sha1(struct commit *commit, struct diff_filespec *spec)
        unsigned mode;
        struct object_id oid;
 
-       if (get_tree_entry(commit->object.oid.hash, spec->path,
-                          oid.hash, &mode))
+       if (get_tree_entry(&commit->object.oid, spec->path, &oid, &mode))
                die("There is no path %s in the commit", spec->path);
        fill_filespec(spec, &oid, 1, mode);
 
index 4356c45368e10bd7f41e15f91130dbfd3e4e9281..0ec83aaf1888903be4f1de38c8a94a594ef2130a 100644 (file)
@@ -117,7 +117,7 @@ static enum list_objects_filter_result filter_blobs_limit(
                assert(obj->type == OBJ_BLOB);
                assert((obj->flags & SEEN) == 0);
 
-               t = sha1_object_info(obj->oid.hash, &object_length);
+               t = oid_object_info(&obj->oid, &object_length);
                if (t != OBJ_BLOB) { /* probably OBJ_NONE */
                        /*
                         * We DO NOT have the blob locally, so we cannot
index bdf23c5f7b89eda2997057285d1fff64acb0d30c..d1c0bedf244fce0c8894175bf800384c0474b312 100644 (file)
@@ -177,7 +177,7 @@ static void show_parents(struct commit *commit, int abbrev, FILE *file)
        struct commit_list *p;
        for (p = commit->parents; p ; p = p->next) {
                struct commit *parent = p->item;
-               fprintf(file, " %s", find_unique_abbrev(parent->object.oid.hash, abbrev));
+               fprintf(file, " %s", find_unique_abbrev(&parent->object.oid, abbrev));
        }
 }
 
@@ -185,7 +185,7 @@ static void show_children(struct rev_info *opt, struct commit *commit, int abbre
 {
        struct commit_list *p = lookup_decoration(&opt->children, &commit->object);
        for ( ; p; p = p->next) {
-               fprintf(opt->diffopt.file, " %s", find_unique_abbrev(p->item->object.oid.hash, abbrev));
+               fprintf(opt->diffopt.file, " %s", find_unique_abbrev(&p->item->object.oid, abbrev));
        }
 }
 
@@ -558,7 +558,7 @@ void show_log(struct rev_info *opt)
 
                if (!opt->graph)
                        put_revision_mark(opt, commit);
-               fputs(find_unique_abbrev(commit->object.oid.hash, abbrev_commit), opt->diffopt.file);
+               fputs(find_unique_abbrev(&commit->object.oid, abbrev_commit), opt->diffopt.file);
                if (opt->print_parents)
                        show_parents(commit, abbrev_commit, opt->diffopt.file);
                if (opt->children.name)
@@ -620,7 +620,8 @@ void show_log(struct rev_info *opt)
 
                if (!opt->graph)
                        put_revision_mark(opt, commit);
-               fputs(find_unique_abbrev(commit->object.oid.hash, abbrev_commit),
+               fputs(find_unique_abbrev(&commit->object.oid,
+                                        abbrev_commit),
                      opt->diffopt.file);
                if (opt->print_parents)
                        show_parents(commit, abbrev_commit, opt->diffopt.file);
@@ -628,8 +629,7 @@ void show_log(struct rev_info *opt)
                        show_children(opt, commit, abbrev_commit);
                if (parent)
                        fprintf(opt->diffopt.file, " (from %s)",
-                              find_unique_abbrev(parent->object.oid.hash,
-                                                 abbrev_commit));
+                              find_unique_abbrev(&parent->object.oid, abbrev_commit));
                fputs(diff_get_color_opt(&opt->diffopt, DIFF_RESET), opt->diffopt.file);
                show_decorations(opt, commit);
                if (opt->commit_format == CMIT_FMT_ONELINE) {
index cb921b4db676e3db918ee16f419cd2b78e0bf57e..13f0d2884e25edef3fde5bdf72b89a770111e472 100644 (file)
--- a/mailmap.c
+++ b/mailmap.c
@@ -224,7 +224,7 @@ static int read_mailmap_blob(struct string_list *map,
        if (get_oid(name, &oid) < 0)
                return 0;
 
-       buf = read_sha1_file(oid.hash, &type, &size);
+       buf = read_object_file(&oid, &type, &size);
        if (!buf)
                return error("unable to read mailmap object at %s", name);
        if (type != OBJ_BLOB)
index 0ca99d51626f49b5d4a88b9edc43c533c970dd0e..72cc2baa3f96b2cbfa296335c7f0ff1094b6e96c 100644 (file)
@@ -54,7 +54,7 @@ static void *fill_tree_desc_strict(struct tree_desc *desc,
        enum object_type type;
        unsigned long size;
 
-       buffer = read_sha1_file(hash->hash, &type, &size);
+       buffer = read_object_file(hash, &type, &size);
        if (!buffer)
                die("unable to read tree (%s)", oid_to_hex(hash));
        if (type != OBJ_TREE)
@@ -180,7 +180,7 @@ static int splice_tree(const struct object_id *oid1, const char *prefix,
        if (*subpath)
                subpath++;
 
-       buf = read_sha1_file(oid1->hash, &type, &sz);
+       buf = read_object_file(oid1, &type, &sz);
        if (!buf)
                die("cannot read tree %s", oid_to_hex(oid1));
        init_tree_desc(&desc, buf, sz);
@@ -269,7 +269,7 @@ void shift_tree(const struct object_id *hash1,
                if (!*del_prefix)
                        return;
 
-               if (get_tree_entry(hash2->hash, del_prefix, shifted->hash, &mode))
+               if (get_tree_entry(hash2, del_prefix, shifted, &mode))
                        die("cannot find path %s in tree %s",
                            del_prefix, oid_to_hex(hash2));
                return;
@@ -296,12 +296,12 @@ void shift_tree_by(const struct object_id *hash1,
        unsigned candidate = 0;
 
        /* Can hash2 be a tree at shift_prefix in tree hash1? */
-       if (!get_tree_entry(hash1->hash, shift_prefix, sub1.hash, &mode1) &&
+       if (!get_tree_entry(hash1, shift_prefix, &sub1, &mode1) &&
            S_ISDIR(mode1))
                candidate |= 1;
 
        /* Can hash1 be a tree at shift_prefix in tree hash2? */
-       if (!get_tree_entry(hash2->hash, shift_prefix, sub2.hash, &mode2) &&
+       if (!get_tree_entry(hash2, shift_prefix, &sub2, &mode2) &&
            S_ISDIR(mode2))
                candidate |= 2;
 
index 9b6eac22e4256d8f2bf82961b6e4f320d89fdeba..fa49c17287f4120b4bbb75acc6b92b3d339710cd 100644 (file)
@@ -11,7 +11,7 @@ static int fill_mmfile_blob(mmfile_t *f, struct blob *obj)
        unsigned long size;
        enum object_type type;
 
-       buf = read_sha1_file(obj->object.oid.hash, &type, &size);
+       buf = read_object_file(&obj->object.oid, &type, &size);
        if (!buf)
                return -1;
        if (type != OBJ_BLOB) {
@@ -66,7 +66,7 @@ void *merge_blobs(const char *path, struct blob *base, struct blob *our, struct
                        return NULL;
                if (!our)
                        our = their;
-               return read_sha1_file(our->object.oid.hash, &type, size);
+               return read_object_file(&our->object.oid, &type, size);
        }
 
        if (fill_mmfile_blob(&f1, our) < 0)
index 869092f7b9bc0ce1104a1c43c7201acdee2eb4f8..0c0d48624da1d6162f0804e4a105841d965bb2c2 100644 (file)
@@ -228,7 +228,7 @@ static void output_commit_title(struct merge_options *o, struct commit *commit)
                strbuf_addf(&o->obuf, "virtual %s\n",
                        merge_remote_util(commit)->name);
        else {
-               strbuf_add_unique_abbrev(&o->obuf, commit->object.oid.hash,
+               strbuf_add_unique_abbrev(&o->obuf, &commit->object.oid,
                                         DEFAULT_ABBREV);
                strbuf_addch(&o->obuf, ' ');
                if (parse_commit(commit) != 0)
@@ -335,7 +335,7 @@ struct tree *write_tree_from_memory(struct merge_options *o)
        return result;
 }
 
-static int save_files_dirs(const unsigned char *sha1,
+static int save_files_dirs(const struct object_id *oid,
                struct strbuf *base, const char *path,
                unsigned int mode, int stage, void *context)
 {
@@ -370,12 +370,12 @@ static struct stage_data *insert_stage_data(const char *path,
 {
        struct string_list_item *item;
        struct stage_data *e = xcalloc(1, sizeof(struct stage_data));
-       get_tree_entry(o->object.oid.hash, path,
-                       e->stages[1].oid.hash, &e->stages[1].mode);
-       get_tree_entry(a->object.oid.hash, path,
-                       e->stages[2].oid.hash, &e->stages[2].mode);
-       get_tree_entry(b->object.oid.hash, path,
-                       e->stages[3].oid.hash, &e->stages[3].mode);
+       get_tree_entry(&o->object.oid, path,
+                       &e->stages[1].oid, &e->stages[1].mode);
+       get_tree_entry(&a->object.oid, path,
+                       &e->stages[2].oid, &e->stages[2].mode);
+       get_tree_entry(&b->object.oid, path,
+                       &e->stages[3].oid, &e->stages[3].mode);
        item = string_list_insert(entries, path);
        item->util = e;
        return e;
@@ -842,7 +842,7 @@ static int update_file_flags(struct merge_options *o,
                        goto update_index;
                }
 
-               buf = read_sha1_file(oid->hash, &type, &size);
+               buf = read_object_file(oid, &type, &size);
                if (!buf)
                        return err(o, _("cannot read object %s '%s'"), oid_to_hex(oid), path);
                if (type != OBJ_BLOB) {
@@ -1656,7 +1656,7 @@ static int read_oid_strbuf(struct merge_options *o,
        void *buf;
        enum object_type type;
        unsigned long size;
-       buf = read_sha1_file(oid->hash, &type, &size);
+       buf = read_object_file(oid, &type, &size);
        if (!buf)
                return err(o, _("cannot read object %s"), oid_to_hex(oid));
        if (type != OBJ_BLOB) {
diff --git a/mergetools/guiffy b/mergetools/guiffy
new file mode 100644 (file)
index 0000000..8b23a13
--- /dev/null
@@ -0,0 +1,18 @@
+diff_cmd () {
+       "$merge_tool_path" "$LOCAL" "$REMOTE"
+}
+
+merge_cmd () {
+       if $base_present
+       then
+               "$merge_tool_path" -s "$LOCAL" \
+               "$REMOTE" "$BASE" "$MERGED"
+       else
+               "$merge_tool_path" -m "$LOCAL" \
+               "$REMOTE" "$MERGED"
+       fi
+}
+
+exit_code_trustable () {
+       true
+}
index 398e61d5e943b1e6e143f159739f83fc0df9b6b8..e61988e503b0b2097afeb6716123d88429c0717d 100644 (file)
@@ -77,7 +77,7 @@ char *notes_cache_get(struct notes_cache *c, struct object_id *key_oid,
        value_oid = get_note(&c->tree, key_oid);
        if (!value_oid)
                return NULL;
-       value = read_sha1_file(value_oid->hash, &type, &size);
+       value = read_object_file(value_oid, &type, &size);
 
        *outsize = size;
        return value;
index c09c5e0e474a30b0a8bf3d91063c8bbc61e63557..8e0726a9418e3b24bc8e665057f607e18e7d4206 100644 (file)
@@ -322,7 +322,7 @@ static void write_note_to_worktree(const struct object_id *obj,
 {
        enum object_type type;
        unsigned long size;
-       void *buf = read_sha1_file(note->hash, &type, &size);
+       void *buf = read_object_file(note, &type, &size);
 
        if (!buf)
                die("cannot read note %s for object %s",
diff --git a/notes.c b/notes.c
index ce9a8f53f8668bbbf790f3b2d20f641fc034c301..a386d450c4c812ef30d0fc661fe2c03e1d062a83 100644 (file)
--- a/notes.c
+++ b/notes.c
@@ -796,13 +796,13 @@ int combine_notes_concatenate(struct object_id *cur_oid,
 
        /* read in both note blob objects */
        if (!is_null_oid(new_oid))
-               new_msg = read_sha1_file(new_oid->hash, &new_type, &new_len);
+               new_msg = read_object_file(new_oid, &new_type, &new_len);
        if (!new_msg || !new_len || new_type != OBJ_BLOB) {
                free(new_msg);
                return 0;
        }
        if (!is_null_oid(cur_oid))
-               cur_msg = read_sha1_file(cur_oid->hash, &cur_type, &cur_len);
+               cur_msg = read_object_file(cur_oid, &cur_type, &cur_len);
        if (!cur_msg || !cur_len || cur_type != OBJ_BLOB) {
                free(cur_msg);
                free(new_msg);
@@ -858,7 +858,7 @@ static int string_list_add_note_lines(struct string_list *list,
                return 0;
 
        /* read_sha1_file NUL-terminates */
-       data = read_sha1_file(oid->hash, &t, &len);
+       data = read_object_file(oid, &t, &len);
        if (t != OBJ_BLOB || !data || !len) {
                free(data);
                return t != OBJ_BLOB || !data;
@@ -1012,7 +1012,7 @@ void init_notes(struct notes_tree *t, const char *notes_ref,
                return;
        if (flags & NOTES_INIT_WRITABLE && read_ref(notes_ref, &object_oid))
                die("Cannot use notes ref %s", notes_ref);
-       if (get_tree_entry(object_oid.hash, "", oid.hash, &mode))
+       if (get_tree_entry(&object_oid, "", &oid, &mode))
                die("Failed to read notes tree referenced by %s (%s)",
                    notes_ref, oid_to_hex(&object_oid));
 
@@ -1217,7 +1217,7 @@ static void format_note(struct notes_tree *t, const struct object_id *object_oid
        if (!oid)
                return;
 
-       if (!(msg = read_sha1_file(oid->hash, &type, &msglen)) || type != OBJ_BLOB) {
+       if (!(msg = read_object_file(oid, &type, &msglen)) || type != OBJ_BLOB) {
                free(msg);
                return;
        }
diff --git a/object-store.h b/object-store.h
new file mode 100644 (file)
index 0000000..fef33f3
--- /dev/null
@@ -0,0 +1,132 @@
+#ifndef OBJECT_STORE_H
+#define OBJECT_STORE_H
+
+struct alternate_object_database {
+       struct alternate_object_database *next;
+
+       /* see alt_scratch_buf() */
+       struct strbuf scratch;
+       size_t base_len;
+
+       /*
+        * Used to store the results of readdir(3) calls when searching
+        * for unique abbreviated hashes.  This cache is never
+        * invalidated, thus it's racy and not necessarily accurate.
+        * That's fine for its purpose; don't use it for tasks requiring
+        * greater accuracy!
+        */
+       char loose_objects_subdir_seen[256];
+       struct oid_array loose_objects_cache;
+
+       /*
+        * Path to the alternative object store. If this is a relative path,
+        * it is relative to the current working directory.
+        */
+       char path[FLEX_ARRAY];
+};
+void prepare_alt_odb(struct repository *r);
+char *compute_alternate_path(const char *path, struct strbuf *err);
+typedef int alt_odb_fn(struct alternate_object_database *, void *);
+int foreach_alt_odb(alt_odb_fn, void*);
+
+/*
+ * Allocate a "struct alternate_object_database" but do _not_ actually
+ * add it to the list of alternates.
+ */
+struct alternate_object_database *alloc_alt_odb(const char *dir);
+
+/*
+ * Add the directory to the on-disk alternates file; the new entry will also
+ * take effect in the current process.
+ */
+void add_to_alternates_file(const char *dir);
+
+/*
+ * Add the directory to the in-memory list of alternates (along with any
+ * recursive alternates it points to), but do not modify the on-disk alternates
+ * file.
+ */
+void add_to_alternates_memory(const char *dir);
+
+/*
+ * Returns a scratch strbuf pre-filled with the alternate object directory,
+ * including a trailing slash, which can be used to access paths in the
+ * alternate. Always use this over direct access to alt->scratch, as it
+ * cleans up any previous use of the scratch buffer.
+ */
+struct strbuf *alt_scratch_buf(struct alternate_object_database *alt);
+
+struct packed_git {
+       struct packed_git *next;
+       struct list_head mru;
+       struct pack_window *windows;
+       off_t pack_size;
+       const void *index_data;
+       size_t index_size;
+       uint32_t num_objects;
+       uint32_t num_bad_objects;
+       unsigned char *bad_object_sha1;
+       int index_version;
+       time_t mtime;
+       int pack_fd;
+       unsigned pack_local:1,
+                pack_keep:1,
+                freshened:1,
+                do_not_close:1,
+                pack_promisor:1;
+       unsigned char sha1[20];
+       struct revindex_entry *revindex;
+       /* something like ".git/objects/pack/xxxxx.pack" */
+       char pack_name[FLEX_ARRAY]; /* more */
+};
+
+struct raw_object_store {
+       /*
+        * Path to the repository's object store.
+        * Cannot be NULL after initialization.
+        */
+       char *objectdir;
+
+       /* Path to extra alternate object database if not NULL */
+       char *alternate_db;
+
+       struct alternate_object_database *alt_odb_list;
+       struct alternate_object_database **alt_odb_tail;
+
+       /*
+        * private data
+        *
+        * should only be accessed directly by packfile.c
+        */
+
+       struct packed_git *packed_git;
+       /* A most-recently-used ordered version of the packed_git list. */
+       struct list_head packed_git_mru;
+
+       /*
+        * A fast, rough count of the number of objects in the repository.
+        * These two fields are not meant for direct access. Use
+        * approximate_object_count() instead.
+        */
+       unsigned long approximate_object_count;
+       unsigned approximate_object_count_valid : 1;
+
+       /*
+        * Whether packed_git has already been populated with this repository's
+        * packs.
+        */
+       unsigned packed_git_initialized : 1;
+};
+
+struct raw_object_store *raw_object_store_new(void);
+void raw_object_store_clear(struct raw_object_store *o);
+
+/*
+ * Put in `buf` the name of the file in the local object database that
+ * would be used to store a loose object with the specified sha1.
+ */
+void sha1_file_name(struct repository *r, struct strbuf *buf, const unsigned char *sha1);
+
+void *map_sha1_file(struct repository *r, const unsigned char *sha1, unsigned long *size);
+
+#endif /* OBJECT_STORE_H */
index e6ad3f61f03a98aa82dd901d96cbc230381c2e90..a0a756f24f33621bbe83cbe69b18eef6790edacf 100644 (file)
--- a/object.c
+++ b/object.c
@@ -4,6 +4,8 @@
 #include "tree.h"
 #include "commit.h"
 #include "tag.h"
+#include "object-store.h"
+#include "packfile.h"
 
 static struct object **obj_hash;
 static int nr_objs, obj_hash_size;
@@ -244,7 +246,7 @@ struct object *parse_object(const struct object_id *oid)
        unsigned long size;
        enum object_type type;
        int eaten;
-       const unsigned char *repl = lookup_replace_object(oid->hash);
+       const struct object_id *repl = lookup_replace_object(oid);
        void *buffer;
        struct object *obj;
 
@@ -254,8 +256,8 @@ struct object *parse_object(const struct object_id *oid)
 
        if ((obj && obj->type == OBJ_BLOB && has_object_file(oid)) ||
            (!obj && has_object_file(oid) &&
-            sha1_object_info(oid->hash, NULL) == OBJ_BLOB)) {
-               if (check_sha1_signature(repl, NULL, 0, NULL) < 0) {
+            oid_object_info(oid, NULL) == OBJ_BLOB)) {
+               if (check_object_signature(repl, NULL, 0, NULL) < 0) {
                        error("sha1 mismatch %s", oid_to_hex(oid));
                        return NULL;
                }
@@ -263,11 +265,11 @@ struct object *parse_object(const struct object_id *oid)
                return lookup_object(oid->hash);
        }
 
-       buffer = read_sha1_file(oid->hash, &type, &size);
+       buffer = read_object_file(oid, &type, &size);
        if (buffer) {
-               if (check_sha1_signature(repl, buffer, size, type_name(type)) < 0) {
+               if (check_object_signature(repl, buffer, size, type_name(type)) < 0) {
                        free(buffer);
-                       error("sha1 mismatch %s", sha1_to_hex(repl));
+                       error("sha1 mismatch %s", oid_to_hex(repl));
                        return NULL;
                }
 
@@ -445,3 +447,43 @@ void clear_commit_marks_all(unsigned int flags)
                        obj->flags &= ~flags;
        }
 }
+
+struct raw_object_store *raw_object_store_new(void)
+{
+       struct raw_object_store *o = xmalloc(sizeof(*o));
+
+       memset(o, 0, sizeof(*o));
+       INIT_LIST_HEAD(&o->packed_git_mru);
+       return o;
+}
+
+static void free_alt_odb(struct alternate_object_database *alt)
+{
+       strbuf_release(&alt->scratch);
+       oid_array_clear(&alt->loose_objects_cache);
+       free(alt);
+}
+
+static void free_alt_odbs(struct raw_object_store *o)
+{
+       while (o->alt_odb_list) {
+               struct alternate_object_database *next;
+
+               next = o->alt_odb_list->next;
+               free_alt_odb(o->alt_odb_list);
+               o->alt_odb_list = next;
+       }
+}
+
+void raw_object_store_clear(struct raw_object_store *o)
+{
+       FREE_AND_NULL(o->objectdir);
+       FREE_AND_NULL(o->alternate_db);
+
+       free_alt_odbs(o);
+       o->alt_odb_tail = NULL;
+
+       INIT_LIST_HEAD(&o->packed_git_mru);
+       close_all_packs(o);
+       o->packed_git = NULL;
+}
index e01f9928840488b85db2ebc62527d8e4aab81ffc..41ae27fb19a94a4c44058d8850a9592c41b82f90 100644 (file)
@@ -73,8 +73,7 @@ void bitmap_writer_build_type_index(struct pack_idx_entry **index,
                        break;
 
                default:
-                       real_type = sha1_object_info(entry->idx.oid.hash,
-                                                    NULL);
+                       real_type = oid_object_info(&entry->idx.oid, NULL);
                        break;
                }
 
index 9270983e5f581e40f894a8885396e43d13e71015..3f2dab340f6cc05cde659f97dacbd825d8266bc9 100644 (file)
@@ -10,6 +10,8 @@
 #include "pack-revindex.h"
 #include "pack-objects.h"
 #include "packfile.h"
+#include "repository.h"
+#include "object-store.h"
 
 /*
  * An entry on the bitmap index, representing the bitmap for a given
@@ -334,8 +336,7 @@ static int open_pack_bitmap(void)
 
        assert(!bitmap_git.map && !bitmap_git.loaded);
 
-       prepare_packed_git();
-       for (p = packed_git; p; p = p->next) {
+       for (p = get_packed_git(the_repository); p; p = p->next) {
                if (open_pack_bitmap_1(p) == 0)
                        ret = 0;
        }
index 8fc7dd1694cf1a67da69bc010879e0c54ee403be..385d964bdd1691b962250ec5a49abf2253ca75c1 100644 (file)
@@ -3,6 +3,7 @@
 #include "pack-revindex.h"
 #include "progress.h"
 #include "packfile.h"
+#include "object-store.h"
 
 struct idx_entry {
        off_t                offset;
@@ -126,7 +127,7 @@ static int verify_packfile(struct packed_git *p,
 
                if (type == OBJ_BLOB && big_file_threshold <= size) {
                        /*
-                        * Let check_sha1_signature() check it with
+                        * Let check_object_signature() check it with
                         * the streaming interface; no point slurping
                         * the data in-core only to discard.
                         */
@@ -141,7 +142,7 @@ static int verify_packfile(struct packed_git *p,
                        err = error("cannot unpack %s from %s at offset %"PRIuMAX"",
                                    oid_to_hex(entries[i].oid.oid), p->pack_name,
                                    (uintmax_t)entries[i].offset);
-               else if (check_sha1_signature(entries[i].oid.hash, data, size, type_name(type)))
+               else if (check_object_signature(entries[i].oid.oid, data, size, type_name(type)))
                        err = error("packed %s from %s is corrupt",
                                    oid_to_hex(entries[i].oid.oid), p->pack_name);
                else if (fn) {
index ff5f62c03326a7f01926c72a19be5029ae4c1a8b..bb521cf7fb2911bc2d3653f46224880f8540f9ab 100644 (file)
@@ -1,5 +1,6 @@
 #include "cache.h"
 #include "pack-revindex.h"
+#include "object-store.h"
 
 /*
  * Pack index for existing packs give us easy access to the offsets into
index 7c1a2519fcb9c45aacf5481811bc26f44736de59..0bc67d0e00966008f9f8a6fa1c1b6540569a7cc0 100644 (file)
@@ -1,6 +1,7 @@
 #include "cache.h"
 #include "list.h"
 #include "pack.h"
+#include "repository.h"
 #include "dir.h"
 #include "mergesort.h"
 #include "packfile.h"
@@ -13,6 +14,7 @@
 #include "tag.h"
 #include "tree-walk.h"
 #include "tree.h"
+#include "object-store.h"
 
 char *odb_pack_name(struct strbuf *buf,
                    const unsigned char *sha1,
@@ -44,8 +46,6 @@ static unsigned int pack_open_fds;
 static unsigned int pack_max_fds;
 static size_t peak_pack_mapped;
 static size_t pack_mapped;
-struct packed_git *packed_git;
-LIST_HEAD(packed_git_mru);
 
 #define SZ_FMT PRIuMAX
 static inline uintmax_t sz_fmt(size_t s) { return s; }
@@ -245,7 +245,7 @@ static int unuse_one_window(struct packed_git *current)
 
        if (current)
                scan_windows(current, &lru_p, &lru_w, &lru_l);
-       for (p = packed_git; p; p = p->next)
+       for (p = the_repository->objects->packed_git; p; p = p->next)
                scan_windows(p, &lru_p, &lru_w, &lru_l);
        if (lru_p) {
                munmap(lru_w->base, lru_w->len);
@@ -311,11 +311,11 @@ static void close_pack(struct packed_git *p)
        close_pack_index(p);
 }
 
-void close_all_packs(void)
+void close_all_packs(struct raw_object_store *o)
 {
        struct packed_git *p;
 
-       for (p = packed_git; p; p = p->next)
+       for (p = o->packed_git; p; p = p->next)
                if (p->do_not_close)
                        die("BUG: want to close pack marked 'do-not-close'");
                else
@@ -383,7 +383,7 @@ static int close_one_pack(void)
        struct pack_window *mru_w = NULL;
        int accept_windows_inuse = 1;
 
-       for (p = packed_git; p; p = p->next) {
+       for (p = the_repository->objects->packed_git; p; p = p->next) {
                if (p->pack_fd == -1)
                        continue;
                find_lru_pack(p, &lru_p, &mru_w, &accept_windows_inuse);
@@ -680,13 +680,13 @@ struct packed_git *add_packed_git(const char *path, size_t path_len, int local)
        return p;
 }
 
-void install_packed_git(struct packed_git *pack)
+void install_packed_git(struct repository *r, struct packed_git *pack)
 {
        if (pack->pack_fd != -1)
                pack_open_fds++;
 
-       pack->next = packed_git;
-       packed_git = pack;
+       pack->next = r->objects->packed_git;
+       r->objects->packed_git = pack;
 }
 
 void (*report_garbage)(unsigned seen_bits, const char *path);
@@ -735,7 +735,7 @@ static void report_pack_garbage(struct string_list *list)
        report_helper(list, seen_bits, first, list->nr);
 }
 
-static void prepare_packed_git_one(char *objdir, int local)
+static void prepare_packed_git_one(struct repository *r, char *objdir, int local)
 {
        struct strbuf path = STRBUF_INIT;
        size_t dirnamelen;
@@ -768,7 +768,8 @@ static void prepare_packed_git_one(char *objdir, int local)
                base_len = path.len;
                if (strip_suffix_mem(path.buf, &base_len, ".idx")) {
                        /* Don't reopen a pack we already have. */
-                       for (p = packed_git; p; p = p->next) {
+                       for (p = r->objects->packed_git; p;
+                            p = p->next) {
                                size_t len;
                                if (strip_suffix(p->pack_name, ".pack", &len) &&
                                    len == base_len &&
@@ -781,7 +782,7 @@ static void prepare_packed_git_one(char *objdir, int local)
                             * corresponding .pack file that we can map.
                             */
                            (p = add_packed_git(path.buf, path.len, local)) != NULL)
-                               install_packed_git(p);
+                               install_packed_git(r, p);
                }
 
                if (!report_garbage)
@@ -802,8 +803,7 @@ static void prepare_packed_git_one(char *objdir, int local)
        strbuf_release(&path);
 }
 
-static int approximate_object_count_valid;
-
+static void prepare_packed_git(struct repository *r);
 /*
  * Give a fast, rough count of the number of objects in the repository. This
  * ignores loose objects completely. If you have a lot of them, then either
@@ -813,19 +813,20 @@ static int approximate_object_count_valid;
  */
 unsigned long approximate_object_count(void)
 {
-       static unsigned long count;
-       if (!approximate_object_count_valid) {
+       if (!the_repository->objects->approximate_object_count_valid) {
+               unsigned long count;
                struct packed_git *p;
 
-               prepare_packed_git();
+               prepare_packed_git(the_repository);
                count = 0;
-               for (p = packed_git; p; p = p->next) {
+               for (p = the_repository->objects->packed_git; p; p = p->next) {
                        if (open_pack_index(p))
                                continue;
                        count += p->num_objects;
                }
+               the_repository->objects->approximate_object_count = count;
        }
-       return count;
+       return the_repository->objects->approximate_object_count;
 }
 
 static void *get_next_packed_git(const void *p)
@@ -866,43 +867,55 @@ static int sort_pack(const void *a_, const void *b_)
        return -1;
 }
 
-static void rearrange_packed_git(void)
+static void rearrange_packed_git(struct repository *r)
 {
-       packed_git = llist_mergesort(packed_git, get_next_packed_git,
-                                    set_next_packed_git, sort_pack);
+       r->objects->packed_git = llist_mergesort(
+               r->objects->packed_git, get_next_packed_git,
+               set_next_packed_git, sort_pack);
 }
 
-static void prepare_packed_git_mru(void)
+static void prepare_packed_git_mru(struct repository *r)
 {
        struct packed_git *p;
 
-       INIT_LIST_HEAD(&packed_git_mru);
+       INIT_LIST_HEAD(&r->objects->packed_git_mru);
 
-       for (p = packed_git; p; p = p->next)
-               list_add_tail(&p->mru, &packed_git_mru);
+       for (p = r->objects->packed_git; p; p = p->next)
+               list_add_tail(&p->mru, &r->objects->packed_git_mru);
 }
 
-static int prepare_packed_git_run_once = 0;
-void prepare_packed_git(void)
+static void prepare_packed_git(struct repository *r)
 {
        struct alternate_object_database *alt;
 
-       if (prepare_packed_git_run_once)
+       if (r->objects->packed_git_initialized)
                return;
-       prepare_packed_git_one(get_object_directory(), 1);
-       prepare_alt_odb();
-       for (alt = alt_odb_list; alt; alt = alt->next)
-               prepare_packed_git_one(alt->path, 0);
-       rearrange_packed_git();
-       prepare_packed_git_mru();
-       prepare_packed_git_run_once = 1;
+       prepare_packed_git_one(r, r->objects->objectdir, 1);
+       prepare_alt_odb(r);
+       for (alt = r->objects->alt_odb_list; alt; alt = alt->next)
+               prepare_packed_git_one(r, alt->path, 0);
+       rearrange_packed_git(r);
+       prepare_packed_git_mru(r);
+       r->objects->packed_git_initialized = 1;
+}
+
+void reprepare_packed_git(struct repository *r)
+{
+       r->objects->approximate_object_count_valid = 0;
+       r->objects->packed_git_initialized = 0;
+       prepare_packed_git(r);
+}
+
+struct packed_git *get_packed_git(struct repository *r)
+{
+       prepare_packed_git(r);
+       return r->objects->packed_git;
 }
 
-void reprepare_packed_git(void)
+struct list_head *get_packed_git_mru(struct repository *r)
 {
-       approximate_object_count_valid = 0;
-       prepare_packed_git_run_once = 0;
-       prepare_packed_git();
+       prepare_packed_git(r);
+       return &r->objects->packed_git_mru;
 }
 
 unsigned long unpack_object_header_buffer(const unsigned char *buf,
@@ -1013,7 +1026,7 @@ const struct packed_git *has_packed_and_bad(const unsigned char *sha1)
        struct packed_git *p;
        unsigned i;
 
-       for (p = packed_git; p; p = p->next)
+       for (p = the_repository->objects->packed_git; p; p = p->next)
                for (i = 0; i < p->num_bad_objects; i++)
                        if (!hashcmp(sha1, p->bad_object_sha1 + 20 * i))
                                return p;
@@ -1095,13 +1108,13 @@ static int retry_bad_packed_offset(struct packed_git *p, off_t obj_offset)
 {
        int type;
        struct revindex_entry *revidx;
-       const unsigned char *sha1;
+       struct object_id oid;
        revidx = find_pack_revindex(p, obj_offset);
        if (!revidx)
                return OBJ_BAD;
-       sha1 = nth_packed_object_sha1(p, revidx->nr);
-       mark_bad_packed_object(p, sha1);
-       type = sha1_object_info(sha1, NULL);
+       nth_packed_object_oid(&oid, p, revidx->nr);
+       mark_bad_packed_object(p, oid.hash);
+       type = oid_object_info(&oid, NULL);
        if (type <= OBJ_NONE)
                return OBJ_BAD;
        return type;
@@ -1452,7 +1465,7 @@ struct unpack_entry_stack_ent {
        unsigned long size;
 };
 
-static void *read_object(const unsigned char *sha1, enum object_type *type,
+static void *read_object(const struct object_id *oid, enum object_type *type,
                         unsigned long *size)
 {
        struct object_info oi = OBJECT_INFO_INIT;
@@ -1461,7 +1474,7 @@ static void *read_object(const unsigned char *sha1, enum object_type *type,
        oi.sizep = size;
        oi.contentp = &content;
 
-       if (sha1_object_info_extended(sha1, &oi, 0) < 0)
+       if (oid_object_info_extended(oid, &oi, 0) < 0)
                return NULL;
        return content;
 }
@@ -1501,11 +1514,11 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset,
                        struct revindex_entry *revidx = find_pack_revindex(p, obj_offset);
                        off_t len = revidx[1].offset - obj_offset;
                        if (check_pack_crc(p, &w_curs, obj_offset, len, revidx->nr)) {
-                               const unsigned char *sha1 =
-                                       nth_packed_object_sha1(p, revidx->nr);
+                               struct object_id oid;
+                               nth_packed_object_oid(&oid, p, revidx->nr);
                                error("bad packed object CRC for %s",
-                                     sha1_to_hex(sha1));
-                               mark_bad_packed_object(p, sha1);
+                                     oid_to_hex(&oid));
+                               mark_bad_packed_object(p, oid.hash);
                                data = NULL;
                                goto out;
                        }
@@ -1588,16 +1601,16 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset,
                         * of a corrupted pack, and is better than failing outright.
                         */
                        struct revindex_entry *revidx;
-                       const unsigned char *base_sha1;
+                       struct object_id base_oid;
                        revidx = find_pack_revindex(p, obj_offset);
                        if (revidx) {
-                               base_sha1 = nth_packed_object_sha1(p, revidx->nr);
+                               nth_packed_object_oid(&base_oid, p, revidx->nr);
                                error("failed to read delta base object %s"
                                      " at offset %"PRIuMAX" from %s",
-                                     sha1_to_hex(base_sha1), (uintmax_t)obj_offset,
+                                     oid_to_hex(&base_oid), (uintmax_t)obj_offset,
                                      p->pack_name);
-                               mark_bad_packed_object(p, base_sha1);
-                               base = read_object(base_sha1, &type, &base_size);
+                               mark_bad_packed_object(p, base_oid.hash);
+                               base = read_object(&base_oid, &type, &base_size);
                                external_base = base;
                        }
                }
@@ -1654,6 +1667,29 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset,
        return data;
 }
 
+int bsearch_pack(const struct object_id *oid, const struct packed_git *p, uint32_t *result)
+{
+       const unsigned char *index_fanout = p->index_data;
+       const unsigned char *index_lookup;
+       int index_lookup_width;
+
+       if (!index_fanout)
+               BUG("bsearch_pack called without a valid pack-index");
+
+       index_lookup = index_fanout + 4 * 256;
+       if (p->index_version == 1) {
+               index_lookup_width = 24;
+               index_lookup += 4;
+       } else {
+               index_lookup_width = 20;
+               index_fanout += 8;
+               index_lookup += 8;
+       }
+
+       return bsearch_hash(oid->hash, (const uint32_t*)index_fanout,
+                           index_lookup, index_lookup_width, result);
+}
+
 const unsigned char *nth_packed_object_sha1(struct packed_git *p,
                                            uint32_t n)
 {
@@ -1720,30 +1756,17 @@ off_t nth_packed_object_offset(const struct packed_git *p, uint32_t n)
 off_t find_pack_entry_one(const unsigned char *sha1,
                                  struct packed_git *p)
 {
-       const uint32_t *level1_ofs = p->index_data;
        const unsigned char *index = p->index_data;
-       unsigned stride;
+       struct object_id oid;
        uint32_t result;
 
        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;
-       }
-       index += 4 * 256;
-       if (p->index_version > 1) {
-               stride = 20;
-       } else {
-               stride = 24;
-               index += 4;
        }
 
-       if (bsearch_hash(sha1, level1_ofs, index, stride, &result))
+       hashcpy(oid.hash, sha1);
+       if (bsearch_pack(&oid, p, &result))
                return nth_packed_object_offset(p, result);
        return 0;
 }
@@ -1814,22 +1837,18 @@ static int fill_pack_entry(const unsigned char *sha1,
        return 1;
 }
 
-/*
- * Iff a pack file contains the object named by sha1, return true and
- * store its location to e.
- */
-int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)
+int find_pack_entry(struct repository *r, const unsigned char *sha1, struct pack_entry *e)
 {
        struct list_head *pos;
 
-       prepare_packed_git();
-       if (!packed_git)
+       prepare_packed_git(r);
+       if (!r->objects->packed_git)
                return 0;
 
-       list_for_each(pos, &packed_git_mru) {
+       list_for_each(pos, &r->objects->packed_git_mru) {
                struct packed_git *p = list_entry(pos, struct packed_git, mru);
                if (fill_pack_entry(sha1, e, p)) {
-                       list_move(&p->mru, &packed_git_mru);
+                       list_move(&p->mru, &r->objects->packed_git_mru);
                        return 1;
                }
        }
@@ -1839,7 +1858,7 @@ int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)
 int has_sha1_pack(const unsigned char *sha1)
 {
        struct pack_entry e;
-       return find_pack_entry(sha1, &e);
+       return find_pack_entry(the_repository, sha1, &e);
 }
 
 int has_pack_index(const unsigned char *sha1)
@@ -1875,8 +1894,8 @@ int for_each_packed_object(each_packed_object_fn cb, void *data, unsigned flags)
        int r = 0;
        int pack_errors = 0;
 
-       prepare_packed_git();
-       for (p = packed_git; p; p = p->next) {
+       prepare_packed_git(the_repository);
+       for (p = the_repository->objects->packed_git; p; p = p->next) {
                if ((flags & FOR_EACH_OBJECT_LOCAL_ONLY) && !p->pack_local)
                        continue;
                if ((flags & FOR_EACH_OBJECT_PROMISOR_ONLY) &&
@@ -1907,7 +1926,7 @@ static int add_promisor_object(const struct object_id *oid,
 
        /*
         * If this is a tree, commit, or tag, the objects it refers
-        * to are also promisor objects. (Blobs refer to no objects.)
+        * to are also promisor objects. (Blobs refer to no objects->)
         */
        if (obj->type == OBJ_TREE) {
                struct tree *tree = (struct tree *)obj;
index a7fca598d672b73010a5fb99e4507da4634002ff..a92c0b241cfa65066ab57995f0f902ddb79a3be4 100644 (file)
@@ -34,9 +34,11 @@ extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_
 #define PACKDIR_FILE_GARBAGE 4
 extern void (*report_garbage)(unsigned seen_bits, const char *path);
 
-extern void prepare_packed_git(void);
-extern void reprepare_packed_git(void);
-extern void install_packed_git(struct packed_git *pack);
+extern void reprepare_packed_git(struct repository *r);
+extern void install_packed_git(struct repository *r, struct packed_git *pack);
+
+struct packed_git *get_packed_git(struct repository *r);
+struct list_head *get_packed_git_mru(struct repository *r);
 
 /*
  * Give a rough count of objects in the repository. This sacrifices accuracy
@@ -63,7 +65,7 @@ extern void close_pack_index(struct packed_git *);
 
 extern unsigned char *use_pack(struct packed_git *, struct pack_window **, off_t, unsigned long *);
 extern void close_pack_windows(struct packed_git *);
-extern void close_all_packs(void);
+extern void close_all_packs(struct raw_object_store *o);
 extern void unuse_pack(struct pack_window **);
 extern void clear_delta_base_cache(void);
 extern struct packed_git *add_packed_git(const char *path, size_t path_len, int local);
@@ -78,6 +80,14 @@ extern struct packed_git *add_packed_git(const char *path, size_t path_len, int
  */
 extern void check_pack_index_ptr(const struct packed_git *p, const void *ptr);
 
+/*
+ * Perform binary search on a pack-index for a given oid. Packfile is expected to
+ * have a valid pack-index.
+ *
+ * See 'bsearch_hash' for more information.
+ */
+int bsearch_pack(const struct object_id *oid, const struct packed_git *p, uint32_t *result);
+
 /*
  * Return the SHA-1 of the nth object within the specified packfile.
  * Open the index if it is not already open.  The return value points
@@ -120,7 +130,11 @@ extern int packed_object_info(struct packed_git *pack, off_t offset, struct obje
 extern void mark_bad_packed_object(struct packed_git *p, const unsigned char *sha1);
 extern const struct packed_git *has_packed_and_bad(const unsigned char *sha1);
 
-extern int find_pack_entry(const unsigned char *sha1, struct pack_entry *e);
+/*
+ * Iff a pack file in the given repository contains the object named by sha1,
+ * return true and store its location to e.
+ */
+extern int find_pack_entry(struct repository *r, const unsigned char *sha1, struct pack_entry *e);
 
 extern int has_sha1_pack(const unsigned char *sha1);
 
index 125e84f98451b4eb12e9d8a6cb4da58b2d8db51e..0f7059a8ab32a624775026d7dc2289245c87c192 100644 (file)
@@ -317,14 +317,16 @@ static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg,
                return get_value(p, options, all_opts, flags ^ opt_flags);
        }
 
-       if (ambiguous_option)
-               return error("Ambiguous option: %s "
+       if (ambiguous_option) {
+               error("Ambiguous option: %s "
                        "(could be --%s%s or --%s%s)",
                        arg,
                        (ambiguous_flags & OPT_UNSET) ?  "no-" : "",
                        ambiguous_option->long_name,
                        (abbrev_flags & OPT_UNSET) ?  "no-" : "",
                        abbrev_option->long_name);
+               return -3;
+       }
        if (abbrev_option)
                return get_value(p, abbrev_option, all_opts, abbrev_flags);
        return -2;
@@ -476,7 +478,6 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
                       const char * const usagestr[])
 {
        int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP);
-       int err = 0;
 
        /* we must reset ->opt, unknown short option leave it dangling */
        ctx->opt = NULL;
@@ -505,7 +506,7 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
                        ctx->opt = arg + 1;
                        switch (parse_short_opt(ctx, options)) {
                        case -1:
-                               goto show_usage_error;
+                               return PARSE_OPT_ERROR;
                        case -2:
                                if (ctx->opt)
                                        check_typos(arg + 1, options);
@@ -518,7 +519,7 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
                        while (ctx->opt) {
                                switch (parse_short_opt(ctx, options)) {
                                case -1:
-                                       goto show_usage_error;
+                                       return PARSE_OPT_ERROR;
                                case -2:
                                        if (internal_help && *ctx->opt == 'h')
                                                goto show_usage;
@@ -550,9 +551,11 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
                        goto show_usage;
                switch (parse_long_opt(ctx, arg + 2, options)) {
                case -1:
-                       goto show_usage_error;
+                       return PARSE_OPT_ERROR;
                case -2:
                        goto unknown;
+               case -3:
+                       goto show_usage;
                }
                continue;
 unknown:
@@ -563,10 +566,8 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
        }
        return PARSE_OPT_DONE;
 
- show_usage_error:
-       err = 1;
  show_usage:
-       return usage_with_options_internal(ctx, usagestr, options, 0, err);
+       return usage_with_options_internal(ctx, usagestr, options, 0, 0);
 }
 
 int parse_options_end(struct parse_opt_ctx_t *ctx)
@@ -585,6 +586,7 @@ int parse_options(int argc, const char **argv, const char *prefix,
        parse_options_start(&ctx, argc, argv, prefix, options, flags);
        switch (parse_options_step(&ctx, options, usagestr)) {
        case PARSE_OPT_HELP:
+       case PARSE_OPT_ERROR:
                exit(129);
        case PARSE_OPT_NON_OPTION:
        case PARSE_OPT_DONE:
index ab1cc362bf2918c28a14dd851c1b1a13dfa0c863..dd14911a297a5b10705ecb31243c55a7dc2f193c 100644 (file)
@@ -200,6 +200,7 @@ enum {
        PARSE_OPT_HELP = -1,
        PARSE_OPT_DONE,
        PARSE_OPT_NON_OPTION,
+       PARSE_OPT_ERROR,
        PARSE_OPT_UNKNOWN
 };
 
diff --git a/path.c b/path.c
index da8b655730d363dda5010bdf2d53bd76abb82931..3308b7b95828821fdda6806d9d19228cbf8e61ed 100644 (file)
--- a/path.c
+++ b/path.c
@@ -10,6 +10,7 @@
 #include "submodule-config.h"
 #include "path.h"
 #include "packfile.h"
+#include "object-store.h"
 
 static int get_st_mode_bits(const char *path, int *mode)
 {
@@ -382,7 +383,7 @@ static void adjust_git_path(const struct repository *repo,
                strbuf_splice(buf, 0, buf->len,
                              repo->index_file, strlen(repo->index_file));
        else if (dir_prefix(base, "objects"))
-               replace_dir(buf, git_dir_len + 7, repo->objectdir);
+               replace_dir(buf, git_dir_len + 7, repo->objects->objectdir);
        else if (git_hooks_path && dir_prefix(base, "hooks"))
                replace_dir(buf, git_dir_len + 5, git_hooks_path);
        else if (repo->different_commondir)
index 991a5885e9230b1f55bd6f3b7f7b53321bf9e562..76b29659057d329670ce07b102de37caf133e97f 100644 (file)
@@ -1482,7 +1482,6 @@ sub call_authors_prog {
        }
        if ($author =~ /^\s*(.+?)\s*<(.*)>\s*$/) {
                my ($name, $email) = ($1, $2);
-               $email = undef if length $2 == 0;
                return [$name, $email];
        } else {
                die "Author: $orig_author: $::_authors_prog returned "
@@ -2020,8 +2019,8 @@ sub make_log_entry {
                remove_username($full_url);
                $log_entry{metadata} = "$full_url\@$r $uuid";
                $log_entry{svm_revision} = $r;
-               $email ||= "$author\@$uuid";
-               $commit_email ||= "$author\@$uuid";
+               $email = "$author\@$uuid" unless defined $email;
+               $commit_email = "$author\@$uuid" unless defined $commit_email;
        } elsif ($self->use_svnsync_props) {
                my $full_url = canonicalize_url(
                        add_path_to_url( $self->svnsync->{url}, $self->path )
@@ -2029,15 +2028,15 @@ sub make_log_entry {
                remove_username($full_url);
                my $uuid = $self->svnsync->{uuid};
                $log_entry{metadata} = "$full_url\@$rev $uuid";
-               $email ||= "$author\@$uuid";
-               $commit_email ||= "$author\@$uuid";
+               $email = "$author\@$uuid" unless defined $email;
+               $commit_email = "$author\@$uuid" unless defined $commit_email;
        } else {
                my $url = $self->metadata_url;
                remove_username($url);
                my $uuid = $self->rewrite_uuid || $self->ra->get_uuid;
                $log_entry{metadata} = "$url\@$rev " . $uuid;
-               $email ||= "$author\@" . $uuid;
-               $commit_email ||= "$author\@" . $uuid;
+               $email = "$author\@$uuid" unless defined $email;
+               $commit_email = "$author\@$uuid" unless defined $commit_email;
        }
        $log_entry{name} = $name;
        $log_entry{email} = $email;
index f7ce4902301490d73bdd79bd396cf7bbe5f893ea..34fe891fc03672fa042257e4d32630882868eadf 100644 (file)
--- a/pretty.c
+++ b/pretty.c
@@ -549,7 +549,7 @@ static void add_merge_info(const struct pretty_print_context *pp,
                struct object_id *oidp = &parent->item->object.oid;
                strbuf_addch(sb, ' ');
                if (pp->abbrev)
-                       strbuf_add_unique_abbrev(sb, oidp->hash, pp->abbrev);
+                       strbuf_add_unique_abbrev(sb, oidp, pp->abbrev);
                else
                        strbuf_addstr(sb, oid_to_hex(oidp));
                parent = parent->next;
@@ -1156,7 +1156,7 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
                return 1;
        case 'h':               /* abbreviated commit hash */
                strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_COMMIT));
-               strbuf_add_unique_abbrev(sb, commit->object.oid.hash,
+               strbuf_add_unique_abbrev(sb, &commit->object.oid,
                                         c->pretty_ctx->abbrev);
                strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET));
                return 1;
@@ -1164,7 +1164,7 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
                strbuf_addstr(sb, oid_to_hex(&commit->tree->object.oid));
                return 1;
        case 't':               /* abbreviated tree hash */
-               strbuf_add_unique_abbrev(sb, commit->tree->object.oid.hash,
+               strbuf_add_unique_abbrev(sb, &commit->tree->object.oid,
                                         c->pretty_ctx->abbrev);
                return 1;
        case 'P':               /* parent hashes */
@@ -1178,7 +1178,7 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
                for (p = commit->parents; p; p = p->next) {
                        if (p != commit->parents)
                                strbuf_addch(sb, ' ');
-                       strbuf_add_unique_abbrev(sb, p->item->object.oid.hash,
+                       strbuf_add_unique_abbrev(sb, &p->item->object.oid,
                                                 c->pretty_ctx->abbrev);
                }
                return 1;
index 191ebe3e6a99d26913a510967a9545f53db58bc8..a6ea33a5db8b616420572cda4b857ac6d7d43cb1 100644 (file)
@@ -11,6 +11,7 @@
 #include "list-objects.h"
 #include "packfile.h"
 #include "worktree.h"
+#include "object-store.h"
 
 struct connectivity_progress {
        struct progress *progress;
@@ -77,7 +78,7 @@ static void add_recent_object(const struct object_id *oid,
         * later processing, and the revision machinery expects
         * commits and tags to have been parsed.
         */
-       type = sha1_object_info(oid->hash, NULL);
+       type = oid_object_info(oid, NULL);
        if (type < 0)
                die("unable to get object info for %s", oid_to_hex(oid));
 
index 59a73f4a81d76a19b8a2280e9643f7c1e715a5d4..10f1c6bb8a316e85448445afc3478c832d61709c 100644 (file)
@@ -185,7 +185,7 @@ static int ce_compare_link(const struct cache_entry *ce, size_t expected_size)
        if (strbuf_readlink(&sb, ce->name, expected_size))
                return -1;
 
-       buffer = read_sha1_file(ce->oid.hash, &type, &size);
+       buffer = read_object_file(&ce->oid, &type, &size);
        if (buffer) {
                if (size == sb.len)
                        match = memcmp(buffer, sb.buf, size);
@@ -2693,7 +2693,7 @@ void *read_blob_data_from_index(const struct index_state *istate,
        }
        if (pos < 0)
                return NULL;
-       data = read_sha1_file(istate->cache[pos]->oid.hash, &type, &sz);
+       data = read_object_file(&istate->cache[pos]->oid, &type, &sz);
        if (!data || type != OBJ_BLOB) {
                free(data);
                return NULL;
index 6e9328b274de7e4c8f7935ff289fba5b64dbd43f..ac82f9f21e15b26d1654d63e8cabb621175f7d34 100644 (file)
@@ -728,7 +728,7 @@ int verify_ref_format(struct ref_format *format)
 static void *get_obj(const struct object_id *oid, struct object **obj, unsigned long *sz, int *eaten)
 {
        enum object_type type;
-       void *buf = read_sha1_file(oid->hash, &type, sz);
+       void *buf = read_object_file(oid, &type, sz);
 
        if (buf)
                *obj = parse_object_buffer(oid, type, *sz, buf, eaten);
@@ -737,18 +737,18 @@ static void *get_obj(const struct object_id *oid, struct object **obj, unsigned
        return buf;
 }
 
-static int grab_objectname(const char *name, const unsigned char *sha1,
+static int grab_objectname(const char *name, const struct object_id *oid,
                           struct atom_value *v, struct used_atom *atom)
 {
        if (starts_with(name, "objectname")) {
                if (atom->u.objectname.option == O_SHORT) {
-                       v->s = xstrdup(find_unique_abbrev(sha1, DEFAULT_ABBREV));
+                       v->s = xstrdup(find_unique_abbrev(oid, DEFAULT_ABBREV));
                        return 1;
                } else if (atom->u.objectname.option == O_FULL) {
-                       v->s = xstrdup(sha1_to_hex(sha1));
+                       v->s = xstrdup(oid_to_hex(oid));
                        return 1;
                } else if (atom->u.objectname.option == O_LENGTH) {
-                       v->s = xstrdup(find_unique_abbrev(sha1, atom->u.objectname.length));
+                       v->s = xstrdup(find_unique_abbrev(oid, atom->u.objectname.length));
                        return 1;
                } else
                        die("BUG: unknown %%(objectname) option");
@@ -775,7 +775,7 @@ static void grab_common_values(struct atom_value *val, int deref, struct object
                        v->s = xstrfmt("%lu", sz);
                }
                else if (deref)
-                       grab_objectname(name, obj->oid.hash, v, &used_atom[i]);
+                       grab_objectname(name, &obj->oid, v, &used_atom[i]);
        }
 }
 
@@ -1309,10 +1309,14 @@ char *get_head_description(void)
        memset(&state, 0, sizeof(state));
        wt_status_get_state(&state, 1);
        if (state.rebase_in_progress ||
-           state.rebase_interactive_in_progress)
-               strbuf_addf(&desc, _("(no branch, rebasing %s)"),
-                           state.branch);
-       else if (state.bisect_in_progress)
+           state.rebase_interactive_in_progress) {
+               if (state.branch)
+                       strbuf_addf(&desc, _("(no branch, rebasing %s)"),
+                                   state.branch);
+               else
+                       strbuf_addf(&desc, _("(no branch, rebasing detached HEAD %s)"),
+                                   state.detached_from);
+       } else if (state.bisect_in_progress)
                strbuf_addf(&desc, _("(no branch, bisect started on %s)"),
                            state.branch);
        else if (state.detached_from) {
@@ -1455,7 +1459,7 @@ static void populate_value(struct ref_array_item *ref)
                                v->s = xstrdup(buf + 1);
                        }
                        continue;
-               } else if (!deref && grab_objectname(name, ref->objectname.hash, v, atom)) {
+               } else if (!deref && grab_objectname(name, &ref->objectname, v, atom)) {
                        continue;
                } else if (!strcmp(name, "HEAD")) {
                        if (atom->u.head && !strcmp(ref->refname, atom->u.head))
diff --git a/refs.c b/refs.c
index 20ba82b4343ff2ef72cea32deec8a8d7fbd6def7..8b7a77fe5eedb08c0b034b1cf3bb4ef40efa9834 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -301,7 +301,7 @@ enum peel_status peel_object(const struct object_id *name, struct object_id *oid
        struct object *o = lookup_unknown_object(name->hash);
 
        if (o->type == OBJ_NONE) {
-               int type = sha1_object_info(name->hash, NULL);
+               int type = oid_object_info(name, NULL);
                if (type < 0 || !object_as_type(o, type, 0))
                        return PEEL_INVALID;
        }
index bec8e30e9e3e2995739dfff7cc971f8de623610d..a92a2aa82137e811e12d1e9d67eb3b4fd85f19fd 100644 (file)
@@ -9,6 +9,7 @@
 #include "../lockfile.h"
 #include "../object.h"
 #include "../dir.h"
+#include "../chdir-notify.h"
 
 /*
  * This backend uses the following flags in `ref_update::flags` for
@@ -106,6 +107,11 @@ static struct ref_store *files_ref_store_create(const char *gitdir,
        refs->packed_ref_store = packed_ref_store_create(sb.buf, flags);
        strbuf_release(&sb);
 
+       chdir_notify_reparent("files-backend $GIT_DIR",
+                             &refs->gitdir);
+       chdir_notify_reparent("files-backend $GIT_COMMONDIR",
+                             &refs->gitcommondir);
+
        return ref_store;
 }
 
index 65288c647278aa27790b13c0360f756686dadf7a..369c34f886fc5532de2afbd1590823eed0758a33 100644 (file)
@@ -5,6 +5,7 @@
 #include "packed-backend.h"
 #include "../iterator.h"
 #include "../lockfile.h"
+#include "../chdir-notify.h"
 
 enum mmap_strategy {
        /*
@@ -202,6 +203,8 @@ struct ref_store *packed_ref_store_create(const char *path,
        refs->store_flags = store_flags;
 
        refs->path = xstrdup(path);
+       chdir_notify_reparent("packed-refs", &refs->path);
+
        return ref_store;
 }
 
index bcebb4c789567eb4017a3a0132ba55c59c427991..c4bb9a8ba920c1b344b910e7f6e59915044f4f9a 100644 (file)
@@ -61,7 +61,7 @@ static char *read_ref_note(const struct object_id *oid)
        init_notes(NULL, notes_ref, NULL, 0);
        if (!(note_oid = get_note(NULL, oid)))
                return NULL;    /* note tree not found */
-       if (!(msg = read_sha1_file(note_oid->hash, &type, &msglen)))
+       if (!(msg = read_object_file(note_oid, &type, &msglen)))
                error("Empty notes tree. %s", notes_ref);
        else if (!msglen || type != OBJ_BLOB) {
                error("Note contains unusable content. "
@@ -108,7 +108,7 @@ static int note2mark_cb(const struct object_id *object_oid,
        enum object_type type;
        struct rev_note note;
 
-       if (!(msg = read_sha1_file(note_oid->hash, &type, &msglen)) ||
+       if (!(msg = read_object_file(note_oid, &type, &msglen)) ||
                        !msglen || type != OBJ_BLOB) {
                free(msg);
                return 1;
index c10d87c24615e9d6497b46a69a82a71d3c1735a6..91eb010ca983c5493bbc17c5652ef31060390226 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -1376,7 +1376,7 @@ static void add_missing_tags(struct ref *src, struct ref **dst, struct ref ***ds
                        continue; /* not a tag */
                if (string_list_has_string(&dst_tag, ref->name))
                        continue; /* they already have it */
-               if (sha1_object_info(ref->new_oid.hash, NULL) != OBJ_TAG)
+               if (oid_object_info(&ref->new_oid, NULL) != OBJ_TAG)
                        continue; /* be conservative */
                item = string_list_append(&src_tag, ref->name);
                item->util = ref;
index 3e49965d050829ad883e571d9b7c4596991aa974..336357394d8b1eac1414fe4577272b0002463a86 100644 (file)
@@ -8,8 +8,8 @@
  * sha1.
  */
 static struct replace_object {
-       unsigned char original[20];
-       unsigned char replacement[20];
+       struct object_id original;
+       struct object_id replacement;
 } **replace_object;
 
 static int replace_object_alloc, replace_object_nr;
@@ -17,7 +17,7 @@ static int replace_object_alloc, replace_object_nr;
 static const unsigned char *replace_sha1_access(size_t index, void *table)
 {
        struct replace_object **replace = table;
-       return replace[index]->original;
+       return replace[index]->original.hash;
 }
 
 static int replace_object_pos(const unsigned char *sha1)
@@ -29,7 +29,7 @@ static int replace_object_pos(const unsigned char *sha1)
 static int register_replace_object(struct replace_object *replace,
                                   int ignore_dups)
 {
-       int pos = replace_object_pos(replace->original);
+       int pos = replace_object_pos(replace->original.hash);
 
        if (0 <= pos) {
                if (ignore_dups)
@@ -59,14 +59,14 @@ static int register_replace_ref(const char *refname,
        const char *hash = slash ? slash + 1 : refname;
        struct replace_object *repl_obj = xmalloc(sizeof(*repl_obj));
 
-       if (strlen(hash) != 40 || get_sha1_hex(hash, repl_obj->original)) {
+       if (get_oid_hex(hash, &repl_obj->original)) {
                free(repl_obj);
                warning("bad replace ref name: %s", refname);
                return 0;
        }
 
        /* Copy sha1 from the read ref */
-       hashcpy(repl_obj->replacement, oid->hash);
+       oidcpy(&repl_obj->replacement, oid);
 
        /* Register new object */
        if (register_replace_object(repl_obj, 1))
@@ -92,16 +92,16 @@ static void prepare_replace_object(void)
 #define MAXREPLACEDEPTH 5
 
 /*
- * If a replacement for object sha1 has been set up, return the
+ * If a replacement for object oid has been set up, return the
  * replacement object's name (replaced recursively, if necessary).
- * The return value is either sha1 or a pointer to a
+ * The return value is either oid or a pointer to a
  * permanently-allocated value.  This function always respects replace
  * references, regardless of the value of check_replace_refs.
  */
-const unsigned char *do_lookup_replace_object(const unsigned char *sha1)
+const struct object_id *do_lookup_replace_object(const struct object_id *oid)
 {
        int pos, depth = MAXREPLACEDEPTH;
-       const unsigned char *cur = sha1;
+       const struct object_id *cur = oid;
 
        prepare_replace_object();
 
@@ -109,11 +109,11 @@ const unsigned char *do_lookup_replace_object(const unsigned char *sha1)
        do {
                if (--depth < 0)
                        die("replace depth too high for object %s",
-                           sha1_to_hex(sha1));
+                           oid_to_hex(oid));
 
-               pos = replace_object_pos(cur);
+               pos = replace_object_pos(cur->hash);
                if (0 <= pos)
-                       cur = replace_object[pos]->replacement;
+                       cur = &replace_object[pos]->replacement;
        } while (0 <= pos);
 
        return cur;
index 4ffbe9bc94edc18314cb49c945038e2f20a40922..a4848c1bd05e94efbf7aadf155c2cce504523c83 100644 (file)
@@ -1,67 +1,73 @@
 #include "cache.h"
 #include "repository.h"
+#include "object-store.h"
 #include "config.h"
 #include "submodule-config.h"
 
 /* The main repository */
-static struct repository the_repo = {
-       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &the_index, &hash_algos[GIT_HASH_SHA1], 0, 0
-};
-struct repository *the_repository = &the_repo;
+static struct repository the_repo;
+struct repository *the_repository;
 
-static char *git_path_from_env(const char *envvar, const char *git_dir,
-                              const char *path, int fromenv)
+void initialize_the_repository(void)
 {
-       if (fromenv) {
-               const char *value = getenv(envvar);
-               if (value)
-                       return xstrdup(value);
-       }
+       the_repository = &the_repo;
 
-       return xstrfmt("%s/%s", git_dir, path);
+       the_repo.index = &the_index;
+       the_repo.objects = raw_object_store_new();
+       repo_set_hash_algo(&the_repo, GIT_HASH_SHA1);
 }
 
-static int find_common_dir(struct strbuf *sb, const char *gitdir, int fromenv)
+static void expand_base_dir(char **out, const char *in,
+                           const char *base_dir, const char *def_in)
 {
-       if (fromenv) {
-               const char *value = getenv(GIT_COMMON_DIR_ENVIRONMENT);
-               if (value) {
-                       strbuf_addstr(sb, value);
-                       return 1;
-               }
-       }
-
-       return get_common_dir_noenv(sb, gitdir);
+       free(*out);
+       if (in)
+               *out = xstrdup(in);
+       else
+               *out = xstrfmt("%s/%s", base_dir, def_in);
 }
 
-static void repo_setup_env(struct repository *repo)
+static void repo_set_commondir(struct repository *repo,
+                              const char *commondir)
 {
        struct strbuf sb = STRBUF_INIT;
 
-       repo->different_commondir = find_common_dir(&sb, repo->gitdir,
-                                                   !repo->ignore_env);
        free(repo->commondir);
+
+       if (commondir) {
+               repo->different_commondir = 1;
+               repo->commondir = xstrdup(commondir);
+               return;
+       }
+
+       repo->different_commondir = get_common_dir_noenv(&sb, repo->gitdir);
        repo->commondir = strbuf_detach(&sb, NULL);
-       free(repo->objectdir);
-       repo->objectdir = git_path_from_env(DB_ENVIRONMENT, repo->commondir,
-                                           "objects", !repo->ignore_env);
-       free(repo->graft_file);
-       repo->graft_file = git_path_from_env(GRAFT_ENVIRONMENT, repo->commondir,
-                                            "info/grafts", !repo->ignore_env);
-       free(repo->index_file);
-       repo->index_file = git_path_from_env(INDEX_ENVIRONMENT, repo->gitdir,
-                                            "index", !repo->ignore_env);
 }
 
-void repo_set_gitdir(struct repository *repo, const char *path)
+void repo_set_gitdir(struct repository *repo,
+                    const char *root,
+                    const struct set_gitdir_args *o)
 {
-       const char *gitfile = read_gitfile(path);
+       const char *gitfile = read_gitfile(root);
+       /*
+        * repo->gitdir is saved because the caller could pass "root"
+        * that also points to repo->gitdir. We want to keep it alive
+        * until after xstrdup(root). Then we can free it.
+        */
        char *old_gitdir = repo->gitdir;
 
-       repo->gitdir = xstrdup(gitfile ? gitfile : path);
-       repo_setup_env(repo);
-
+       repo->gitdir = xstrdup(gitfile ? gitfile : root);
        free(old_gitdir);
+
+       repo_set_commondir(repo, o->commondir);
+       expand_base_dir(&repo->objects->objectdir, o->object_dir,
+                       repo->commondir, "objects");
+       free(repo->objects->alternate_db);
+       repo->objects->alternate_db = xstrdup_or_null(o->alternate_db);
+       expand_base_dir(&repo->graft_file, o->graft_file,
+                       repo->commondir, "info/grafts");
+       expand_base_dir(&repo->index_file, o->index_file,
+                       repo->gitdir, "index");
 }
 
 void repo_set_hash_algo(struct repository *repo, int hash_algo)
@@ -79,6 +85,7 @@ static int repo_init_gitdir(struct repository *repo, const char *gitdir)
        int error = 0;
        char *abspath = NULL;
        const char *resolved_gitdir;
+       struct set_gitdir_args args = { NULL };
 
        abspath = real_pathdup(gitdir, 0);
        if (!abspath) {
@@ -93,7 +100,7 @@ static int repo_init_gitdir(struct repository *repo, const char *gitdir)
                goto out;
        }
 
-       repo_set_gitdir(repo, resolved_gitdir);
+       repo_set_gitdir(repo, resolved_gitdir, &args);
 
 out:
        free(abspath);
@@ -128,12 +135,14 @@ static int read_and_verify_repository_format(struct repository_format *format,
  * Initialize 'repo' based on the provided 'gitdir'.
  * Return 0 upon success and a non-zero value upon failure.
  */
-int repo_init(struct repository *repo, const char *gitdir, const char *worktree)
+static int repo_init(struct repository *repo,
+                    const char *gitdir,
+                    const char *worktree)
 {
        struct repository_format format;
        memset(repo, 0, sizeof(*repo));
 
-       repo->ignore_env = 1;
+       repo->objects = raw_object_store_new();
 
        if (repo_init_gitdir(repo, gitdir))
                goto error;
@@ -209,12 +218,14 @@ void repo_clear(struct repository *repo)
 {
        FREE_AND_NULL(repo->gitdir);
        FREE_AND_NULL(repo->commondir);
-       FREE_AND_NULL(repo->objectdir);
        FREE_AND_NULL(repo->graft_file);
        FREE_AND_NULL(repo->index_file);
        FREE_AND_NULL(repo->worktree);
        FREE_AND_NULL(repo->submodule_prefix);
 
+       raw_object_store_clear(repo->objects);
+       FREE_AND_NULL(repo->objects);
+
        if (repo->config) {
                git_configset_clear(repo->config);
                FREE_AND_NULL(repo->config);
index 0329e40c7f5e72dad3ba46328a8e3d6c29ed8e58..09df94a4722dacc40ab106e3b3ca348167daa764 100644 (file)
@@ -2,9 +2,10 @@
 #define REPOSITORY_H
 
 struct config_set;
+struct git_hash_algo;
 struct index_state;
+struct raw_object_store;
 struct submodule_cache;
-struct git_hash_algo;
 
 struct repository {
        /* Environment */
@@ -21,10 +22,9 @@ struct repository {
        char *commondir;
 
        /*
-        * Path to the repository's object store.
-        * Cannot be NULL after initialization.
+        * Holds any information related to accessing the raw object content.
         */
-       char *objectdir;
+       struct raw_object_store *objects;
 
        /*
         * Path to the repository's graft file.
@@ -72,15 +72,6 @@ struct repository {
        const struct git_hash_algo *hash_algo;
 
        /* Configurations */
-       /*
-        * Bit used during initialization to indicate if repository state (like
-        * the location of the 'objectdir') should be read from the
-        * environment.  By default this bit will be set at the begining of
-        * 'repo_init()' so that all repositories will ignore the environment.
-        * The exception to this is 'the_repository', which doesn't go through
-        * the normal 'repo_init()' process.
-        */
-       unsigned ignore_env:1;
 
        /* Indicate if a repository has a different 'commondir' from 'gitdir' */
        unsigned different_commondir:1;
@@ -88,10 +79,24 @@ struct repository {
 
 extern struct repository *the_repository;
 
-extern void repo_set_gitdir(struct repository *repo, const char *path);
+/*
+ * Define a custom repository layout. Any field can be NULL, which
+ * will default back to the path according to the default layout.
+ */
+struct set_gitdir_args {
+       const char *commondir;
+       const char *object_dir;
+       const char *graft_file;
+       const char *index_file;
+       const char *alternate_db;
+};
+
+extern void repo_set_gitdir(struct repository *repo,
+                           const char *root,
+                           const struct set_gitdir_args *extra_args);
 extern void repo_set_worktree(struct repository *repo, const char *path);
 extern void repo_set_hash_algo(struct repository *repo, int algo);
-extern int repo_init(struct repository *repo, const char *gitdir, const char *worktree);
+extern void initialize_the_repository(void);
 extern int repo_submodule_init(struct repository *submodule,
                               struct repository *superproject,
                               const char *path);
index ea24d4c2f47ab6495d97f38245dd420a1ad38391..18cae2d11c9a86aae0ed352a8f7606b142c5c183 100644 (file)
--- a/rerere.c
+++ b/rerere.c
@@ -979,8 +979,8 @@ static int handle_cache(const char *path, unsigned char *sha1, const char *outpu
                        break;
                i = ce_stage(ce) - 1;
                if (!mmfile[i].ptr) {
-                       mmfile[i].ptr = read_sha1_file(ce->oid.hash, &type,
-                                                      &size);
+                       mmfile[i].ptr = read_object_file(&ce->oid, &type,
+                                                        &size);
                        mmfile[i].size = size;
                }
        }
index b40f3173d3fe5ef5c06c00ff8994060a9078669d..aed95b4b35fbb187bb96242afcf6b4d8e3d2008b 100644 (file)
@@ -24,7 +24,7 @@ void record_resolve_undo(struct index_state *istate, struct cache_entry *ce)
        if (!lost->util)
                lost->util = xcalloc(1, sizeof(*ui));
        ui = lost->util;
-       hashcpy(ui->sha1[stage - 1], ce->oid.hash);
+       oidcpy(&ui->oid[stage - 1], &ce->oid);
        ui->mode[stage - 1] = ce->ce_mode;
 }
 
@@ -44,7 +44,7 @@ void resolve_undo_write(struct strbuf *sb, struct string_list *resolve_undo)
                for (i = 0; i < 3; i++) {
                        if (!ui->mode[i])
                                continue;
-                       strbuf_add(sb, ui->sha1[i], 20);
+                       strbuf_add(sb, ui->oid[i].hash, the_hash_algo->rawsz);
                }
        }
 }
@@ -55,6 +55,7 @@ struct string_list *resolve_undo_read(const char *data, unsigned long size)
        size_t len;
        char *endptr;
        int i;
+       const unsigned rawsz = the_hash_algo->rawsz;
 
        resolve_undo = xcalloc(1, sizeof(*resolve_undo));
        resolve_undo->strdup_strings = 1;
@@ -87,11 +88,11 @@ struct string_list *resolve_undo_read(const char *data, unsigned long size)
                for (i = 0; i < 3; i++) {
                        if (!ui->mode[i])
                                continue;
-                       if (size < 20)
+                       if (size < rawsz)
                                goto error;
-                       hashcpy(ui->sha1[i], (const unsigned char *)data);
-                       size -= 20;
-                       data += 20;
+                       memcpy(ui->oid[i].hash, (const unsigned char *)data, rawsz);
+                       size -= rawsz;
+                       data += rawsz;
                }
        }
        return resolve_undo;
@@ -145,7 +146,7 @@ int unmerge_index_entry_at(struct index_state *istate, int pos)
                struct cache_entry *nce;
                if (!ru->mode[i])
                        continue;
-               nce = make_cache_entry(ru->mode[i], ru->sha1[i],
+               nce = make_cache_entry(ru->mode[i], ru->oid[i].hash,
                                       name, i + 1, 0);
                if (matched)
                        nce->ce_flags |= CE_MATCHED;
index 46306455edddb94a554a7a2fcadf49a30861f599..87291904bd34e0e7f3a3601b6742f5345391824d 100644 (file)
@@ -3,7 +3,7 @@
 
 struct resolve_undo_info {
        unsigned int mode[3];
-       unsigned char sha1[3][20];
+       struct object_id oid[3];
 };
 
 extern void record_resolve_undo(struct index_state *, struct cache_entry *);
index a483d5904a3ec1acae8908dd2e699fa00bcaaa9d..84899e423f098bb8cd61eee86bcc484139b1482f 100644 (file)
@@ -621,7 +621,7 @@ static void trace_run_command(const struct child_process *cp)
        if (!trace_want(&trace_default_key))
                return;
 
-       strbuf_addf(&buf, "trace: run_command:");
+       strbuf_addstr(&buf, "trace: run_command:");
        if (cp->dir) {
                strbuf_addstr(&buf, " cd ");
                sq_quote_buf_pretty(&buf, cp->dir);
index 8d9190f5e7815c6b2f18afd266643a8c862e526e..19025a7aca82a7066b9a2d40d4d50406a9749a5f 100644 (file)
@@ -37,14 +37,14 @@ int option_parse_push_signed(const struct option *opt,
        die("bad %s argument: %s", opt->long_name, arg);
 }
 
-static void feed_object(const unsigned char *sha1, FILE *fh, int negative)
+static void feed_object(const struct object_id *oid, FILE *fh, int negative)
 {
-       if (negative && !has_sha1_file(sha1))
+       if (negative && !has_sha1_file(oid->hash))
                return;
 
        if (negative)
                putc('^', fh);
-       fputs(sha1_to_hex(sha1), fh);
+       fputs(oid_to_hex(oid), fh);
        putc('\n', fh);
 }
 
@@ -89,13 +89,13 @@ static int pack_objects(int fd, struct ref *refs, struct oid_array *extra, struc
         */
        po_in = xfdopen(po.in, "w");
        for (i = 0; i < extra->nr; i++)
-               feed_object(extra->oid[i].hash, po_in, 1);
+               feed_object(&extra->oid[i], po_in, 1);
 
        while (refs) {
                if (!is_null_oid(&refs->old_oid))
-                       feed_object(refs->old_oid.hash, po_in, 1);
+                       feed_object(&refs->old_oid, po_in, 1);
                if (!is_null_oid(&refs->new_oid))
-                       feed_object(refs->new_oid.hash, po_in, 0);
+                       feed_object(&refs->new_oid, po_in, 0);
                refs = refs->next;
        }
 
index f9d1001dee9ad10e243aaeafc46fbdd13597fce7..a7d31e0525cead13981172851383d2f5da4f70fc 100644 (file)
@@ -127,6 +127,7 @@ static GIT_PATH_FUNC(rebase_path_rewritten_pending,
 static GIT_PATH_FUNC(rebase_path_gpg_sign_opt, "rebase-merge/gpg_sign_opt")
 static GIT_PATH_FUNC(rebase_path_orig_head, "rebase-merge/orig-head")
 static GIT_PATH_FUNC(rebase_path_verbose, "rebase-merge/verbose")
+static GIT_PATH_FUNC(rebase_path_signoff, "rebase-merge/signoff")
 static GIT_PATH_FUNC(rebase_path_head_name, "rebase-merge/head-name")
 static GIT_PATH_FUNC(rebase_path_onto, "rebase-merge/onto")
 static GIT_PATH_FUNC(rebase_path_autostash, "rebase-merge/autostash")
@@ -282,7 +283,7 @@ struct commit_message {
 
 static const char *short_commit_name(struct commit *commit)
 {
-       return find_unique_abbrev(commit->object.oid.hash, DEFAULT_ABBREV);
+       return find_unique_abbrev(&commit->object.oid, DEFAULT_ABBREV);
 }
 
 static int get_message(struct commit *commit, struct commit_message *out)
@@ -1112,7 +1113,7 @@ static int try_to_commit(struct strbuf *msg, const char *author,
                commit_list_insert(current_head, &parents);
        }
 
-       if (write_cache_as_tree(tree.hash, 0, NULL)) {
+       if (write_cache_as_tree(&tree, 0, NULL)) {
                res = error(_("git write-tree failed to write a tree"));
                goto out;
        }
@@ -1474,7 +1475,7 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
                 * that represents the "current" state for merge-recursive
                 * to work on.
                 */
-               if (write_cache_as_tree(head.hash, 0, NULL))
+               if (write_cache_as_tree(&head, 0, NULL))
                        return error(_("your index file is unmerged."));
        } else {
                unborn = get_oid("HEAD", &head);
@@ -1604,7 +1605,7 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
                }
        }
 
-       if (opts->signoff)
+       if (opts->signoff && !is_fixup(command))
                append_signoff(&msgbuf, 0, 0);
 
        if (is_rebase_i(opts) && write_author_script(msg.message) < 0)
@@ -2043,6 +2044,11 @@ static int read_populate_opts(struct replay_opts *opts)
                if (file_exists(rebase_path_verbose()))
                        opts->verbose = 1;
 
+               if (file_exists(rebase_path_signoff())) {
+                       opts->allow_ff = 0;
+                       opts->signoff = 1;
+               }
+
                read_strategy_opts(opts, &buf);
                strbuf_release(&buf);
 
@@ -2876,7 +2882,8 @@ int sequencer_pick_revisions(struct replay_opts *opts)
 
                if (!get_oid(name, &oid)) {
                        if (!lookup_commit_reference_gently(&oid, 1)) {
-                               enum object_type type = sha1_object_info(oid.hash, NULL);
+                               enum object_type type = oid_object_info(&oid,
+                                                                       NULL);
                                return error(_("%s: can't cherry-pick a %s"),
                                        name, type_name(type));
                        }
@@ -3000,7 +3007,7 @@ int sequencer_make_script(FILE *out, int argc, const char **argv,
        init_revisions(&revs, NULL);
        revs.verbose_header = 1;
        revs.max_parents = 1;
-       revs.cherry_pick = 1;
+       revs.cherry_mark = 1;
        revs.limited = 1;
        revs.reverse = 1;
        revs.right_only = 1;
@@ -3025,8 +3032,12 @@ int sequencer_make_script(FILE *out, int argc, const char **argv,
                return error(_("make_script: error preparing revisions"));
 
        while ((commit = get_revision(&revs))) {
+               int is_empty  = is_original_commit_empty(commit);
+
+               if (!is_empty && (commit->object.flags & PATCHSAME))
+                       continue;
                strbuf_reset(&buf);
-               if (!keep_empty && is_original_commit_empty(commit))
+               if (!keep_empty && is_empty)
                        strbuf_addf(&buf, "%c ", comment_line_char);
                strbuf_addf(&buf, "%s %s ", insn,
                            oid_to_hex(&commit->object.oid));
index 26a6c20b7d420f679d7cceaeba4acdb8ae8c00e7..83460ec0d6f10b26719c076639a08a8a0ce803cc 100644 (file)
@@ -1,9 +1,11 @@
 #include "cache.h"
+#include "repository.h"
 #include "refs.h"
 #include "object.h"
 #include "commit.h"
 #include "tag.h"
 #include "packfile.h"
+#include "object-store.h"
 
 /*
  * Create the file "path" by writing to a temporary file and renaming
@@ -199,8 +201,7 @@ static void init_pack_info(const char *infofile, int force)
        objdir = get_object_directory();
        objdirlen = strlen(objdir);
 
-       prepare_packed_git();
-       for (p = packed_git; p; p = p->next) {
+       for (p = get_packed_git(the_repository); p; p = p->next) {
                /* we ignore things on alternate path since they are
                 * not available to the pullers in general.
                 */
@@ -210,7 +211,7 @@ static void init_pack_info(const char *infofile, int force)
        }
        num_pack = i;
        info = xcalloc(num_pack, sizeof(struct pack_info *));
-       for (i = 0, p = packed_git; p; p = p->next) {
+       for (i = 0, p = get_packed_git(the_repository); p; p = p->next) {
                if (!p->pack_local)
                        continue;
                info[i] = xcalloc(1, sizeof(struct pack_info));
diff --git a/setup.c b/setup.c
index 72877796420b06213665f5d357decb202e71fa91..3e03d442b6fad10c1b11fb8e8626f3c4fe444298 100644 (file)
--- a/setup.c
+++ b/setup.c
@@ -3,6 +3,7 @@
 #include "config.h"
 #include "dir.h"
 #include "string-list.h"
+#include "chdir-notify.h"
 
 static int inside_git_dir = -1;
 static int inside_work_tree = -1;
@@ -378,7 +379,7 @@ int is_inside_work_tree(void)
 
 void setup_work_tree(void)
 {
-       const char *work_tree, *git_dir;
+       const char *work_tree;
        static int initialized = 0;
 
        if (initialized)
@@ -388,10 +389,7 @@ void setup_work_tree(void)
                die(_("unable to set up work tree using invalid config"));
 
        work_tree = get_git_work_tree();
-       git_dir = get_git_dir();
-       if (!is_absolute_path(git_dir))
-               git_dir = real_path(get_git_dir());
-       if (!work_tree || chdir(work_tree))
+       if (!work_tree || chdir_notify(work_tree))
                die(_("this operation must be run in a work tree"));
 
        /*
@@ -401,7 +399,6 @@ void setup_work_tree(void)
        if (getenv(GIT_WORK_TREE_ENVIRONMENT))
                setenv(GIT_WORK_TREE_ENVIRONMENT, ".", 1);
 
-       set_git_dir(remove_leading_path(git_dir, work_tree));
        initialized = 1;
 }
 
@@ -1116,8 +1113,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
                        const char *gitdir = getenv(GIT_DIR_ENVIRONMENT);
                        if (!gitdir)
                                gitdir = DEFAULT_GIT_DIR_ENVIRONMENT;
-                       repo_set_gitdir(the_repository, gitdir);
-                       setup_git_env();
+                       setup_git_env(gitdir);
                }
                if (startup_info->have_repository)
                        repo_set_hash_algo(the_repository, repo_fmt.hash_algo);
index cc0f43ea849569664d1af9fe05a6b42917990a7f..77ccaab928529d37aa971168c54e31358e12ef8e 100644 (file)
@@ -22,6 +22,7 @@
 #include "pack-revindex.h"
 #include "sha1-lookup.h"
 #include "bulk-checkin.h"
+#include "repository.h"
 #include "streaming.h"
 #include "dir.h"
 #include "list.h"
 #include "quote.h"
 #include "packfile.h"
 #include "fetch-object.h"
+#include "object-store.h"
+
+/* The maximum size for an object header. */
+#define MAX_HEADER_LEN 32
 
 const unsigned char null_sha1[GIT_MAX_RAWSZ];
 const struct object_id null_oid;
@@ -319,9 +324,9 @@ static void fill_sha1_path(struct strbuf *buf, const unsigned char *sha1)
        }
 }
 
-void sha1_file_name(struct strbuf *buf, const unsigned char *sha1)
+void sha1_file_name(struct repository *r, struct strbuf *buf, const unsigned char *sha1)
 {
-       strbuf_addstr(buf, get_object_directory());
+       strbuf_addstr(buf, r->objects->objectdir);
        strbuf_addch(buf, '/');
        fill_sha1_path(buf, sha1);
 }
@@ -340,13 +345,12 @@ static const char *alt_sha1_path(struct alternate_object_database *alt,
        return buf->buf;
 }
 
-struct alternate_object_database *alt_odb_list;
-static struct alternate_object_database **alt_odb_tail;
-
 /*
  * Return non-zero iff the path is usable as an alternate object database.
  */
-static int alt_odb_usable(struct strbuf *path, const char *normalized_objdir)
+static int alt_odb_usable(struct raw_object_store *o,
+                         struct strbuf *path,
+                         const char *normalized_objdir)
 {
        struct alternate_object_database *alt;
 
@@ -362,7 +366,7 @@ static int alt_odb_usable(struct strbuf *path, const char *normalized_objdir)
         * Prevent the common mistake of listing the same
         * thing twice, or object directory itself.
         */
-       for (alt = alt_odb_list; alt; alt = alt->next) {
+       for (alt = o->alt_odb_list; alt; alt = alt->next) {
                if (!fspathcmp(path->buf, alt->path))
                        return 0;
        }
@@ -387,9 +391,11 @@ static int alt_odb_usable(struct strbuf *path, const char *normalized_objdir)
  * SHA1, an extra slash for the first level indirection, and the
  * terminating NUL.
  */
-static void read_info_alternates(const char * relative_base, int depth);
-static int link_alt_odb_entry(const char *entry, const char *relative_base,
-       int depth, const char *normalized_objdir)
+static void read_info_alternates(struct repository *r,
+                                const char *relative_base,
+                                int depth);
+static int link_alt_odb_entry(struct repository *r, const char *entry,
+       const char *relative_base, int depth, const char *normalized_objdir)
 {
        struct alternate_object_database *ent;
        struct strbuf pathbuf = STRBUF_INIT;
@@ -414,7 +420,7 @@ static int link_alt_odb_entry(const char *entry, const char *relative_base,
        while (pathbuf.len && pathbuf.buf[pathbuf.len - 1] == '/')
                strbuf_setlen(&pathbuf, pathbuf.len - 1);
 
-       if (!alt_odb_usable(&pathbuf, normalized_objdir)) {
+       if (!alt_odb_usable(r->objects, &pathbuf, normalized_objdir)) {
                strbuf_release(&pathbuf);
                return -1;
        }
@@ -422,12 +428,12 @@ static int link_alt_odb_entry(const char *entry, const char *relative_base,
        ent = alloc_alt_odb(pathbuf.buf);
 
        /* add the alternate entry */
-       *alt_odb_tail = ent;
-       alt_odb_tail = &(ent->next);
+       *r->objects->alt_odb_tail = ent;
+       r->objects->alt_odb_tail = &(ent->next);
        ent->next = NULL;
 
        /* recursively add alternates */
-       read_info_alternates(pathbuf.buf, depth + 1);
+       read_info_alternates(r, pathbuf.buf, depth + 1);
 
        strbuf_release(&pathbuf);
        return 0;
@@ -462,8 +468,8 @@ static const char *parse_alt_odb_entry(const char *string,
        return end;
 }
 
-static void link_alt_odb_entries(const char *alt, int sep,
-                                const char *relative_base, int depth)
+static void link_alt_odb_entries(struct repository *r, const char *alt,
+                                int sep, const char *relative_base, int depth)
 {
        struct strbuf objdirbuf = STRBUF_INIT;
        struct strbuf entry = STRBUF_INIT;
@@ -477,7 +483,7 @@ static void link_alt_odb_entries(const char *alt, int sep,
                return;
        }
 
-       strbuf_add_absolute_path(&objdirbuf, get_object_directory());
+       strbuf_add_absolute_path(&objdirbuf, r->objects->objectdir);
        if (strbuf_normalize_path(&objdirbuf) < 0)
                die("unable to normalize object directory: %s",
                    objdirbuf.buf);
@@ -486,13 +492,16 @@ static void link_alt_odb_entries(const char *alt, int sep,
                alt = parse_alt_odb_entry(alt, sep, &entry);
                if (!entry.len)
                        continue;
-               link_alt_odb_entry(entry.buf, relative_base, depth, objdirbuf.buf);
+               link_alt_odb_entry(r, entry.buf,
+                                  relative_base, depth, objdirbuf.buf);
        }
        strbuf_release(&entry);
        strbuf_release(&objdirbuf);
 }
 
-static void read_info_alternates(const char * relative_base, int depth)
+static void read_info_alternates(struct repository *r,
+                                const char *relative_base,
+                                int depth)
 {
        char *path;
        struct strbuf buf = STRBUF_INIT;
@@ -504,7 +513,7 @@ static void read_info_alternates(const char * relative_base, int depth)
                return;
        }
 
-       link_alt_odb_entries(buf.buf, '\n', relative_base, depth);
+       link_alt_odb_entries(r, buf.buf, '\n', relative_base, depth);
        strbuf_release(&buf);
        free(path);
 }
@@ -557,8 +566,9 @@ void add_to_alternates_file(const char *reference)
                fprintf_or_die(out, "%s\n", reference);
                if (commit_lock_file(&lock))
                        die_errno("unable to move new alternates file into place");
-               if (alt_odb_tail)
-                       link_alt_odb_entries(reference, '\n', NULL, 0);
+               if (the_repository->objects->alt_odb_tail)
+                       link_alt_odb_entries(the_repository, reference,
+                                            '\n', NULL, 0);
        }
        free(alts);
 }
@@ -569,9 +579,10 @@ void add_to_alternates_memory(const char *reference)
         * Make sure alternates are initialized, or else our entry may be
         * overwritten when they are.
         */
-       prepare_alt_odb();
+       prepare_alt_odb(the_repository);
 
-       link_alt_odb_entries(reference, '\n', NULL, 0);
+       link_alt_odb_entries(the_repository, reference,
+                            '\n', NULL, 0);
 }
 
 /*
@@ -654,8 +665,8 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb)
        struct alternate_object_database *ent;
        int r = 0;
 
-       prepare_alt_odb();
-       for (ent = alt_odb_list; ent; ent = ent->next) {
+       prepare_alt_odb(the_repository);
+       for (ent = the_repository->objects->alt_odb_list; ent; ent = ent->next) {
                r = fn(ent, cb);
                if (r)
                        break;
@@ -663,19 +674,15 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb)
        return r;
 }
 
-void prepare_alt_odb(void)
+void prepare_alt_odb(struct repository *r)
 {
-       const char *alt;
-
-       if (alt_odb_tail)
+       if (r->objects->alt_odb_tail)
                return;
 
-       alt = getenv(ALTERNATE_DB_ENVIRONMENT);
+       r->objects->alt_odb_tail = &r->objects->alt_odb_list;
+       link_alt_odb_entries(r, r->objects->alternate_db, PATH_SEP, NULL, 0);
 
-       alt_odb_tail = &alt_odb_list;
-       link_alt_odb_entries(alt, PATH_SEP, NULL, 0);
-
-       read_info_alternates(get_object_directory(), 0);
+       read_info_alternates(r, r->objects->objectdir, 0);
 }
 
 /* Returns 1 if we have successfully freshened the file, 0 otherwise. */
@@ -707,7 +714,7 @@ static int check_and_freshen_local(const unsigned char *sha1, int freshen)
        static struct strbuf buf = STRBUF_INIT;
 
        strbuf_reset(&buf);
-       sha1_file_name(&buf, sha1);
+       sha1_file_name(the_repository, &buf, sha1);
 
        return check_and_freshen_file(buf.buf, freshen);
 }
@@ -715,8 +722,8 @@ static int check_and_freshen_local(const unsigned char *sha1, int freshen)
 static int check_and_freshen_nonlocal(const unsigned char *sha1, int freshen)
 {
        struct alternate_object_database *alt;
-       prepare_alt_odb();
-       for (alt = alt_odb_list; alt; alt = alt->next) {
+       prepare_alt_odb(the_repository);
+       for (alt = the_repository->objects->alt_odb_list; alt; alt = alt->next) {
                const char *path = alt_sha1_path(alt, sha1);
                if (check_and_freshen_file(path, freshen))
                        return 1;
@@ -784,22 +791,22 @@ void *xmmap(void *start, size_t length,
  * With "map" == NULL, try reading the object named with "sha1" using
  * the streaming interface and rehash it to do the same.
  */
-int check_sha1_signature(const unsigned char *sha1, void *map,
-                        unsigned long size, const char *type)
+int check_object_signature(const struct object_id *oid, void *map,
+                          unsigned long size, const char *type)
 {
        struct object_id real_oid;
        enum object_type obj_type;
        struct git_istream *st;
        git_hash_ctx c;
-       char hdr[32];
+       char hdr[MAX_HEADER_LEN];
        int hdrlen;
 
        if (map) {
                hash_object_file(map, size, type, &real_oid);
-               return hashcmp(sha1, real_oid.hash) ? -1 : 0;
+               return oidcmp(oid, &real_oid) ? -1 : 0;
        }
 
-       st = open_istream(sha1, &obj_type, &size, NULL);
+       st = open_istream(oid, &obj_type, &size, NULL);
        if (!st)
                return -1;
 
@@ -823,7 +830,7 @@ int check_sha1_signature(const unsigned char *sha1, void *map,
        }
        the_hash_algo->final_fn(real_oid.hash, &c);
        close_istream(st);
-       return hashcmp(sha1, real_oid.hash) ? -1 : 0;
+       return oidcmp(oid, &real_oid) ? -1 : 0;
 }
 
 int git_open_cloexec(const char *name, int flags)
@@ -861,22 +868,22 @@ int git_open_cloexec(const char *name, int flags)
  * Note that it may point to static storage and is only valid until another
  * call to sha1_file_name(), etc.
  */
-static int stat_sha1_file(const unsigned char *sha1, struct stat *st,
-                         const char **path)
+static int stat_sha1_file(struct repository *r, const unsigned char *sha1,
+                         struct stat *st, const char **path)
 {
        struct alternate_object_database *alt;
        static struct strbuf buf = STRBUF_INIT;
 
        strbuf_reset(&buf);
-       sha1_file_name(&buf, sha1);
+       sha1_file_name(r, &buf, sha1);
        *path = buf.buf;
 
        if (!lstat(*path, st))
                return 0;
 
-       prepare_alt_odb();
+       prepare_alt_odb(r);
        errno = ENOENT;
-       for (alt = alt_odb_list; alt; alt = alt->next) {
+       for (alt = r->objects->alt_odb_list; alt; alt = alt->next) {
                *path = alt_sha1_path(alt, sha1);
                if (!lstat(*path, st))
                        return 0;
@@ -889,7 +896,8 @@ static int stat_sha1_file(const unsigned char *sha1, struct stat *st,
  * Like stat_sha1_file(), but actually open the object and return the
  * descriptor. See the caveats on the "path" parameter above.
  */
-static int open_sha1_file(const unsigned char *sha1, const char **path)
+static int open_sha1_file(struct repository *r,
+                         const unsigned char *sha1, const char **path)
 {
        int fd;
        struct alternate_object_database *alt;
@@ -897,7 +905,7 @@ static int open_sha1_file(const unsigned char *sha1, const char **path)
        static struct strbuf buf = STRBUF_INIT;
 
        strbuf_reset(&buf);
-       sha1_file_name(&buf, sha1);
+       sha1_file_name(r, &buf, sha1);
        *path = buf.buf;
 
        fd = git_open(*path);
@@ -905,8 +913,8 @@ static int open_sha1_file(const unsigned char *sha1, const char **path)
                return fd;
        most_interesting_errno = errno;
 
-       prepare_alt_odb();
-       for (alt = alt_odb_list; alt; alt = alt->next) {
+       prepare_alt_odb(r);
+       for (alt = r->objects->alt_odb_list; alt; alt = alt->next) {
                *path = alt_sha1_path(alt, sha1);
                fd = git_open(*path);
                if (fd >= 0)
@@ -922,9 +930,8 @@ static int open_sha1_file(const unsigned char *sha1, const char **path)
  * Map the loose object at "path" if it is not NULL, or the path found by
  * searching for a loose object named "sha1".
  */
-static void *map_sha1_file_1(const char *path,
-                            const unsigned char *sha1,
-                            unsigned long *size)
+static void *map_sha1_file_1(struct repository *r, const char *path,
+                            const unsigned char *sha1, unsigned long *size)
 {
        void *map;
        int fd;
@@ -932,7 +939,7 @@ static void *map_sha1_file_1(const char *path,
        if (path)
                fd = git_open(path);
        else
-               fd = open_sha1_file(sha1, &path);
+               fd = open_sha1_file(r, sha1, &path);
        map = NULL;
        if (fd >= 0) {
                struct stat st;
@@ -951,9 +958,10 @@ static void *map_sha1_file_1(const char *path,
        return map;
 }
 
-void *map_sha1_file(const unsigned char *sha1, unsigned long *size)
+void *map_sha1_file(struct repository *r,
+                   const unsigned char *sha1, unsigned long *size)
 {
-       return map_sha1_file_1(NULL, sha1, size);
+       return map_sha1_file_1(r, NULL, sha1, size);
 }
 
 static int unpack_sha1_short_header(git_zstream *stream,
@@ -1142,15 +1150,15 @@ int parse_sha1_header(const char *hdr, unsigned long *sizep)
        return parse_sha1_header_extended(hdr, &oi, 0);
 }
 
-static int sha1_loose_object_info(const unsigned char *sha1,
-                                 struct object_info *oi,
-                                 int flags)
+static int sha1_loose_object_info(struct repository *r,
+                                 const unsigned char *sha1,
+                                 struct object_info *oi, int flags)
 {
        int status = 0;
        unsigned long mapsize;
        void *map;
        git_zstream stream;
-       char hdr[32];
+       char hdr[MAX_HEADER_LEN];
        struct strbuf hdrbuf = STRBUF_INIT;
        unsigned long size_scratch;
 
@@ -1168,14 +1176,14 @@ static int sha1_loose_object_info(const unsigned char *sha1,
        if (!oi->typep && !oi->type_name && !oi->sizep && !oi->contentp) {
                const char *path;
                struct stat st;
-               if (stat_sha1_file(sha1, &st, &path) < 0)
+               if (stat_sha1_file(r, sha1, &st, &path) < 0)
                        return -1;
                if (oi->disk_sizep)
                        *oi->disk_sizep = st.st_size;
                return 0;
        }
 
-       map = map_sha1_file(sha1, &mapsize);
+       map = map_sha1_file(r, sha1, &mapsize);
        if (!map)
                return -1;
 
@@ -1222,24 +1230,25 @@ static int sha1_loose_object_info(const unsigned char *sha1,
 
 int fetch_if_missing = 1;
 
-int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi, unsigned flags)
+int oid_object_info_extended(const struct object_id *oid, struct object_info *oi, unsigned flags)
 {
        static struct object_info blank_oi = OBJECT_INFO_INIT;
        struct pack_entry e;
        int rtype;
-       const unsigned char *real = (flags & OBJECT_INFO_LOOKUP_REPLACE) ?
-                                   lookup_replace_object(sha1) :
-                                   sha1;
+       const struct object_id *real = oid;
        int already_retried = 0;
 
-       if (is_null_sha1(real))
+       if (flags & OBJECT_INFO_LOOKUP_REPLACE)
+               real = lookup_replace_object(oid);
+
+       if (is_null_oid(real))
                return -1;
 
        if (!oi)
                oi = &blank_oi;
 
        if (!(flags & OBJECT_INFO_SKIP_CACHED)) {
-               struct cached_object *co = find_cached_object(real);
+               struct cached_object *co = find_cached_object(real->hash);
                if (co) {
                        if (oi->typep)
                                *(oi->typep) = co->type;
@@ -1259,17 +1268,20 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi,
        }
 
        while (1) {
-               if (find_pack_entry(real, &e))
+               if (find_pack_entry(the_repository, real->hash, &e))
                        break;
 
+               if (flags & OBJECT_INFO_IGNORE_LOOSE)
+                       return -1;
+
                /* Most likely it's a loose object. */
-               if (!sha1_loose_object_info(real, oi, flags))
+               if (!sha1_loose_object_info(the_repository, real->hash, oi, flags))
                        return 0;
 
                /* Not a loose object; someone else may have just packed it. */
                if (!(flags & OBJECT_INFO_QUICK)) {
-                       reprepare_packed_git();
-                       if (find_pack_entry(real, &e))
+                       reprepare_packed_git(the_repository);
+                       if (find_pack_entry(the_repository, real->hash, &e))
                                break;
                }
 
@@ -1280,7 +1292,7 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi,
                         * TODO Investigate haveing fetch_object() return
                         * TODO error/success and stopping the music here.
                         */
-                       fetch_object(repository_format_partial_clone, real);
+                       fetch_object(repository_format_partial_clone, real->hash);
                        already_retried = 1;
                        continue;
                }
@@ -1296,8 +1308,8 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi,
                return 0;
        rtype = packed_object_info(e.p, e.offset, oi);
        if (rtype < 0) {
-               mark_bad_packed_object(e.p, real);
-               return sha1_object_info_extended(real, oi, 0);
+               mark_bad_packed_object(e.p, real->hash);
+               return oid_object_info_extended(real, oi, 0);
        } else if (oi->whence == OI_PACKED) {
                oi->u.packed.offset = e.offset;
                oi->u.packed.pack = e.p;
@@ -1309,15 +1321,15 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi,
 }
 
 /* returns enum object_type or negative */
-int sha1_object_info(const unsigned char *sha1, unsigned long *sizep)
+int oid_object_info(const struct object_id *oid, unsigned long *sizep)
 {
        enum object_type type;
        struct object_info oi = OBJECT_INFO_INIT;
 
        oi.typep = &type;
        oi.sizep = sizep;
-       if (sha1_object_info_extended(sha1, &oi,
-                                     OBJECT_INFO_LOOKUP_REPLACE) < 0)
+       if (oid_object_info_extended(oid, &oi,
+                                    OBJECT_INFO_LOOKUP_REPLACE) < 0)
                return -1;
        return type;
 }
@@ -1325,13 +1337,16 @@ int sha1_object_info(const unsigned char *sha1, unsigned long *sizep)
 static void *read_object(const unsigned char *sha1, enum object_type *type,
                         unsigned long *size)
 {
+       struct object_id oid;
        struct object_info oi = OBJECT_INFO_INIT;
        void *content;
        oi.typep = type;
        oi.sizep = size;
        oi.contentp = &content;
 
-       if (sha1_object_info_extended(sha1, &oi, 0) < 0)
+       hashcpy(oid.hash, sha1);
+
+       if (oid_object_info_extended(&oid, &oi, 0) < 0)
                return NULL;
        return content;
 }
@@ -1359,65 +1374,65 @@ int pretend_object_file(void *buf, unsigned long len, enum object_type type,
  * deal with them should arrange to call read_object() and give error
  * messages themselves.
  */
-void *read_sha1_file_extended(const unsigned char *sha1,
-                             enum object_type *type,
-                             unsigned long *size,
-                             int lookup_replace)
+void *read_object_file_extended(const struct object_id *oid,
+                               enum object_type *type,
+                               unsigned long *size,
+                               int lookup_replace)
 {
        void *data;
        const struct packed_git *p;
        const char *path;
        struct stat st;
-       const unsigned char *repl = lookup_replace ? lookup_replace_object(sha1)
-                                                  : sha1;
+       const struct object_id *repl = lookup_replace ? lookup_replace_object(oid)
+                                                     : oid;
 
        errno = 0;
-       data = read_object(repl, type, size);
+       data = read_object(repl->hash, type, size);
        if (data)
                return data;
 
        if (errno && errno != ENOENT)
-               die_errno("failed to read object %s", sha1_to_hex(sha1));
+               die_errno("failed to read object %s", oid_to_hex(oid));
 
        /* die if we replaced an object with one that does not exist */
-       if (repl != sha1)
+       if (repl != oid)
                die("replacement %s not found for %s",
-                   sha1_to_hex(repl), sha1_to_hex(sha1));
+                   oid_to_hex(repl), oid_to_hex(oid));
 
-       if (!stat_sha1_file(repl, &st, &path))
+       if (!stat_sha1_file(the_repository, repl->hash, &st, &path))
                die("loose object %s (stored in %s) is corrupt",
-                   sha1_to_hex(repl), path);
+                   oid_to_hex(repl), path);
 
-       if ((p = has_packed_and_bad(repl)) != NULL)
+       if ((p = has_packed_and_bad(repl->hash)) != NULL)
                die("packed object %s (stored in %s) is corrupt",
-                   sha1_to_hex(repl), p->pack_name);
+                   oid_to_hex(repl), p->pack_name);
 
        return NULL;
 }
 
-void *read_object_with_reference(const unsigned char *sha1,
+void *read_object_with_reference(const struct object_id *oid,
                                 const char *required_type_name,
                                 unsigned long *size,
-                                unsigned char *actual_sha1_return)
+                                struct object_id *actual_oid_return)
 {
        enum object_type type, required_type;
        void *buffer;
        unsigned long isize;
-       unsigned char actual_sha1[20];
+       struct object_id actual_oid;
 
        required_type = type_from_string(required_type_name);
-       hashcpy(actual_sha1, sha1);
+       oidcpy(&actual_oid, oid);
        while (1) {
                int ref_length = -1;
                const char *ref_type = NULL;
 
-               buffer = read_sha1_file(actual_sha1, &type, &isize);
+               buffer = read_object_file(&actual_oid, &type, &isize);
                if (!buffer)
                        return NULL;
                if (type == required_type) {
                        *size = isize;
-                       if (actual_sha1_return)
-                               hashcpy(actual_sha1_return, actual_sha1);
+                       if (actual_oid_return)
+                               oidcpy(actual_oid_return, &actual_oid);
                        return buffer;
                }
                /* Handle references */
@@ -1431,15 +1446,15 @@ void *read_object_with_reference(const unsigned char *sha1,
                }
                ref_length = strlen(ref_type);
 
-               if (ref_length + 40 > isize ||
+               if (ref_length + GIT_SHA1_HEXSZ > isize ||
                    memcmp(buffer, ref_type, ref_length) ||
-                   get_sha1_hex((char *) buffer + ref_length, actual_sha1)) {
+                   get_oid_hex((char *) buffer + ref_length, &actual_oid)) {
                        free(buffer);
                        return NULL;
                }
                free(buffer);
                /* Now we have the ID of the referred-to object in
-                * actual_sha1.  Check again. */
+                * actual_oid.  Check again. */
        }
 }
 
@@ -1512,7 +1527,7 @@ static int write_buffer(int fd, const void *buf, size_t len)
 int hash_object_file(const void *buf, unsigned long len, const char *type,
                     struct object_id *oid)
 {
-       char hdr[32];
+       char hdr[MAX_HEADER_LEN];
        int hdrlen = sizeof(hdr);
        write_object_file_prepare(buf, len, type, oid, hdr, &hdrlen);
        return 0;
@@ -1585,7 +1600,7 @@ static int write_loose_object(const struct object_id *oid, char *hdr,
        static struct strbuf filename = STRBUF_INIT;
 
        strbuf_reset(&filename);
-       sha1_file_name(&filename, oid->hash);
+       sha1_file_name(the_repository, &filename, oid->hash);
 
        fd = create_tmpfile(&tmp_file, filename.buf);
        if (fd < 0) {
@@ -1654,7 +1669,7 @@ static int freshen_loose_object(const unsigned char *sha1)
 static int freshen_packed_object(const unsigned char *sha1)
 {
        struct pack_entry e;
-       if (!find_pack_entry(sha1, &e))
+       if (!find_pack_entry(the_repository, sha1, &e))
                return 0;
        if (e.p->freshened)
                return 1;
@@ -1667,7 +1682,7 @@ static int freshen_packed_object(const unsigned char *sha1)
 int write_object_file(const void *buf, unsigned long len, const char *type,
                      struct object_id *oid)
 {
-       char hdr[32];
+       char hdr[MAX_HEADER_LEN];
        int hdrlen = sizeof(hdr);
 
        /* Normally if we have it in the pack then we do not bother writing
@@ -1687,7 +1702,7 @@ int hash_object_file_literally(const void *buf, unsigned long len,
        int hdrlen, status = 0;
 
        /* type string, SP, %lu of the length plus NUL must fit this */
-       hdrlen = strlen(type) + 32;
+       hdrlen = strlen(type) + MAX_HEADER_LEN;
        header = xmalloc(hdrlen);
        write_object_file_prepare(buf, len, type, oid, header, &hdrlen);
 
@@ -1707,7 +1722,7 @@ int force_object_loose(const struct object_id *oid, time_t mtime)
        void *buf;
        unsigned long len;
        enum object_type type;
-       char hdr[32];
+       char hdr[MAX_HEADER_LEN];
        int hdrlen;
        int ret;
 
@@ -1725,10 +1740,12 @@ int force_object_loose(const struct object_id *oid, time_t mtime)
 
 int has_sha1_file_with_flags(const unsigned char *sha1, int flags)
 {
+       struct object_id oid;
        if (!startup_info->have_repository)
                return 0;
-       return sha1_object_info_extended(sha1, NULL,
-                                        flags | OBJECT_INFO_SKIP_CACHED) >= 0;
+       hashcpy(oid.hash, sha1);
+       return oid_object_info_extended(&oid, NULL,
+                                       flags | OBJECT_INFO_SKIP_CACHED) >= 0;
 }
 
 int has_object_file(const struct object_id *oid)
@@ -1894,7 +1911,7 @@ static int index_stream(struct object_id *oid, int fd, size_t size,
                        enum object_type type, const char *path,
                        unsigned flags)
 {
-       return index_bulk_checkin(oid->hash, fd, size, type, path, flags);
+       return index_bulk_checkin(oid, fd, size, type, path, flags);
 }
 
 int index_fd(struct object_id *oid, int fd, struct stat *st,
@@ -1968,13 +1985,13 @@ int read_pack_header(int fd, struct pack_header *header)
        return 0;
 }
 
-void assert_sha1_type(const unsigned char *sha1, enum object_type expect)
+void assert_oid_type(const struct object_id *oid, enum object_type expect)
 {
-       enum object_type type = sha1_object_info(sha1, NULL);
+       enum object_type type = oid_object_info(oid, NULL);
        if (type < 0)
-               die("%s is not a valid object", sha1_to_hex(sha1));
+               die("%s is not a valid object", oid_to_hex(oid));
        if (type != expect)
-               die("%s is not a valid '%s' object", sha1_to_hex(sha1),
+               die("%s is not a valid '%s' object", oid_to_hex(oid),
                    type_name(expect));
 }
 
@@ -2178,7 +2195,7 @@ static int check_stream_sha1(git_zstream *stream,
 }
 
 int read_loose_object(const char *path,
-                     const unsigned char *expected_sha1,
+                     const struct object_id *expected_oid,
                      enum object_type *type,
                      unsigned long *size,
                      void **contents)
@@ -2187,11 +2204,11 @@ int read_loose_object(const char *path,
        void *map = NULL;
        unsigned long mapsize;
        git_zstream stream;
-       char hdr[32];
+       char hdr[MAX_HEADER_LEN];
 
        *contents = NULL;
 
-       map = map_sha1_file_1(path, NULL, &mapsize);
+       map = map_sha1_file_1(the_repository, path, NULL, &mapsize);
        if (!map) {
                error_errno("unable to mmap %s", path);
                goto out;
@@ -2210,19 +2227,19 @@ int read_loose_object(const char *path,
        }
 
        if (*type == OBJ_BLOB) {
-               if (check_stream_sha1(&stream, hdr, *size, path, expected_sha1) < 0)
+               if (check_stream_sha1(&stream, hdr, *size, path, expected_oid->hash) < 0)
                        goto out;
        } else {
-               *contents = unpack_sha1_rest(&stream, hdr, *size, expected_sha1);
+               *contents = unpack_sha1_rest(&stream, hdr, *size, expected_oid->hash);
                if (!*contents) {
                        error("unable to unpack contents of %s", path);
                        git_inflate_end(&stream);
                        goto out;
                }
-               if (check_sha1_signature(expected_sha1, *contents,
+               if (check_object_signature(expected_oid, *contents,
                                         *size, type_name(*type))) {
                        error("sha1 mismatch for %s (expected %s)", path,
-                             sha1_to_hex(expected_sha1));
+                             oid_to_hex(expected_oid));
                        free(*contents);
                        goto out;
                }
index 735c1c0b8ec032b3aac8b6a8976dcdb09ba5e91d..5b93bf8da36939376b506f96624f568875397969 100644 (file)
@@ -10,6 +10,8 @@
 #include "dir.h"
 #include "sha1-array.h"
 #include "packfile.h"
+#include "object-store.h"
+#include "repository.h"
 
 static int get_oid_oneline(const char *, struct object_id *, struct commit_list *);
 
@@ -104,7 +106,7 @@ static void find_short_object_filename(struct disambiguate_state *ds)
                 */
                fakeent = alloc_alt_odb(get_object_directory());
        }
-       fakeent->next = alt_odb_list;
+       fakeent->next = the_repository->objects->alt_odb_list;
 
        for (alt = fakeent; alt && !ds->ambiguous; alt = alt->next) {
                int pos;
@@ -150,31 +152,14 @@ static int match_sha(unsigned len, const unsigned char *a, const unsigned char *
 static void unique_in_pack(struct packed_git *p,
                           struct disambiguate_state *ds)
 {
-       uint32_t num, last, i, first = 0;
+       uint32_t num, i, first = 0;
        const struct object_id *current = NULL;
 
        if (open_pack_index(p) || !p->num_objects)
                return;
 
        num = p->num_objects;
-       last = num;
-       while (first < last) {
-               uint32_t mid = first + (last - first) / 2;
-               const unsigned char *current;
-               int cmp;
-
-               current = nth_packed_object_sha1(p, mid);
-               cmp = hashcmp(ds->bin_pfx.hash, current);
-               if (!cmp) {
-                       first = mid;
-                       break;
-               }
-               if (cmp > 0) {
-                       first = mid+1;
-                       continue;
-               }
-               last = mid;
-       }
+       bsearch_pack(&ds->bin_pfx, p, &first);
 
        /*
         * At this point, "first" is the location of the lowest object
@@ -194,8 +179,8 @@ static void find_short_packed_object(struct disambiguate_state *ds)
 {
        struct packed_git *p;
 
-       prepare_packed_git();
-       for (p = packed_git; p && !ds->ambiguous; p = p->next)
+       for (p = get_packed_git(the_repository); p && !ds->ambiguous;
+            p = p->next)
                unique_in_pack(p, ds);
 }
 
@@ -238,7 +223,7 @@ static int finish_object_disambiguation(struct disambiguate_state *ds,
 
 static int disambiguate_commit_only(const struct object_id *oid, void *cb_data_unused)
 {
-       int kind = sha1_object_info(oid->hash, NULL);
+       int kind = oid_object_info(oid, NULL);
        return kind == OBJ_COMMIT;
 }
 
@@ -247,7 +232,7 @@ static int disambiguate_committish_only(const struct object_id *oid, void *cb_da
        struct object *obj;
        int kind;
 
-       kind = sha1_object_info(oid->hash, NULL);
+       kind = oid_object_info(oid, NULL);
        if (kind == OBJ_COMMIT)
                return 1;
        if (kind != OBJ_TAG)
@@ -262,7 +247,7 @@ static int disambiguate_committish_only(const struct object_id *oid, void *cb_da
 
 static int disambiguate_tree_only(const struct object_id *oid, void *cb_data_unused)
 {
-       int kind = sha1_object_info(oid->hash, NULL);
+       int kind = oid_object_info(oid, NULL);
        return kind == OBJ_TREE;
 }
 
@@ -271,7 +256,7 @@ static int disambiguate_treeish_only(const struct object_id *oid, void *cb_data_
        struct object *obj;
        int kind;
 
-       kind = sha1_object_info(oid->hash, NULL);
+       kind = oid_object_info(oid, NULL);
        if (kind == OBJ_TREE || kind == OBJ_COMMIT)
                return 1;
        if (kind != OBJ_TAG)
@@ -286,7 +271,7 @@ static int disambiguate_treeish_only(const struct object_id *oid, void *cb_data_
 
 static int disambiguate_blob_only(const struct object_id *oid, void *cb_data_unused)
 {
-       int kind = sha1_object_info(oid->hash, NULL);
+       int kind = oid_object_info(oid, NULL);
        return kind == OBJ_BLOB;
 }
 
@@ -351,7 +336,7 @@ static int init_object_disambiguation(const char *name, int len,
 
        ds->len = len;
        ds->hex_pfx[len] = '\0';
-       prepare_alt_odb();
+       prepare_alt_odb(the_repository);
        return 0;
 }
 
@@ -365,7 +350,7 @@ static int show_ambiguous_object(const struct object_id *oid, void *data)
        if (ds->fn && !ds->fn(oid, ds->cb_data))
                return 0;
 
-       type = sha1_object_info(oid->hash, NULL);
+       type = oid_object_info(oid, NULL);
        if (type == OBJ_COMMIT) {
                struct commit *commit = lookup_commit(oid);
                if (commit) {
@@ -380,7 +365,7 @@ static int show_ambiguous_object(const struct object_id *oid, void *data)
        }
 
        advise("  %s %s%s",
-              find_unique_abbrev(oid->hash, DEFAULT_ABBREV),
+              find_unique_abbrev(oid, DEFAULT_ABBREV),
               type_name(type) ? type_name(type) : "unknown type",
               desc.buf);
 
@@ -480,7 +465,7 @@ struct min_abbrev_data {
        unsigned int init_len;
        unsigned int cur_len;
        char *hex;
-       const unsigned char *hash;
+       const struct object_id *oid;
 };
 
 static inline char get_hex_char_from_oid(const struct object_id *oid,
@@ -512,32 +497,16 @@ static void find_abbrev_len_for_pack(struct packed_git *p,
                                     struct min_abbrev_data *mad)
 {
        int match = 0;
-       uint32_t num, last, first = 0;
+       uint32_t num, first = 0;
        struct object_id oid;
+       const struct object_id *mad_oid;
 
        if (open_pack_index(p) || !p->num_objects)
                return;
 
        num = p->num_objects;
-       last = num;
-       while (first < last) {
-               uint32_t mid = first + (last - first) / 2;
-               const unsigned char *current;
-               int cmp;
-
-               current = nth_packed_object_sha1(p, mid);
-               cmp = hashcmp(mad->hash, current);
-               if (!cmp) {
-                       match = 1;
-                       first = mid;
-                       break;
-               }
-               if (cmp > 0) {
-                       first = mid + 1;
-                       continue;
-               }
-               last = mid;
-       }
+       mad_oid = mad->oid;
+       match = bsearch_pack(mad_oid, p, &first);
 
        /*
         * first is now the position in the packfile where we would insert
@@ -564,12 +533,11 @@ static void find_abbrev_len_packed(struct min_abbrev_data *mad)
 {
        struct packed_git *p;
 
-       prepare_packed_git();
-       for (p = packed_git; p; p = p->next)
+       for (p = get_packed_git(the_repository); p; p = p->next)
                find_abbrev_len_for_pack(p, mad);
 }
 
-int find_unique_abbrev_r(char *hex, const unsigned char *sha1, int len)
+int find_unique_abbrev_r(char *hex, const struct object_id *oid, int len)
 {
        struct disambiguate_state ds;
        struct min_abbrev_data mad;
@@ -596,14 +564,14 @@ int find_unique_abbrev_r(char *hex, const unsigned char *sha1, int len)
                        len = FALLBACK_DEFAULT_ABBREV;
        }
 
-       sha1_to_hex_r(hex, sha1);
+       oid_to_hex_r(hex, oid);
        if (len == GIT_SHA1_HEXSZ || !len)
                return GIT_SHA1_HEXSZ;
 
        mad.init_len = len;
        mad.cur_len = len;
        mad.hex = hex;
-       mad.hash = sha1;
+       mad.oid = oid;
 
        find_abbrev_len_packed(&mad);
 
@@ -621,13 +589,13 @@ int find_unique_abbrev_r(char *hex, const unsigned char *sha1, int len)
        return mad.cur_len;
 }
 
-const char *find_unique_abbrev(const unsigned char *sha1, int len)
+const char *find_unique_abbrev(const struct object_id *oid, int len)
 {
        static int bufno;
        static char hexbuffer[4][GIT_MAX_HEXSZ + 1];
        char *hex = hexbuffer[bufno];
        bufno = (bufno + 1) % ARRAY_SIZE(hexbuffer);
-       find_unique_abbrev_r(hex, sha1, len);
+       find_unique_abbrev_r(hex, oid, len);
        return hex;
 }
 
@@ -1529,8 +1497,7 @@ static void diagnose_invalid_oid_path(const char *prefix,
        if (is_missing_file_error(errno)) {
                char *fullname = xstrfmt("%s%s", prefix, filename);
 
-               if (!get_tree_entry(tree_oid->hash, fullname,
-                                   oid.hash, &mode)) {
+               if (!get_tree_entry(tree_oid, fullname, &oid, &mode)) {
                        die("Path '%s' exists, but not '%s'.\n"
                            "Did you mean '%.*s:%s' aka '%.*s:./%s'?",
                            fullname,
@@ -1722,8 +1689,8 @@ static int get_oid_with_context_1(const char *name,
                                        filename, oid->hash, &oc->symlink_path,
                                        &oc->mode);
                        } else {
-                               ret = get_tree_entry(tree_oid.hash, filename,
-                                                    oid->hash, &oc->mode);
+                               ret = get_tree_entry(&tree_oid, filename, oid,
+                                                    &oc->mode);
                                if (ret && only_to_die) {
                                        diagnose_invalid_oid_path(prefix,
                                                                   filename,
index 0759590b3e56de0fab6ff34f25206fb4cdeca4c5..43a840c67b30754c10f9d6a260882a863169c52c 100644 (file)
--- a/strbuf.c
+++ b/strbuf.c
@@ -881,12 +881,12 @@ void strbuf_addftime(struct strbuf *sb, const char *fmt, const struct tm *tm,
        strbuf_setlen(sb, sb->len + len);
 }
 
-void strbuf_add_unique_abbrev(struct strbuf *sb, const unsigned char *sha1,
+void strbuf_add_unique_abbrev(struct strbuf *sb, const struct object_id *oid,
                              int abbrev_len)
 {
        int r;
        strbuf_grow(sb, GIT_SHA1_HEXSZ + 1);
-       r = find_unique_abbrev_r(sb->buf + sb->len, sha1, abbrev_len);
+       r = find_unique_abbrev_r(sb->buf + sb->len, oid, abbrev_len);
        strbuf_setlen(sb, sb->len + r);
 }
 
index e6cae5f4398c8eb4c4a53c7db226a920e32bfde9..4efa80c1de60b5886ea47655fc6570ef6c5f049b 100644 (file)
--- a/strbuf.h
+++ b/strbuf.h
@@ -70,6 +70,12 @@ struct strbuf {
 extern char strbuf_slopbuf[];
 #define STRBUF_INIT  { .alloc = 0, .len = 0, .buf = strbuf_slopbuf }
 
+/*
+ * Predeclare this here, since cache.h includes this file before it defines the
+ * struct.
+ */
+struct object_id;
+
 /**
  * Life Cycle Functions
  * --------------------
@@ -542,7 +548,7 @@ extern void strbuf_list_free(struct strbuf **);
  * the strbuf `sb`.
  */
 extern void strbuf_add_unique_abbrev(struct strbuf *sb,
-                                    const unsigned char *sha1,
+                                    const struct object_id *oid,
                                     int abbrev_len);
 
 /**
index 5892b50bd89c3c66bdb541ca0100f0671834a542..7d55ba64c7551de0f3be1dfcf56cd3344ebd8f59 100644 (file)
@@ -3,6 +3,8 @@
  */
 #include "cache.h"
 #include "streaming.h"
+#include "repository.h"
+#include "object-store.h"
 #include "packfile.h"
 
 enum input_source {
@@ -14,7 +16,7 @@ enum input_source {
 
 typedef int (*open_istream_fn)(struct git_istream *,
                               struct object_info *,
-                              const unsigned char *,
+                              const struct object_id *,
                               enum object_type *);
 typedef int (*close_istream_fn)(struct git_istream *);
 typedef ssize_t (*read_istream_fn)(struct git_istream *, char *, size_t);
@@ -27,7 +29,7 @@ struct stream_vtbl {
 #define open_method_decl(name) \
        int open_istream_ ##name \
        (struct git_istream *st, struct object_info *oi, \
-        const unsigned char *sha1, \
+        const struct object_id *oid, \
         enum object_type *type)
 
 #define close_method_decl(name) \
@@ -105,7 +107,7 @@ ssize_t read_istream(struct git_istream *st, void *buf, size_t sz)
        return st->vtbl->read(st, buf, sz);
 }
 
-static enum input_source istream_source(const unsigned char *sha1,
+static enum input_source istream_source(const struct object_id *oid,
                                        enum object_type *type,
                                        struct object_info *oi)
 {
@@ -114,7 +116,7 @@ static enum input_source istream_source(const unsigned char *sha1,
 
        oi->typep = type;
        oi->sizep = &size;
-       status = sha1_object_info_extended(sha1, oi, 0);
+       status = oid_object_info_extended(oid, oi, 0);
        if (status < 0)
                return stream_error;
 
@@ -130,14 +132,14 @@ static enum input_source istream_source(const unsigned char *sha1,
        }
 }
 
-struct git_istream *open_istream(const unsigned char *sha1,
+struct git_istream *open_istream(const struct object_id *oid,
                                 enum object_type *type,
                                 unsigned long *size,
                                 struct stream_filter *filter)
 {
        struct git_istream *st;
        struct object_info oi = OBJECT_INFO_INIT;
-       const unsigned char *real = lookup_replace_object(sha1);
+       const struct object_id *real = lookup_replace_object(oid);
        enum input_source src = istream_source(real, type, &oi);
 
        if (src < 0)
@@ -335,7 +337,8 @@ static struct stream_vtbl loose_vtbl = {
 
 static open_method_decl(loose)
 {
-       st->u.loose.mapped = map_sha1_file(sha1, &st->u.loose.mapsize);
+       st->u.loose.mapped = map_sha1_file(the_repository,
+                                          oid->hash, &st->u.loose.mapsize);
        if (!st->u.loose.mapped)
                return -1;
        if ((unpack_sha1_header(&st->z,
@@ -486,7 +489,7 @@ static struct stream_vtbl incore_vtbl = {
 
 static open_method_decl(incore)
 {
-       st->u.incore.buf = read_sha1_file_extended(sha1, type, &st->size, 0);
+       st->u.incore.buf = read_object_file_extended(oid, type, &st->size, 0);
        st->u.incore.read_ptr = 0;
        st->vtbl = &incore_vtbl;
 
@@ -507,7 +510,7 @@ int stream_blob_to_fd(int fd, const struct object_id *oid, struct stream_filter
        ssize_t kept = 0;
        int result = -1;
 
-       st = open_istream(oid->hash, &type, &sz, filter);
+       st = open_istream(oid, &type, &sz, filter);
        if (!st) {
                if (filter)
                        free_stream_filter(filter);
index 73c1d156b352898c9b5661a3e480f579b80c5a00..32f46267710b4e88cd0fc90e1a5a6f6388361c61 100644 (file)
@@ -8,7 +8,7 @@
 /* opaque */
 struct git_istream;
 
-extern struct git_istream *open_istream(const unsigned char *, enum object_type *, unsigned long *, struct stream_filter *);
+extern struct git_istream *open_istream(const struct object_id *, enum object_type *, unsigned long *, struct stream_filter *);
 extern int close_istream(struct git_istream *);
 extern ssize_t read_istream(struct git_istream *, void *, size_t);
 
index 602ba8ca8b8455df9b34e2990397c838d542569f..3f2075764feb53fc8c981aab39d16c6b191cb6d8 100644 (file)
@@ -520,7 +520,7 @@ static const struct submodule *config_from(struct submodule_cache *cache,
        if (submodule)
                goto out;
 
-       config = read_sha1_file(oid.hash, &type, &config_size);
+       config = read_object_file(&oid, &type, &config_size);
        if (!config || type != OBJ_BLOB)
                goto out;
 
index 12a2503fda7df9060d858bd572ea106e3141b083..9a50168b2375d9cac306a22c8be4559dde114d95 100644 (file)
@@ -21,6 +21,7 @@
 #include "remote.h"
 #include "worktree.h"
 #include "parse-options.h"
+#include "object-store.h"
 
 static int config_update_recurse_submodules = RECURSE_SUBMODULES_OFF;
 static struct string_list changed_submodule_names = STRING_LIST_INIT_DUP;
@@ -540,9 +541,9 @@ static void show_submodule_header(struct diff_options *o, const char *path,
 
 output_header:
        strbuf_addf(&sb, "Submodule %s ", path);
-       strbuf_add_unique_abbrev(&sb, one->hash, DEFAULT_ABBREV);
+       strbuf_add_unique_abbrev(&sb, one, DEFAULT_ABBREV);
        strbuf_addstr(&sb, (fast_backward || fast_forward) ? ".." : "...");
-       strbuf_add_unique_abbrev(&sb, two->hash, DEFAULT_ABBREV);
+       strbuf_add_unique_abbrev(&sb, two, DEFAULT_ABBREV);
        if (message)
                strbuf_addf(&sb, " %s\n", message);
        else
@@ -817,7 +818,7 @@ static int check_has_commit(const struct object_id *oid, void *data)
 {
        struct has_commit_data *cb = data;
 
-       enum object_type type = sha1_object_info(oid->hash, NULL);
+       enum object_type type = oid_object_info(oid, NULL);
 
        switch (type) {
        case OBJ_COMMIT:
index e760256406fa9c2fe0f9b2cde0ffb97ff11c6cab..1790ceab510d53182225d3a28bbd4b4ef51abcdd 100644 (file)
@@ -5,28 +5,29 @@
  *
  * The mtime can be changed to an absolute value:
  *
- *     test-chmtime =<seconds> file...
+ *     test-tool chmtime =<seconds> file...
  *
  * Relative to the current time as returned by time(3):
  *
- *     test-chmtime =+<seconds> (or =-<seconds>) file...
+ *     test-tool chmtime =+<seconds> (or =-<seconds>) file...
  *
  * Or relative to the current mtime of the file:
  *
- *     test-chmtime <seconds> file...
- *     test-chmtime +<seconds> (or -<seconds>) file...
+ *     test-tool chmtime <seconds> file...
+ *     test-tool chmtime +<seconds> (or -<seconds>) file...
  *
  * Examples:
  *
  * To just print the mtime use --verbose and set the file mtime offset to 0:
  *
- *     test-chmtime -v +0 file
+ *     test-tool chmtime -v +0 file
  *
  * To set the mtime to current time:
  *
- *     test-chmtime =+0 file
+ *     test-tool chmtime =+0 file
  *
  */
+#include "test-tool.h"
 #include "git-compat-util.h"
 #include <utime.h>
 
@@ -56,7 +57,7 @@ static int timespec_arg(const char *arg, long int *set_time, int *set_eq)
        return 1;
 }
 
-int cmd_main(int argc, const char **argv)
+int cmd__chmtime(int argc, const char **argv)
 {
        static int verbose;
 
index 1a7b8bd3d650fe1111c77115d2c68644b6ac9edb..214003d5b2f9bbe978d5aa4d9c9ab3f9b8a990da 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "config.h"
 #include "string-list.h"
@@ -32,7 +33,7 @@
  * Examples:
  *
  * To print the value with highest priority for key "foo.bAr Baz.rock":
- *     test-config get_value "foo.bAr Baz.rock"
+ *     test-tool config get_value "foo.bAr Baz.rock"
  *
  */
 
@@ -77,7 +78,7 @@ static int early_config_cb(const char *var, const char *value, void *vdata)
        return 0;
 }
 
-int cmd_main(int argc, const char **argv)
+int cmd__config(int argc, const char **argv)
 {
        int i, val;
        const char *v;
index bb72c47df570d9c07ae4567fd6d31ea49fe49656..92c4c2313e78a305dd0da1e7a853e58e325d2f84 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 
 static int rc;
@@ -28,7 +29,7 @@ static int is_in(const char *s, int ch)
 #define LOWER "abcdefghijklmnopqrstuvwxyz"
 #define UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 
-int cmd_main(int argc, const char **argv)
+int cmd__ctype(int argc, const char **argv)
 {
        TEST_CLASS(isdigit, DIGIT);
        TEST_CLASS(isspace, " \n\r\t");
index ac8368797073adfdf203f60d93df55a988443dbd..a0837371aba17956331ddcdb04847c6c9edeefd2 100644 (file)
@@ -1,13 +1,14 @@
+#include "test-tool.h"
 #include "cache.h"
 
 static const char *usage_msg = "\n"
-"  test-date relative [time_t]...\n"
-"  test-date show:<format> [time_t]...\n"
-"  test-date parse [date]...\n"
-"  test-date approxidate [date]...\n"
-"  test-date timestamp [date]...\n"
-"  test-date is64bit\n"
-"  test-date time_t-is64bit\n";
+"  test-tool date relative [time_t]...\n"
+"  test-tool date show:<format> [time_t]...\n"
+"  test-tool date parse [date]...\n"
+"  test-tool date approxidate [date]...\n"
+"  test-tool date timestamp [date]...\n"
+"  test-tool date is64bit\n"
+"  test-tool date time_t-is64bit\n";
 
 static void show_relative_dates(const char **argv, struct timeval *now)
 {
@@ -81,7 +82,7 @@ static void parse_approx_timestamp(const char **argv, struct timeval *now)
        }
 }
 
-int cmd_main(int argc, const char **argv)
+int cmd__date(int argc, const char **argv)
 {
        struct timeval now;
        const char *x;
index 591730adc4f3940940fdb4691da0afb81648e353..34c7259248760ff8bdea495ac5effd5de2b04ae3 100644 (file)
@@ -8,14 +8,15 @@
  * published by the Free Software Foundation.
  */
 
+#include "test-tool.h"
 #include "git-compat-util.h"
 #include "delta.h"
 #include "cache.h"
 
 static const char usage_str[] =
-       "test-delta (-d|-p) <from_file> <data_file> <out_file>";
+       "test-tool delta (-d|-p) <from_file> <data_file> <out_file>";
 
-int cmd_main(int argc, const char **argv)
+int cmd__delta(int argc, const char **argv)
 {
        int fd;
        struct stat st;
index bd1a857d5224a1a8d3c4a0d8e0ce54476d70372e..838760898b6f4ccfc0d7a3c4bd2c8653020a93ec 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "git-compat-util.h"
 
 #if defined(GIT_WINDOWS_NATIVE)
@@ -157,7 +158,7 @@ static int cmd_dropcaches(void)
 
 #endif
 
-int cmd_main(int argc, const char **argv)
+int cmd__drop_caches(int argc, const char **argv)
 {
        cmd_sync();
        return cmd_dropcaches();
index ebf3aab22d6c197b99b0203dbe9881ccf417be86..98a4891f1dc936a486075703de319affdacb1c78 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "tree.h"
 #include "cache-tree.h"
@@ -54,7 +55,7 @@ static int dump_cache_tree(struct cache_tree *it,
        return errs;
 }
 
-int cmd_main(int ac, const char **av)
+int cmd__dump_cache_tree(int ac, const char **av)
 {
        struct index_state istate;
        struct cache_tree *another = cache_tree();
index e44430b699db732252afa6fcb06686ec89b5811d..4e2fdb5e30d1ae30b1f75b7e3ca636afa4c0e097 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "split-index.h"
 #include "ewah/ewok.h"
@@ -7,7 +8,7 @@ static void show_bit(size_t pos, void *data)
        printf(" %d", (int)pos);
 }
 
-int cmd_main(int ac, const char **av)
+int cmd__dump_split_index(int ac, const char **av)
 {
        struct split_index *si;
        int i;
index 90dc97a9d0444bc2dd8beaa1bfdd970f4280efb7..081115bf8eb7cb2e27c39f632af0e40001b5b6e9 100644 (file)
@@ -1,8 +1,9 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "object.h"
 #include "decorate.h"
 
-int cmd_main(int argc, const char **argv)
+int cmd__example_decorate(int argc, const char **argv)
 {
        struct decoration n;
        struct object_id one_oid = { {1} };
index 8d11d22d98649900b6d558cc174e2af1dbff9948..99b8dc1e2d9cdc3a0e0f464fdeee0f94733d00d1 100644 (file)
@@ -4,9 +4,10 @@
  * Copyright (C) 2007 by Nicolas Pitre, licensed under the GPL version 2.
  */
 
+#include "test-tool.h"
 #include "git-compat-util.h"
 
-int cmd_main(int argc, const char **argv)
+int cmd__genrandom(int argc, const char **argv)
 {
        unsigned long count, next = 0;
        unsigned char *c;
index 9ae9281c071254019ccca3486b3a6762d9c0085f..23d2b172fe708f711a15613e906637cd948324ef 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "git-compat-util.h"
 #include "hashmap.h"
 #include "strbuf.h"
@@ -77,7 +78,7 @@ static unsigned int hash(unsigned int method, unsigned int i, const char *key)
 
 /*
  * Test performance of hashmap.[ch]
- * Usage: time echo "perfhashmap method rounds" | test-hashmap
+ * Usage: time echo "perfhashmap method rounds" | test-tool hashmap
  */
 static void perf_hashmap(unsigned int method, unsigned int rounds)
 {
@@ -144,7 +145,7 @@ static void perf_hashmap(unsigned int method, unsigned int rounds)
  *
  * perfhashmap method rounds -> test hashmap.[ch] performance
  */
-int cmd_main(int argc, const char **argv)
+int cmd__hashmap(int argc, const char **argv)
 {
        struct strbuf line = STRBUF_INIT;
        struct hashmap map;
index f569f6b7eff87227f82dbe6390fd31fb970a5fca..fcd10968cc10bdab8db146b8ba65080431e5ed24 100644 (file)
@@ -1,6 +1,7 @@
+#include "test-tool.h"
 #include "cache.h"
 
-int cmd_main(int argc, const char **argv)
+int cmd__index_version(int argc, const char **argv)
 {
        struct cache_header hdr;
        int version;
index 297fb01d61eded5d83d02175199efcd217376738..b99a37080d935fa27df4e372e0e8cddd9fd08b3c 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "parse-options.h"
 
@@ -184,14 +185,14 @@ static void analyze_run(void)
        }
 }
 
-int cmd_main(int argc, const char **argv)
+int cmd__lazy_init_name_hash(int argc, const char **argv)
 {
        const char *usage[] = {
-               "test-lazy-init-name-hash -d (-s | -m)",
-               "test-lazy-init-name-hash -p [-c c]",
-               "test-lazy-init-name-hash -a a [--step s] [-c c]",
-               "test-lazy-init-name-hash (-s | -m) [-c c]",
-               "test-lazy-init-name-hash -s -m [-c c]",
+               "test-tool lazy-init-name-hash -d (-s | -m)",
+               "test-tool lazy-init-name-hash -p [-c c]",
+               "test-tool lazy-init-name-hash -a a [--step s] [-c c]",
+               "test-tool lazy-init-name-hash (-s | -m) [-c c]",
+               "test-tool lazy-init-name-hash -s -m [-c c]",
                NULL
        };
        struct option options[] = {
index 356d8edef1d25524abaae0f0fcb3bf072d229c30..96857f26ac8540cf22e74aed72bbd30bc8147f00 100644 (file)
@@ -1,7 +1,8 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "tree.h"
 
-int cmd_main(int ac, const char **av)
+int cmd__match_trees(int ac, const char **av)
 {
        struct object_id hash1, hash2, shifted;
        struct tree *one, *two;
index 335cf6b6264cdaf9563736fbcfa40e7a3006a432..c5cffaa4b73ff52b2f166231ceb4a77b24ee8cef 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "mergesort.h"
 
@@ -22,7 +23,7 @@ static int compare_strings(const void *a, const void *b)
        return strcmp(x->text, y->text);
 }
 
-int cmd_main(int argc, const char **argv)
+int cmd__mergesort(int argc, const char **argv)
 {
        struct line *line, *p = NULL, *lines = NULL;
        struct strbuf sb = STRBUF_INIT;
index 89d9b2f7bee05ff5c9fde31ba6798651ccee2947..229068894029338c52f5d0b9828c442658be67e5 100644 (file)
@@ -1,9 +1,10 @@
 /*
  * test-mktemp.c: code to exercise the creation of temporary files
  */
+#include "test-tool.h"
 #include "git-compat-util.h"
 
-int cmd_main(int argc, const char **argv)
+int cmd__mktemp(int argc, const char **argv)
 {
        if (argc != 2)
                usage("Expected 1 parameter defining the temporary file template");
index 06c09c6b886f843b2d3c6fdb8e00730afc7fe40b..8cb0d53840f3dc60d583fa1b72f95572d2148d11 100644 (file)
@@ -1,7 +1,8 @@
+#include "test-tool.h"
 #include "git-compat-util.h"
 #include "thread-utils.h"
 
-int cmd_main(int argc, const char **argv)
+int cmd__online_cpus(int argc, const char **argv)
 {
        printf("%d\n", online_cpus());
        return 0;
index 2b3c5092a199835ea2e84339b473a9e29778178d..e115d44ac26e1d4fed48a5fd82632e5a93a487e6 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "string-list.h"
 
@@ -170,7 +171,7 @@ static struct test_data dirname_data[] = {
        { NULL,              NULL     }
 };
 
-int cmd_main(int argc, const char **argv)
+int cmd__path_utils(int argc, const char **argv)
 {
        if (argc == 3 && !strcmp(argv[1], "normalize_path_copy")) {
                char *buf = xmallocz(strlen(argv[2]));
index ae58fff35972a09c08a47d2bc0abb67c96ba20eb..9807b649b14c0002bee6d10b200c27bb89a54812 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "prio-queue.h"
 
@@ -16,7 +17,7 @@ static void show(int *v)
        free(v);
 }
 
-int cmd_main(int argc, const char **argv)
+int cmd__prio_queue(int argc, const char **argv)
 {
        struct prio_queue pq = { intcmp };
 
index 48255eef31a1e83d9a2bbb01670ba089a11c91f8..d674c88ba092d60366a14eaeccc9f4bc6f32660c 100644 (file)
@@ -1,6 +1,7 @@
+#include "test-tool.h"
 #include "cache.h"
 
-int cmd_main(int argc, const char **argv)
+int cmd__read_cache(int argc, const char **argv)
 {
        int i, cnt = 1;
        if (argc == 2)
index 7120634b04733bb8abe1f0622f0e1e9c8280b643..7c4f43746e8792a368814664a70c51ca55ab43e1 100644 (file)
@@ -1,6 +1,8 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "refs.h"
 #include "worktree.h"
+#include "object-store.h"
 
 static const char *notnull(const char *arg, const char *name)
 {
@@ -274,7 +276,7 @@ static struct command commands[] = {
        { NULL, NULL }
 };
 
-int cmd_main(int argc, const char **argv)
+int cmd__ref_store(int argc, const char **argv)
 {
        struct ref_store *refs;
        const char *func;
index b5ea8a97c54e1737d91dec894c1cc02e1baf64e5..10284cc56fa9f69703aa69f242edef113d6a40de 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "git-compat-util.h"
 #include "gettext.h"
 
@@ -36,7 +37,7 @@ static int test_regex_bug(void)
        return 0;
 }
 
-int cmd_main(int argc, const char **argv)
+int cmd__regex(int argc, const char **argv)
 {
        const char *pat;
        const char *str;
@@ -47,8 +48,8 @@ int cmd_main(int argc, const char **argv)
        if (argc == 2 && !strcmp(argv[1], "--bug"))
                return test_regex_bug();
        else if (argc < 3)
-               usage("test-regex --bug\n"
-                     "test-regex <pattern> <string> [<options>]");
+               usage("test-tool regex --bug\n"
+                     "test-tool regex <pattern> <string> [<options>]");
 
        argv++;
        pat = *argv++;
index b8e6fe1d007449d30dd30ccd4319b26f151bbf23..4f8bc758213c47906d3dc1a4d4e02df2737c508d 100644 (file)
@@ -8,6 +8,7 @@
  * published by the Free Software Foundation.
  */
 
+#include "test-tool.h"
 #include "cache.h"
 #include "commit.h"
 #include "diff.h"
@@ -45,7 +46,7 @@ static int run_revision_walk(void)
        return got_revision;
 }
 
-int cmd_main(int argc, const char **argv)
+int cmd__revision_walking(int argc, const char **argv)
 {
        if (argc < 2)
                return 1;
index 153342e44dd11ae357cc299a9214f4c365614a5e..2cc93bb69c522d99491cd8a9e02e211b2c3df807 100644 (file)
@@ -8,6 +8,7 @@
  * published by the Free Software Foundation.
  */
 
+#include "test-tool.h"
 #include "git-compat-util.h"
 #include "run-command.h"
 #include "argv-array.h"
@@ -49,7 +50,7 @@ static int task_finished(int result,
        return 1;
 }
 
-int cmd_main(int argc, const char **argv)
+int cmd__run_command(int argc, const char **argv)
 {
        struct child_process proc = CHILD_PROCESS_INIT;
        int jobs;
index d2a63bea4346fb76d38ba43508ee6e60599e41a9..d26d3e7c8b1a407e2cf40ce20750495f500d5170 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "lockfile.h"
 #include "tree.h"
@@ -5,7 +6,7 @@
 
 static struct lock_file index_lock;
 
-int cmd_main(int ac, const char **av)
+int cmd__scrap_cache_tree(int ac, const char **av)
 {
        setup_git_directory();
        hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR);
index edfd52d82aeca0bb9ba2c5b2ce18bc39d27e5a34..ad5e69f9d3b0e03442f0d23b3b559bbfc163ee7b 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "sha1-array.h"
 
@@ -7,7 +8,7 @@ static int print_oid(const struct object_id *oid, void *data)
        return 0;
 }
 
-int cmd_main(int argc, const char **argv)
+int cmd__sha1_array(int argc, const char **argv)
 {
        struct oid_array array = OID_ARRAY_INIT;
        struct strbuf line = STRBUF_INIT;
index a1c13f54eca0db7d11a5df134d565171d70b8cce..1ba0675c75f0d2dab281d054b577272cd45c39f9 100644 (file)
@@ -1,6 +1,7 @@
+#include "test-tool.h"
 #include "cache.h"
 
-int cmd_main(int ac, const char **av)
+int cmd__sha1(int ac, const char **av)
 {
        git_SHA_CTX ctx;
        unsigned char sha1[20];
index 750b95a0a1c39b4d761b7f2f861f6df4c85ecb65..84594885c703887c3b09aceb51583b9895ac3b45 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 dd if=/dev/zero bs=1048576 count=100 2>/dev/null |
-/usr/bin/time t/helper/test-sha1 >/dev/null
+/usr/bin/time t/helper/test-tool sha1 >/dev/null
 
 while read expect cnt pfx
 do
@@ -11,7 +11,7 @@ do
                        test -z "$pfx" || echo "$pfx"
                        dd if=/dev/zero bs=1048576 count=$cnt 2>/dev/null |
                        perl -pe 'y/\000/g/'
-               } | ./t/helper/test-sha1 $cnt
+               } | ./t/helper/test-tool sha1 $cnt
        )
        if test "$expect" = "$actual"
        then
index b71edbd4429184b59b4bd1355d5cfb53970a1876..77ac5bc33f8eb635f78d8ba590c23bbbe4f29636 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "sigchain.h"
 
@@ -13,7 +14,7 @@ X(two)
 X(three)
 #undef X
 
-int cmd_main(int argc, const char **argv) {
+int cmd__sigchain(int argc, const char **argv) {
        sigchain_push(SIGTERM, one);
        sigchain_push(SIGTERM, two);
        sigchain_push(SIGTERM, three);
index e159c9a127f6854541ab497c8fd4b6efb9d4ea39..44e4a6d143e24cbd05b5d94404a5f5d4e732c880 100644 (file)
@@ -1,6 +1,7 @@
+#include "test-tool.h"
 #include "cache.h"
 
-int cmd_main(int argc, const char **argv)
+int cmd__strcmp_offset(int argc, const char **argv)
 {
        int result;
        size_t offset;
index 829ec3d7d2f58b9538bb3bbab47213eddb9e62ec..2123dda85bf10033dcbf0d801028b3705e73a507 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "string-list.h"
 
@@ -41,7 +42,7 @@ static int prefix_cb(struct string_list_item *item, void *cb_data)
        return starts_with(item->string, prefix);
 }
 
-int cmd_main(int argc, const char **argv)
+int cmd__string_list(int argc, const char **argv)
 {
        if (argc == 5 && !strcmp(argv[1], "split")) {
                struct string_list list = STRING_LIST_INIT_DUP;
index f23db3b19a9911b554ca8eaf567cd0370d42af6e..5c6e4b010d61d2076f08e7077aa5ccbe6db665fc 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "config.h"
 #include "submodule-config.h"
@@ -10,7 +11,7 @@ static void die_usage(int argc, const char **argv, const char *msg)
        exit(1);
 }
 
-int cmd_main(int argc, const char **argv)
+int cmd__submodule_config(int argc, const char **argv)
 {
        const char **arg = argv;
        int my_argc = argc;
index 30c5765bfc3590421c21bc2350eed882752de3a0..92b69de635296d32d38d1f7d7589d5f8b6fbc296 100644 (file)
@@ -1,7 +1,8 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "run-command.h"
 
-int cmd_main(int argc, const char **argv)
+int cmd__subprocess(int argc, const char **argv)
 {
        struct child_process cp = CHILD_PROCESS_INIT;
        int nogit = 0;
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
new file mode 100644 (file)
index 0000000..87066ce
--- /dev/null
@@ -0,0 +1,62 @@
+#include "git-compat-util.h"
+#include "test-tool.h"
+
+struct test_cmd {
+       const char *name;
+       int (*fn)(int argc, const char **argv);
+};
+
+static struct test_cmd cmds[] = {
+       { "chmtime", cmd__chmtime },
+       { "config", cmd__config },
+       { "ctype", cmd__ctype },
+       { "date", cmd__date },
+       { "delta", cmd__delta },
+       { "drop-caches", cmd__drop_caches },
+       { "dump-cache-tree", cmd__dump_cache_tree },
+       { "dump-split-index", cmd__dump_split_index },
+       { "example-decorate", cmd__example_decorate },
+       { "genrandom", cmd__genrandom },
+       { "hashmap", cmd__hashmap },
+       { "index-version", cmd__index_version },
+       { "lazy-init-name-hash", cmd__lazy_init_name_hash },
+       { "match-trees", cmd__match_trees },
+       { "mergesort", cmd__mergesort },
+       { "mktemp", cmd__mktemp },
+       { "online-cpus", cmd__online_cpus },
+       { "path-utils", cmd__path_utils },
+       { "prio-queue", cmd__prio_queue },
+       { "read-cache", cmd__read_cache },
+       { "ref-store", cmd__ref_store },
+       { "regex", cmd__regex },
+       { "revision-walking", cmd__revision_walking },
+       { "run-command", cmd__run_command },
+       { "scrap-cache-tree", cmd__scrap_cache_tree },
+       { "sha1-array", cmd__sha1_array },
+       { "sha1", cmd__sha1 },
+       { "sigchain", cmd__sigchain },
+       { "strcmp-offset", cmd__strcmp_offset },
+       { "string-list", cmd__string_list },
+       { "submodule-config", cmd__submodule_config },
+       { "subprocess", cmd__subprocess },
+       { "urlmatch-normalization", cmd__urlmatch_normalization },
+       { "wildmatch", cmd__wildmatch },
+       { "write-cache", cmd__write_cache },
+};
+
+int cmd_main(int argc, const char **argv)
+{
+       int i;
+
+       if (argc < 2)
+               die("I need a test name!");
+
+       for (i = 0; i < ARRAY_SIZE(cmds); i++) {
+               if (!strcmp(cmds[i].name, argv[1])) {
+                       argv++;
+                       argc--;
+                       return cmds[i].fn(argc, argv);
+               }
+       }
+       die("There is no test named '%s'", argv[1]);
+}
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
new file mode 100644 (file)
index 0000000..7116ddf
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef __TEST_TOOL_H__
+#define __TEST_TOOL_H__
+
+int cmd__chmtime(int argc, const char **argv);
+int cmd__config(int argc, const char **argv);
+int cmd__ctype(int argc, const char **argv);
+int cmd__date(int argc, const char **argv);
+int cmd__delta(int argc, const char **argv);
+int cmd__drop_caches(int argc, const char **argv);
+int cmd__dump_cache_tree(int argc, const char **argv);
+int cmd__dump_split_index(int argc, const char **argv);
+int cmd__example_decorate(int argc, const char **argv);
+int cmd__genrandom(int argc, const char **argv);
+int cmd__hashmap(int argc, const char **argv);
+int cmd__index_version(int argc, const char **argv);
+int cmd__lazy_init_name_hash(int argc, const char **argv);
+int cmd__match_trees(int argc, const char **argv);
+int cmd__mergesort(int argc, const char **argv);
+int cmd__mktemp(int argc, const char **argv);
+int cmd__online_cpus(int argc, const char **argv);
+int cmd__path_utils(int argc, const char **argv);
+int cmd__prio_queue(int argc, const char **argv);
+int cmd__read_cache(int argc, const char **argv);
+int cmd__ref_store(int argc, const char **argv);
+int cmd__regex(int argc, const char **argv);
+int cmd__revision_walking(int argc, const char **argv);
+int cmd__run_command(int argc, const char **argv);
+int cmd__scrap_cache_tree(int argc, const char **argv);
+int cmd__sha1_array(int argc, const char **argv);
+int cmd__sha1(int argc, const char **argv);
+int cmd__sigchain(int argc, const char **argv);
+int cmd__strcmp_offset(int argc, const char **argv);
+int cmd__string_list(int argc, const char **argv);
+int cmd__submodule_config(int argc, const char **argv);
+int cmd__subprocess(int argc, const char **argv);
+int cmd__urlmatch_normalization(int argc, const char **argv);
+int cmd__wildmatch(int argc, const char **argv);
+int cmd__write_cache(int argc, const char **argv);
+
+#endif
index 49b6e836be257c0689601bf17138439cff0d61a0..8f4d67e646953c5b094b55ec8112f6ba3b9b9024 100644 (file)
@@ -1,9 +1,10 @@
+#include "test-tool.h"
 #include "git-compat-util.h"
 #include "urlmatch.h"
 
-int cmd_main(int argc, const char **argv)
+int cmd__urlmatch_normalization(int argc, const char **argv)
 {
-       const char usage[] = "test-urlmatch-normalization [-p | -l] <url1> | <url1> <url2>";
+       const char usage[] = "test-tool urlmatch-normalization [-p | -l] <url1> | <url1> <url2>";
        char *url1, *url2;
        int opt_p = 0, opt_l = 0;
 
index 66d33dfcfd1a0b3fa6b94a029aab9117a2511224..2c103d1824cfc7f035aea4a6453c9706f9b4491e 100644 (file)
@@ -1,6 +1,7 @@
+#include "test-tool.h"
 #include "cache.h"
 
-int cmd_main(int argc, const char **argv)
+int cmd__wildmatch(int argc, const char **argv)
 {
        int i;
        for (i = 2; i < argc; i++) {
index b7ee0396692b6143e852af16695dd5800c0044be..017dc303800d9ba385a9836d85f81445c6b7e8b7 100644 (file)
@@ -1,9 +1,10 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "lockfile.h"
 
 static struct lock_file index_lock;
 
-int cmd_main(int argc, const char **argv)
+int cmd__write_cache(int argc, const char **argv)
 {
        int i, cnt = 1, lockfd;
        if (argc == 2)
index 54fd5a6ca02757f77004d0f8babfcc6d616162c0..c27599474cf2f272b53e2e76997e5e38af0fe647 100644 (file)
@@ -39,7 +39,7 @@ native_path () {
        then
                path=$(cygpath --windows "$path")
        else
-               path=$(test-path-utils real_path "$path")
+               path=$(test-tool path-utils real_path "$path")
        fi &&
        echo "$path"
 }
index 4c1f81f1678d83ab8b9ee7704d400bdd47ea70f7..a8130f9119d629462efb6b52f91890c0352e4e85 100644 (file)
@@ -49,7 +49,7 @@ rawsvnrepo="$svnrepo"
 svnrepo="file://$svnrepo"
 
 poke() {
-       test-chmtime +1 "$1"
+       test-tool chmtime +1 "$1"
 }
 
 # We need this, because we should pass empty configuration directory to
index 75098465716512a3373e64d51a5cdf848e9f1101..501078249dc7d5d5b27dd6b75a22086767a0eddf 100644 (file)
@@ -85,7 +85,7 @@ pack_obj () {
 
 # Compute and append pack trailer to "$1"
 pack_trailer () {
-       test-sha1 -b <"$1" >trailer.tmp &&
+       test-tool sha1 -b <"$1" >trailer.tmp &&
        cat trailer.tmp >>"$1" &&
        rm -f trailer.tmp
 }
index 821cf1498b78bbb5b43b2bda32bbcc88d580c31b..48637ef64bb658098d8bc1d0f00eba87f7daa681 100755 (executable)
@@ -37,7 +37,7 @@ sub format_times {
 }
 
 my (@dirs, %dirnames, %dirabbrevs, %prefixes, @tests,
-    $codespeed, $subsection, $reponame);
+    $codespeed, $sortby, $subsection, $reponame);
 while (scalar @ARGV) {
        my $arg = $ARGV[0];
        my $dir;
@@ -46,6 +46,18 @@ sub format_times {
                shift @ARGV;
                next;
        }
+       if ($arg =~ /--sort-by(?:=(.*))?/) {
+               shift @ARGV;
+               if (defined $1) {
+                       $sortby = $1;
+               } else {
+                       $sortby = shift @ARGV;
+                       if (! defined $sortby) {
+                               die "'--sort-by' requires an argument";
+                       }
+               }
+               next;
+       }
        if ($arg eq "--subsection") {
                shift @ARGV;
                $subsection = $ARGV[0];
@@ -147,6 +159,11 @@ sub have_slash {
        return 0;
 }
 
+sub display_dir {
+       my ($d) = @_;
+       return exists $dirabbrevs{$d} ? $dirabbrevs{$d} : $dirnames{$d};
+}
+
 sub print_default_results {
        my %descrs;
        my $descrlen = 4; # "Test"
@@ -168,8 +185,7 @@ sub print_default_results {
        my %times;
        my @colwidth = ((0)x@dirs);
        for my $i (0..$#dirs) {
-               my $d = $dirs[$i];
-               my $w = length (exists $dirabbrevs{$d} ? $dirabbrevs{$d} : $dirnames{$d});
+               my $w = length display_dir($dirs[$i]);
                $colwidth[$i] = $w if $w > $colwidth[$i];
        }
        for my $t (@subtests) {
@@ -188,8 +204,7 @@ sub print_default_results {
 
        printf "%-${descrlen}s", "Test";
        for my $i (0..$#dirs) {
-               my $d = $dirs[$i];
-               printf "   %-$colwidth[$i]s", (exists $dirabbrevs{$d} ? $dirabbrevs{$d} : $dirnames{$d});
+               printf "   %-$colwidth[$i]s", display_dir($dirs[$i]);
        }
        print "\n";
        print "-"x$totalwidth, "\n";
@@ -206,6 +221,49 @@ sub print_default_results {
        }
 }
 
+sub print_sorted_results {
+       my ($sortby) = @_;
+
+       if ($sortby ne "regression") {
+               die "only 'regression' is supported as '--sort-by' argument";
+       }
+
+       my @evolutions;
+       for my $t (@subtests) {
+               my ($prevr, $prevu, $prevs, $prevrev);
+               for my $i (0..$#dirs) {
+                       my $d = $dirs[$i];
+                       my ($r, $u, $s) = get_times("$resultsdir/$prefixes{$d}$t.times");
+                       if ($i > 0 and defined $r and defined $prevr and $prevr > 0) {
+                               my $percent = 100.0 * ($r - $prevr) / $prevr;
+                               push @evolutions, { "percent"  => $percent,
+                                                   "test"     => $t,
+                                                   "prevrev"  => $prevrev,
+                                                   "rev"      => $d,
+                                                   "prevr"    => $prevr,
+                                                   "r"        => $r,
+                                                   "prevu"    => $prevu,
+                                                   "u"        => $u,
+                                                   "prevs"    => $prevs,
+                                                   "s"        => $s};
+                       }
+                       ($prevr, $prevu, $prevs, $prevrev) = ($r, $u, $s, $d);
+               }
+       }
+
+       my @sorted_evolutions = sort { $b->{percent} <=> $a->{percent} } @evolutions;
+
+       for my $e (@sorted_evolutions) {
+               printf "%+.1f%%", $e->{percent};
+               print " " . $e->{test};
+               print " " . format_times($e->{prevr}, $e->{prevu}, $e->{prevs});
+               print " " . format_times($e->{r}, $e->{u}, $e->{s});
+               print " " . display_dir($e->{prevrev});
+               print " " . display_dir($e->{rev});
+               print "\n";
+       }
+}
+
 sub print_codespeed_results {
        my ($subsection) = @_;
 
@@ -260,6 +318,8 @@ sub print_codespeed_results {
 
 if ($codespeed) {
        print_codespeed_results($subsection);
+} elsif (defined $sortby) {
+       print_sorted_results($sortby);
 } else {
        print_default_results();
 }
index 9180ae9343a03824653e087aaa766b9d33e50a94..cdd105a5945239850a12479ff1138a5428e3b6d6 100755 (executable)
@@ -8,7 +8,7 @@ test_perf_default_repo
 
 count=1000
 test_perf "read_cache/discard_cache $count times" "
-       test-read-cache $count
+       test-tool read-cache $count
 "
 
 test_done
index 8de5a98cfc6c513bb35cd8355f3e831ab3a8007d..1afc08fe7f1990cdf7143f0dfd3cfaa66628ca73 100755 (executable)
@@ -7,8 +7,8 @@ test_perf_large_repo
 test_checkout_worktree
 
 test_expect_success 'verify both methods build the same hashmaps' '
-       test-lazy-init-name-hash --dump --single >out.single &&
-       if test-lazy-init-name-hash --dump --multi >out.multi
+       test-tool lazy-init-name-hash --dump --single >out.single &&
+       if test-tool lazy-init-name-hash --dump --multi >out.multi
        then
                test_set_prereq REPO_BIG_ENOUGH_FOR_MULTI &&
                sort <out.single >sorted.single &&
@@ -46,11 +46,11 @@ test_expect_success 'calibrate' '
 '
 
 test_perf "single-threaded, $desc" "
-       test-lazy-init-name-hash --single --count=$count
+       test-tool lazy-init-name-hash --single --count=$count
 "
 
 test_perf REPO_BIG_ENOUGH_FOR_MULTI "multi-threaded, $desc" "
-       test-lazy-init-name-hash --multi --count=$count
+       test-tool lazy-init-name-hash --multi --count=$count
 "
 
 test_done
index 261fe92fd93aaf65101dfe4d1b87741453985cbe..09595264f09fa4b1dc28b3e5d2a3d6482d998bcc 100755 (executable)
@@ -23,7 +23,7 @@ test_expect_success "setup repo" '
 
 count=3
 test_perf "write_locked_index $count times ($nr_files files)" "
-       test-write-cache $count
+       test-tool write-cache $count
 "
 
 test_done
index 7c9a35a646a6406e5c284a65748863a93098c2af..6e924f5fa3f900b4b82a55f282e810572a62f20b 100755 (executable)
@@ -16,7 +16,7 @@ test_perf 'sort(1)' '
 '
 
 test_perf 'string_list_sort()' '
-       test-string-list sort <unsorted >actual
+       test-tool string-list sort <unsorted >actual
 '
 
 test_expect_success 'string_list_sort() sorts like sort(1)' '
index 65e145c02d9eafc5a43d56c1fb30fef7be63d704..def7ecdbc786c6472e5b7909a97650a1034cecb2 100755 (executable)
@@ -118,7 +118,7 @@ test_expect_success "setup for fsmonitor" '
 '
 
 if test -n "$GIT_PERF_7519_DROP_CACHE"; then
-       test-drop-caches
+       test-tool drop-caches
 fi
 
 test_perf "status (fsmonitor=$INTEGRATION_SCRIPT)" '
@@ -126,7 +126,7 @@ test_perf "status (fsmonitor=$INTEGRATION_SCRIPT)" '
 '
 
 if test -n "$GIT_PERF_7519_DROP_CACHE"; then
-       test-drop-caches
+       test-tool drop-caches
 fi
 
 test_perf "status -uno (fsmonitor=$INTEGRATION_SCRIPT)" '
@@ -134,7 +134,7 @@ test_perf "status -uno (fsmonitor=$INTEGRATION_SCRIPT)" '
 '
 
 if test -n "$GIT_PERF_7519_DROP_CACHE"; then
-       test-drop-caches
+       test-tool drop-caches
 fi
 
 test_perf "status -uall (fsmonitor=$INTEGRATION_SCRIPT)" '
@@ -148,7 +148,7 @@ test_expect_success "setup without fsmonitor" '
 '
 
 if test -n "$GIT_PERF_7519_DROP_CACHE"; then
-       test-drop-caches
+       test-tool drop-caches
 fi
 
 test_perf "status (fsmonitor=$INTEGRATION_SCRIPT)" '
@@ -156,7 +156,7 @@ test_perf "status (fsmonitor=$INTEGRATION_SCRIPT)" '
 '
 
 if test -n "$GIT_PERF_7519_DROP_CACHE"; then
-       test-drop-caches
+       test-tool drop-caches
 fi
 
 test_perf "status -uno (fsmonitor=$INTEGRATION_SCRIPT)" '
@@ -164,7 +164,7 @@ test_perf "status -uno (fsmonitor=$INTEGRATION_SCRIPT)" '
 '
 
 if test -n "$GIT_PERF_7519_DROP_CACHE"; then
-       test-drop-caches
+       test-tool drop-caches
 fi
 
 test_perf "status -uall (fsmonitor=$INTEGRATION_SCRIPT)" '
index 46042f1f1338f628d5256f0e932a4037e98b34ab..4c214bd11c48859f0c4e64dbbe2d783e744eb1d1 100755 (executable)
@@ -10,7 +10,7 @@ one
 EOF
 
 test_expect_success 'sigchain works' '
-       { test-sigchain >actual; ret=$?; } &&
+       { test-tool sigchain >actual; ret=$?; } &&
        {
                # Signal death by raise() on Windows acts like exit(3),
                # regardless of the signal number. So we must allow that
@@ -24,7 +24,7 @@ test_expect_success 'sigchain works' '
 test_expect_success !MINGW 'signals are propagated using shell convention' '
        # we use exec here to avoid any sub-shell interpretation
        # of the exit code
-       git config alias.sigterm "!exec test-sigchain" &&
+       git config alias.sigterm "!exec test-tool sigchain" &&
        test_expect_code 143 git sigterm
 '
 
@@ -36,7 +36,7 @@ large_git () {
 }
 
 test_expect_success 'create blob' '
-       test-genrandom foo 16384 >file &&
+       test-tool genrandom foo 16384 >file &&
        git add file
 '
 
index 7ac9466d5055e02179467fa9e41004bbc89df6dc..64ff86df8eb02aa635af1bad0b6d1f31578f222a 100755 (executable)
@@ -10,7 +10,7 @@ check_relative() {
        t=$(($TEST_DATE_NOW - $1))
        echo "$t -> $2" >expect
        test_expect_${3:-success} "relative date ($2)" "
-       test-date relative $t >actual &&
+       test-tool date relative $t >actual &&
        test_i18ncmp expect actual
        "
 }
@@ -35,7 +35,7 @@ check_show () {
        zone=$5
        test_expect_success $prereqs "show date ($format:$time)" '
                echo "$time -> $expect" >expect &&
-               TZ=${zone:-$TZ} test-date show:"$format" "$time" >actual &&
+               TZ=${zone:-$TZ} test-tool date show:"$format" "$time" >actual &&
                test_cmp expect actual
        '
 }
@@ -71,7 +71,7 @@ check_show iso-local "$FUTURE" "2152-06-19 22:24:56 +0000" TIME_IS_64BIT,TIME_T_
 check_parse() {
        echo "$1 -> $2" >expect
        test_expect_${4:-success} "parse date ($1${3:+ TZ=$3})" "
-       TZ=${3:-$TZ} test-date parse '$1' >actual &&
+       TZ=${3:-$TZ} test-tool date parse '$1' >actual &&
        test_cmp expect actual
        "
 }
@@ -92,7 +92,7 @@ check_parse '2008-02-14 20:30:45' '2008-02-14 20:30:45 -0500' EST5
 check_approxidate() {
        echo "$1 -> $2 +0000" >expect
        test_expect_${3:-success} "parse approxidate ($1)" "
-       test-date approxidate '$1' >actual &&
+       test-tool date approxidate '$1' >actual &&
        test_cmp expect actual
        "
 }
index 94045c3fad18d94e0e83acf757594cede066134b..e56dfce6680298c133bc2b2de12d9492fda66b7a 100755 (executable)
@@ -17,7 +17,7 @@ cat >expect <<'EOF'
 10
 EOF
 test_expect_success 'basic ordering' '
-       test-prio-queue 2 6 3 10 9 5 7 4 5 8 1 dump >actual &&
+       test-tool prio-queue 2 6 3 10 9 5 7 4 5 8 1 dump >actual &&
        test_cmp expect actual
 '
 
@@ -30,7 +30,7 @@ cat >expect <<'EOF'
 6
 EOF
 test_expect_success 'mixed put and get' '
-       test-prio-queue 6 2 4 get 5 3 get get 1 dump >actual &&
+       test-tool prio-queue 6 2 4 get 5 3 get get 1 dump >actual &&
        test_cmp expect actual
 '
 
@@ -43,7 +43,7 @@ NULL
 NULL
 EOF
 test_expect_success 'notice empty queue' '
-       test-prio-queue 1 2 get get get 1 2 get get get >actual &&
+       test-tool prio-queue 1 2 get get get 1 2 get get get >actual &&
        test_cmp expect actual
 '
 
index 9c217d948c14dfd75f73e27a0911fd194eb11bce..3f1f505e8937f391666a1b7e6d9b972a5f146974 100755 (executable)
@@ -4,7 +4,7 @@ test_description='test hashmap and string hash functions'
 . ./test-lib.sh
 
 test_hashmap() {
-       echo "$1" | test-hashmap $3 > actual &&
+       echo "$1" | test-tool hashmap $3 > actual &&
        echo "$2" > expect &&
        test_cmp expect actual
 }
@@ -232,7 +232,7 @@ test_expect_success 'grow / shrink' '
        echo value40 >> expect &&
        echo size >> in &&
        echo 64 39 >> expect &&
-       cat in | test-hashmap > out &&
+       cat in | test-tool hashmap > out &&
        test_cmp expect out
 
 '
index 6d655cb161b2ed39eda97bb4acb54d1cf74a826d..419f31a8f7d4cb20041f054d25ddb25c7d43e3fb 100755 (executable)
@@ -11,7 +11,7 @@ then
 fi
 
 test_expect_success 'test-sha1 detects shattered pdf' '
-       test_must_fail test-sha1 <"$TEST_DATA/shattered-1.pdf" 2>err &&
+       test_must_fail test-tool sha1 <"$TEST_DATA/shattered-1.pdf" 2>err &&
        test_i18ngrep collision err &&
        grep 38762cf7f55934b34d179ae6a4c80cadccbb7f0a err
 '
index 46f8e583c37da7d03d715ea5cb1a4ee5bbe0ca28..9479a4aaabc1a4187fc702f864642ac493508bb9 100755 (executable)
@@ -19,7 +19,7 @@ write_script rot13-filter.pl "$PERL_PATH" \
 generate_random_characters () {
        LEN=$1
        NAME=$2
-       test-genrandom some-seed $LEN |
+       test-tool genrandom some-seed $LEN |
                perl -pe "s/./chr((ord($&) % 26) + ord('a'))/sge" >"$TEST_ROOT/$NAME"
 }
 
@@ -267,7 +267,7 @@ test_expect_success 'filtering large input to small output should use little mem
 '
 
 test_expect_success 'filter that does not read is fine' '
-       test-genrandom foo $((128 * 1024 + 1)) >big &&
+       test-tool genrandom foo $((128 * 1024 + 1)) >big &&
        echo "big filter=epipe" >.gitattributes &&
        test_config filter.epipe.clean "echo xyzzy" &&
        git add big &&
index 0c2fc81d7b0fa401db58c41cd2fed4469e80b058..04d474c84fd69121c686f5ca5adc40ce081f0e9d 100755 (executable)
@@ -291,7 +291,7 @@ test_expect_success 'OPT_CALLBACK() and OPT_BIT() work' '
 test_expect_success 'OPT_CALLBACK() and callback errors work' '
        test_must_fail test-parse-options --no-length >output 2>output.err &&
        test_i18ncmp expect output &&
-       test_i18ncmp expect.err output.err
+       test_must_be_empty output.err
 '
 
 cat >expect <<\EOF
diff --git a/t/t0041-usage.sh b/t/t0041-usage.sh
new file mode 100755 (executable)
index 0000000..5b927b7
--- /dev/null
@@ -0,0 +1,107 @@
+#!/bin/sh
+
+test_description='Test commands behavior when given invalid argument value'
+
+. ./test-lib.sh
+
+test_expect_success 'setup ' '
+       test_commit "v1.0"
+'
+
+test_expect_success 'tag --contains <existent_tag>' '
+       git tag --contains "v1.0" >actual 2>actual.err &&
+       grep "v1.0" actual &&
+       test_line_count = 0 actual.err
+'
+
+test_expect_success 'tag --contains <inexistent_tag>' '
+       test_must_fail git tag --contains "notag" >actual 2>actual.err &&
+       test_line_count = 0 actual &&
+       test_i18ngrep "error" actual.err &&
+       test_i18ngrep ! "usage" actual.err
+'
+
+test_expect_success 'tag --no-contains <existent_tag>' '
+       git tag --no-contains "v1.0" >actual 2>actual.err  &&
+       test_line_count = 0 actual &&
+       test_line_count = 0 actual.err
+'
+
+test_expect_success 'tag --no-contains <inexistent_tag>' '
+       test_must_fail git tag --no-contains "notag" >actual 2>actual.err &&
+       test_line_count = 0 actual &&
+       test_i18ngrep "error" actual.err &&
+       test_i18ngrep ! "usage" actual.err
+'
+
+test_expect_success 'tag usage error' '
+       test_must_fail git tag --noopt >actual 2>actual.err &&
+       test_line_count = 0 actual &&
+       test_i18ngrep "usage" actual.err
+'
+
+test_expect_success 'branch --contains <existent_commit>' '
+       git branch --contains "master" >actual 2>actual.err &&
+       test_i18ngrep "master" actual &&
+       test_line_count = 0 actual.err
+'
+
+test_expect_success 'branch --contains <inexistent_commit>' '
+       test_must_fail git branch --no-contains "nocommit" >actual 2>actual.err &&
+       test_line_count = 0 actual &&
+       test_i18ngrep "error" actual.err &&
+       test_i18ngrep ! "usage" actual.err
+'
+
+test_expect_success 'branch --no-contains <existent_commit>' '
+       git branch --no-contains "master" >actual 2>actual.err &&
+       test_line_count = 0 actual &&
+       test_line_count = 0 actual.err
+'
+
+test_expect_success 'branch --no-contains <inexistent_commit>' '
+       test_must_fail git branch --no-contains "nocommit" >actual 2>actual.err &&
+       test_line_count = 0 actual &&
+       test_i18ngrep "error" actual.err &&
+       test_i18ngrep ! "usage" actual.err
+'
+
+test_expect_success 'branch usage error' '
+       test_must_fail git branch --noopt >actual 2>actual.err &&
+       test_line_count = 0 actual &&
+       test_i18ngrep "usage" actual.err
+'
+
+test_expect_success 'for-each-ref --contains <existent_object>' '
+       git for-each-ref --contains "master" >actual 2>actual.err &&
+       test_line_count = 2 actual &&
+       test_line_count = 0 actual.err
+'
+
+test_expect_success 'for-each-ref --contains <inexistent_object>' '
+       test_must_fail git for-each-ref --no-contains "noobject" >actual 2>actual.err &&
+       test_line_count = 0 actual &&
+       test_i18ngrep "error" actual.err &&
+       test_i18ngrep ! "usage" actual.err
+'
+
+test_expect_success 'for-each-ref --no-contains <existent_object>' '
+       git for-each-ref --no-contains "master" >actual 2>actual.err &&
+       test_line_count = 0 actual &&
+       test_line_count = 0 actual.err
+'
+
+test_expect_success 'for-each-ref --no-contains <inexistent_object>' '
+       test_must_fail git for-each-ref --no-contains "noobject" >actual 2>actual.err &&
+       test_line_count = 0 actual &&
+       test_i18ngrep "error" actual.err &&
+       test_i18ngrep ! "usage" actual.err
+'
+
+test_expect_success 'for-each-ref usage error' '
+       test_must_fail git for-each-ref --noopt >actual 2>actual.err &&
+       test_line_count = 0 actual &&
+       test_i18ngrep "usage" actual.err
+'
+
+test_done
index 7ea2bb515bd80cc026a18dbfdf4a66cb77d27f20..f46e3c4995509f62f954231f53321f1d24756eff 100755 (executable)
@@ -8,15 +8,15 @@ test_description='Test various path utilities'
 . ./test-lib.sh
 
 norm_path() {
-       expected=$(test-path-utils print_path "$2")
+       expected=$(test-tool path-utils print_path "$2")
        test_expect_success $3 "normalize path: $1 => $2" \
-       "test \"\$(test-path-utils normalize_path_copy '$1')\" = '$expected'"
+       "test \"\$(test-tool path-utils normalize_path_copy '$1')\" = '$expected'"
 }
 
 relative_path() {
-       expected=$(test-path-utils print_path "$3")
+       expected=$(test-tool path-utils print_path "$3")
        test_expect_success $4 "relative path: $1 $2 => $3" \
-       "test \"\$(test-path-utils relative_path '$1' '$2')\" = '$expected'"
+       "test \"\$(test-tool path-utils relative_path '$1' '$2')\" = '$expected'"
 }
 
 test_submodule_relative_url() {
@@ -37,7 +37,7 @@ test_git_path() {
 # On Windows, we are using MSYS's bash, which mangles the paths.
 # Absolute paths are anchored at the MSYS installation directory,
 # which means that the path / accounts for this many characters:
-rootoff=$(test-path-utils normalize_path_copy / | wc -c)
+rootoff=$(test-tool path-utils normalize_path_copy / | wc -c)
 # Account for the trailing LF:
 if test $rootoff = 2; then
        rootoff=        # we are on Unix
@@ -46,7 +46,7 @@ else
        # In MSYS2, the root directory "/" is translated into a Windows
        # directory *with* trailing slash. Let's test for that and adjust
        # our expected longest ancestor length accordingly.
-       case "$(test-path-utils print_path /)" in
+       case "$(test-tool path-utils print_path /)" in
        */) rootslash=1;;
        *) rootslash=0;;
        esac
@@ -61,7 +61,7 @@ ancestor() {
                expected=$(($expected+$rootoff))
        fi
        test_expect_success "longest ancestor: $1 $2 => $expected" \
-       "actual=\$(test-path-utils longest_ancestor_length '$1' '$2') &&
+       "actual=\$(test-tool path-utils longest_ancestor_length '$1' '$2') &&
         test \"\$actual\" = '$expected'"
 }
 
@@ -77,8 +77,8 @@ case $(uname -s) in
        ;;
 esac
 
-test_expect_success basename 'test-path-utils basename'
-test_expect_success dirname 'test-path-utils dirname'
+test_expect_success basename 'test-tool path-utils basename'
+test_expect_success dirname 'test-tool path-utils dirname'
 
 norm_path "" ""
 norm_path . ""
@@ -157,48 +157,48 @@ ancestor /foo/bar /foo:/bar 4
 ancestor /foo/bar /bar -1
 
 test_expect_success 'strip_path_suffix' '
-       test c:/msysgit = $(test-path-utils strip_path_suffix \
+       test c:/msysgit = $(test-tool path-utils strip_path_suffix \
                c:/msysgit/libexec//git-core libexec/git-core)
 '
 
 test_expect_success 'absolute path rejects the empty string' '
-       test_must_fail test-path-utils absolute_path ""
+       test_must_fail test-tool path-utils absolute_path ""
 '
 
 test_expect_success 'real path rejects the empty string' '
-       test_must_fail test-path-utils real_path ""
+       test_must_fail test-tool path-utils real_path ""
 '
 
 test_expect_success POSIX 'real path works on absolute paths 1' '
        nopath="hopefully-absent-path" &&
-       test "/" = "$(test-path-utils real_path "/")" &&
-       test "/$nopath" = "$(test-path-utils real_path "/$nopath")"
+       test "/" = "$(test-tool path-utils real_path "/")" &&
+       test "/$nopath" = "$(test-tool path-utils real_path "/$nopath")"
 '
 
 test_expect_success 'real path works on absolute paths 2' '
        nopath="hopefully-absent-path" &&
        # Find an existing top-level directory for the remaining tests:
        d=$(pwd -P | sed -e "s|^\([^/]*/[^/]*\)/.*|\1|") &&
-       test "$d" = "$(test-path-utils real_path "$d")" &&
-       test "$d/$nopath" = "$(test-path-utils real_path "$d/$nopath")"
+       test "$d" = "$(test-tool path-utils real_path "$d")" &&
+       test "$d/$nopath" = "$(test-tool path-utils real_path "$d/$nopath")"
 '
 
 test_expect_success POSIX 'real path removes extra leading slashes' '
        nopath="hopefully-absent-path" &&
-       test "/" = "$(test-path-utils real_path "///")" &&
-       test "/$nopath" = "$(test-path-utils real_path "///$nopath")" &&
+       test "/" = "$(test-tool path-utils real_path "///")" &&
+       test "/$nopath" = "$(test-tool path-utils real_path "///$nopath")" &&
        # Find an existing top-level directory for the remaining tests:
        d=$(pwd -P | sed -e "s|^\([^/]*/[^/]*\)/.*|\1|") &&
-       test "$d" = "$(test-path-utils real_path "//$d")" &&
-       test "$d/$nopath" = "$(test-path-utils real_path "//$d/$nopath")"
+       test "$d" = "$(test-tool path-utils real_path "//$d")" &&
+       test "$d/$nopath" = "$(test-tool path-utils real_path "//$d/$nopath")"
 '
 
 test_expect_success 'real path removes other extra slashes' '
        nopath="hopefully-absent-path" &&
        # Find an existing top-level directory for the remaining tests:
        d=$(pwd -P | sed -e "s|^\([^/]*/[^/]*\)/.*|\1|") &&
-       test "$d" = "$(test-path-utils real_path "$d///")" &&
-       test "$d/$nopath" = "$(test-path-utils real_path "$d///$nopath")"
+       test "$d" = "$(test-tool path-utils real_path "$d///")" &&
+       test "$d/$nopath" = "$(test-tool path-utils real_path "$d///$nopath")"
 '
 
 test_expect_success SYMLINKS 'real path works on symlinks' '
@@ -209,35 +209,35 @@ test_expect_success SYMLINKS 'real path works on symlinks' '
        mkdir third &&
        dir="$(cd .git; pwd -P)" &&
        dir2=third/../second/other/.git &&
-       test "$dir" = "$(test-path-utils real_path $dir2)" &&
+       test "$dir" = "$(test-tool path-utils real_path $dir2)" &&
        file="$dir"/index &&
-       test "$file" = "$(test-path-utils real_path $dir2/index)" &&
+       test "$file" = "$(test-tool path-utils real_path $dir2/index)" &&
        basename=blub &&
-       test "$dir/$basename" = "$(cd .git && test-path-utils real_path "$basename")" &&
+       test "$dir/$basename" = "$(cd .git && test-tool path-utils real_path "$basename")" &&
        ln -s ../first/file .git/syml &&
        sym="$(cd first; pwd -P)"/file &&
-       test "$sym" = "$(test-path-utils real_path "$dir2/syml")"
+       test "$sym" = "$(test-tool path-utils real_path "$dir2/syml")"
 '
 
 test_expect_success SYMLINKS 'prefix_path works with absolute paths to work tree symlinks' '
        ln -s target symlink &&
-       test "$(test-path-utils prefix_path prefix "$(pwd)/symlink")" = "symlink"
+       test "$(test-tool path-utils prefix_path prefix "$(pwd)/symlink")" = "symlink"
 '
 
 test_expect_success 'prefix_path works with only absolute path to work tree' '
        echo "" >expected &&
-       test-path-utils prefix_path prefix "$(pwd)" >actual &&
+       test-tool path-utils prefix_path prefix "$(pwd)" >actual &&
        test_cmp expected actual
 '
 
 test_expect_success 'prefix_path rejects absolute path to dir with same beginning as work tree' '
-       test_must_fail test-path-utils prefix_path prefix "$(pwd)a"
+       test_must_fail test-tool path-utils prefix_path prefix "$(pwd)a"
 '
 
 test_expect_success SYMLINKS 'prefix_path works with absolute path to a symlink to work tree having  same beginning as work tree' '
        git init repo &&
        ln -s repo repolink &&
-       test "a" = "$(cd repo && test-path-utils prefix_path prefix "$(pwd)/../repolink/a")"
+       test "a" = "$(cd repo && test-tool path-utils prefix_path prefix "$(pwd)/../repolink/a")"
 '
 
 relative_path /foo/a/b/c/      /foo/a/b/       c/
index 24c92b6cd7b1c54eb6541a81abd7e5812b3b99b0..d03149be9f667307a181ef17a3291ecc7eeb19cb 100755 (executable)
@@ -14,13 +14,13 @@ EOF
 >empty
 
 test_expect_success 'start_command reports ENOENT' '
-       test-run-command start-command-ENOENT ./does-not-exist
+       test-tool run-command start-command-ENOENT ./does-not-exist
 '
 
 test_expect_success 'run_command can run a command' '
        cat hello-script >hello.sh &&
        chmod +x hello.sh &&
-       test-run-command run-command ./hello.sh >actual 2>err &&
+       test-tool run-command run-command ./hello.sh >actual 2>err &&
 
        test_cmp hello-script actual &&
        test_cmp empty err
@@ -31,7 +31,7 @@ test_expect_success !MINGW 'run_command can run a script without a #! line' '
        cat hello-script
        EOF
        chmod +x hello &&
-       test-run-command run-command ./hello >actual 2>err &&
+       test-tool run-command run-command ./hello >actual 2>err &&
 
        test_cmp hello-script actual &&
        test_cmp empty err
@@ -45,7 +45,7 @@ test_expect_success 'run_command does not try to execute a directory' '
        EOF
 
        PATH=$PWD/bin1:$PWD/bin2:$PATH \
-               test-run-command run-command greet >actual 2>err &&
+               test-tool run-command run-command greet >actual 2>err &&
        test_cmp bin2/greet actual &&
        test_cmp empty err
 '
@@ -62,7 +62,7 @@ test_expect_success POSIXPERM 'run_command passes over non-executable file' '
        EOF
 
        PATH=$PWD/bin1:$PWD/bin2:$PATH \
-               test-run-command run-command greet >actual 2>err &&
+               test-tool run-command run-command greet >actual 2>err &&
        test_cmp bin2/greet actual &&
        test_cmp empty err
 '
@@ -70,7 +70,7 @@ test_expect_success POSIXPERM 'run_command passes over non-executable file' '
 test_expect_success POSIXPERM 'run_command reports EACCES' '
        cat hello-script >hello.sh &&
        chmod -x hello.sh &&
-       test_must_fail test-run-command run-command ./hello.sh 2>err &&
+       test_must_fail test-tool run-command run-command ./hello.sh 2>err &&
 
        grep "fatal: cannot exec.*hello.sh" err
 '
@@ -104,17 +104,17 @@ World
 EOF
 
 test_expect_success 'run_command runs in parallel with more jobs available than tasks' '
-       test-run-command run-command-parallel 5 sh -c "printf \"%s\n%s\n\" Hello World" 2>actual &&
+       test-tool run-command run-command-parallel 5 sh -c "printf \"%s\n%s\n\" Hello World" 2>actual &&
        test_cmp expect actual
 '
 
 test_expect_success 'run_command runs in parallel with as many jobs as tasks' '
-       test-run-command run-command-parallel 4 sh -c "printf \"%s\n%s\n\" Hello World" 2>actual &&
+       test-tool run-command run-command-parallel 4 sh -c "printf \"%s\n%s\n\" Hello World" 2>actual &&
        test_cmp expect actual
 '
 
 test_expect_success 'run_command runs in parallel with more tasks than jobs available' '
-       test-run-command run-command-parallel 3 sh -c "printf \"%s\n%s\n\" Hello World" 2>actual &&
+       test-tool run-command run-command-parallel 3 sh -c "printf \"%s\n%s\n\" Hello World" 2>actual &&
        test_cmp expect actual
 '
 
@@ -128,7 +128,7 @@ asking for a quick stop
 EOF
 
 test_expect_success 'run_command is asked to abort gracefully' '
-       test-run-command run-command-abort 3 false 2>actual &&
+       test-tool run-command run-command-abort 3 false 2>actual &&
        test_cmp expect actual
 '
 
@@ -137,14 +137,14 @@ no further jobs available
 EOF
 
 test_expect_success 'run_command outputs ' '
-       test-run-command run-command-no-jobs 3 sh -c "printf \"%s\n%s\n\" Hello World" 2>actual &&
+       test-tool run-command run-command-no-jobs 3 sh -c "printf \"%s\n%s\n\" Hello World" 2>actual &&
        test_cmp expect actual
 '
 
 test_trace () {
        expect="$1"
        shift
-       GIT_TRACE=1 test-run-command "$@" run-command true 2>&1 >/dev/null | \
+       GIT_TRACE=1 test-tool run-command "$@" run-command true 2>&1 >/dev/null | \
                sed 's/.* run_command: //' >actual &&
        echo "$expect true" >expect &&
        test_cmp expect actual
index 113c728e676679f8e8e8eb0fce433a84bbee8050..8e215867b8c197dedef32c569e1d1f632d22b631 100755 (executable)
@@ -26,7 +26,7 @@ test_expect_success 'setup' '
 '
 
 test_expect_success 'revision walking can be done twice' '
-       test-revision-walking run-twice >run_twice_actual &&
+       test-tool revision-walking run-twice >run_twice_actual &&
        test_cmp run_twice_expected run_twice_actual
 '
 
index dbfc05ebdc3990bf4ea5b0163afb4c6a9e698fa7..c6ee9f66b11d55f312ee673106ddf295c39bb50d 100755 (executable)
@@ -10,9 +10,9 @@ test_description='Test string list functionality'
 test_split () {
        cat >expected &&
        test_expect_success "split $1 at $2, max $3" "
-               test-string-list split '$1' '$2' '$3' >actual &&
+               test-tool string-list split '$1' '$2' '$3' >actual &&
                test_cmp expected actual &&
-               test-string-list split_in_place '$1' '$2' '$3' >actual &&
+               test-tool string-list split_in_place '$1' '$2' '$3' >actual &&
                test_cmp expected actual
        "
 }
@@ -61,31 +61,31 @@ test_split ":" ":" "-1" <<EOF
 EOF
 
 test_expect_success "test filter_string_list" '
-       test "x-" = "x$(test-string-list filter - y)" &&
-       test "x-" = "x$(test-string-list filter no y)" &&
-       test yes = "$(test-string-list filter yes y)" &&
-       test yes = "$(test-string-list filter no:yes y)" &&
-       test yes = "$(test-string-list filter yes:no y)" &&
-       test y1:y2 = "$(test-string-list filter y1:y2 y)" &&
-       test y2:y1 = "$(test-string-list filter y2:y1 y)" &&
-       test "x-" = "x$(test-string-list filter x1:x2 y)"
+       test "x-" = "x$(test-tool string-list filter - y)" &&
+       test "x-" = "x$(test-tool string-list filter no y)" &&
+       test yes = "$(test-tool string-list filter yes y)" &&
+       test yes = "$(test-tool string-list filter no:yes y)" &&
+       test yes = "$(test-tool string-list filter yes:no y)" &&
+       test y1:y2 = "$(test-tool string-list filter y1:y2 y)" &&
+       test y2:y1 = "$(test-tool string-list filter y2:y1 y)" &&
+       test "x-" = "x$(test-tool string-list filter x1:x2 y)"
 '
 
 test_expect_success "test remove_duplicates" '
-       test "x-" = "x$(test-string-list remove_duplicates -)" &&
-       test "x" = "x$(test-string-list remove_duplicates "")" &&
-       test a = "$(test-string-list remove_duplicates a)" &&
-       test a = "$(test-string-list remove_duplicates a:a)" &&
-       test a = "$(test-string-list remove_duplicates a:a:a:a:a)" &&
-       test a:b = "$(test-string-list remove_duplicates a:b)" &&
-       test a:b = "$(test-string-list remove_duplicates a:a:b)" &&
-       test a:b = "$(test-string-list remove_duplicates a:b:b)" &&
-       test a:b:c = "$(test-string-list remove_duplicates a:b:c)" &&
-       test a:b:c = "$(test-string-list remove_duplicates a:a:b:c)" &&
-       test a:b:c = "$(test-string-list remove_duplicates a:b:b:c)" &&
-       test a:b:c = "$(test-string-list remove_duplicates a:b:c:c)" &&
-       test a:b:c = "$(test-string-list remove_duplicates a:a:b:b:c:c)" &&
-       test a:b:c = "$(test-string-list remove_duplicates a:a:a:b:b:b:c:c:c)"
+       test "x-" = "x$(test-tool string-list remove_duplicates -)" &&
+       test "x" = "x$(test-tool string-list remove_duplicates "")" &&
+       test a = "$(test-tool string-list remove_duplicates a)" &&
+       test a = "$(test-tool string-list remove_duplicates a:a)" &&
+       test a = "$(test-tool string-list remove_duplicates a:a:a:a:a)" &&
+       test a:b = "$(test-tool string-list remove_duplicates a:b)" &&
+       test a:b = "$(test-tool string-list remove_duplicates a:a:b)" &&
+       test a:b = "$(test-tool string-list remove_duplicates a:b:b)" &&
+       test a:b:c = "$(test-tool string-list remove_duplicates a:b:c)" &&
+       test a:b:c = "$(test-tool string-list remove_duplicates a:a:b:c)" &&
+       test a:b:c = "$(test-tool string-list remove_duplicates a:b:b:c)" &&
+       test a:b:c = "$(test-tool string-list remove_duplicates a:b:c:c)" &&
+       test a:b:c = "$(test-tool string-list remove_duplicates a:a:b:b:c:c)" &&
+       test a:b:c = "$(test-tool string-list remove_duplicates a:a:a:b:b:b:c:c:c)"
 '
 
 test_done
index 50b31ffe756658dfa8ce435381ad7f48fee91462..67484502a007e3fed09fe381898bee52d21d07bb 100755 (executable)
@@ -18,7 +18,7 @@ test_expect_success 'ordered enumeration' '
        {
                echo20 append 88 44 aa 55 &&
                echo for_each_unique
-       } | test-sha1-array >actual &&
+       } | test-tool sha1-array >actual &&
        test_cmp expect actual
 '
 
@@ -28,7 +28,7 @@ test_expect_success 'ordered enumeration with duplicate suppression' '
                echo20 append 88 44 aa 55 &&
                echo20 append 88 44 aa 55 &&
                echo for_each_unique
-       } | test-sha1-array >actual &&
+       } | test-tool sha1-array >actual &&
        test_cmp expect actual
 '
 
@@ -36,7 +36,7 @@ test_expect_success 'lookup' '
        {
                echo20 append 88 44 aa 55 &&
                echo20 lookup 55
-       } | test-sha1-array >actual &&
+       } | test-tool sha1-array >actual &&
        n=$(cat actual) &&
        test "$n" -eq 1
 '
@@ -45,7 +45,7 @@ test_expect_success 'lookup non-existing entry' '
        {
                echo20 append 88 44 aa 55 &&
                echo20 lookup 33
-       } | test-sha1-array >actual &&
+       } | test-tool sha1-array >actual &&
        n=$(cat actual) &&
        test "$n" -lt 0
 '
@@ -55,7 +55,7 @@ test_expect_success 'lookup with duplicates' '
                echo20 append 88 44 aa 55 &&
                echo20 append 88 44 aa 55 &&
                echo20 lookup 55
-       } | test-sha1-array >actual &&
+       } | test-tool sha1-array >actual &&
        n=$(cat actual) &&
        test "$n" -ge 2 &&
        test "$n" -le 3
@@ -66,7 +66,7 @@ test_expect_success 'lookup non-existing entry with duplicates' '
                echo20 append 88 44 aa 55 &&
                echo20 append 88 44 aa 55 &&
                echo20 lookup 66
-       } | test-sha1-array >actual &&
+       } | test-tool sha1-array >actual &&
        n=$(cat actual) &&
        test "$n" -lt 0
 '
@@ -76,7 +76,7 @@ test_expect_success 'lookup with almost duplicate values' '
                echo "append 5555555555555555555555555555555555555555" &&
                echo "append 555555555555555555555555555555555555555f" &&
                echo20 lookup 55
-       } | test-sha1-array >actual &&
+       } | test-tool sha1-array >actual &&
        n=$(cat actual) &&
        test "$n" -eq 0
 '
@@ -85,7 +85,7 @@ test_expect_success 'lookup with single duplicate value' '
        {
                echo20 append 55 55 &&
                echo20 lookup 55
-       } | test-sha1-array >actual &&
+       } | test-tool sha1-array >actual &&
        n=$(cat actual) &&
        test "$n" -ge 0 &&
        test "$n" -le 1
index 7d6d21425f483c412bb6d42ea551aaf5eaef4aa0..91fa639c4a74ed69ed69ff7360728b2f1ab08a66 100755 (executable)
@@ -8,7 +8,7 @@ while read s1 s2 expect
 do
        test_expect_success "strcmp_offset($s1, $s2)" '
                echo "$expect" >expect &&
-               test-strcmp-offset "$s1" "$s2" >actual &&
+               test-tool strcmp-offset "$s1" "$s2" >actual &&
                test_cmp expect actual
        '
 done <<-EOF
index 991ed2a48dbf15fb4cb794a587ad900071391e11..23fbe6434abd3f05057d4916f70e5d5b30115b68 100755 (executable)
@@ -9,11 +9,11 @@ Verify wrappers and compatibility functions.
 . ./test-lib.sh
 
 test_expect_success 'character classes (isspace, isalpha etc.)' '
-       test-ctype
+       test-tool ctype
 '
 
 test_expect_success 'mktemp to nonexistent directory prints filename' '
-       test_must_fail test-mktemp doesnotexist/testXXXXXX 2>err &&
+       test_must_fail test-tool mktemp doesnotexist/testXXXXXX 2>err &&
        grep "doesnotexist/test" err
 '
 
@@ -21,7 +21,7 @@ test_expect_success POSIXPERM,SANITY 'mktemp to unwritable directory prints file
        mkdir cannotwrite &&
        chmod -w cannotwrite &&
        test_when_finished "chmod +w cannotwrite" &&
-       test_must_fail test-mktemp cannotwrite/testXXXXXX 2>err &&
+       test_must_fail test-tool mktemp cannotwrite/testXXXXXX 2>err &&
        grep "cannotwrite/test" err
 '
 
@@ -31,7 +31,7 @@ test_expect_success 'git_mkstemps_mode does not fail if fd 0 is not open' '
 
 test_expect_success 'check for a bug in the regex routines' '
        # if this test fails, re-build git with NO_REGEX=1
-       test-regex --bug
+       test-tool regex --bug
 '
 
 test_done
index adfd4f0b5eea1c0c438647d3d6567479acc5d495..4ae0995cd9140d3030da7d975c74ff3d9e55b039 100755 (executable)
@@ -8,13 +8,13 @@ cache-tree extension.
  . ./test-lib.sh
 
 cmp_cache_tree () {
-       test-dump-cache-tree | sed -e '/#(ref)/d' >actual &&
+       test-tool dump-cache-tree | sed -e '/#(ref)/d' >actual &&
        sed "s/$_x40/SHA/" <actual >filtered &&
        test_cmp "$1" filtered
 }
 
 # We don't bother with actually checking the SHA1:
-# test-dump-cache-tree already verifies that all existing data is
+# test-tool dump-cache-tree already verifies that all existing data is
 # correct.
 generate_expected_cache_tree_rec () {
        dir="$1${1:+/}" &&
@@ -47,7 +47,7 @@ test_cache_tree () {
 
 test_invalid_cache_tree () {
        printf "invalid                                  %s ()\n" "" "$@" >expect &&
-       test-dump-cache-tree |
+       test-tool dump-cache-tree |
        sed -n -e "s/[0-9]* subtrees//" -e '/#(ref)/d' -e '/^invalid /p' >actual &&
        test_cmp expect actual
 }
@@ -115,14 +115,14 @@ test_expect_success 'update-index invalidates cache-tree' '
 '
 
 test_expect_success 'write-tree establishes cache-tree' '
-       test-scrap-cache-tree &&
+       test-tool scrap-cache-tree &&
        git write-tree &&
        test_cache_tree
 '
 
-test_expect_success 'test-scrap-cache-tree works' '
+test_expect_success 'test-tool scrap-cache-tree works' '
        git read-tree HEAD &&
-       test-scrap-cache-tree &&
+       test-tool scrap-cache-tree &&
        test_no_cache_tree
 '
 
@@ -170,7 +170,7 @@ test_expect_success 'commit in child dir has cache-tree' '
 '
 
 test_expect_success 'reset --hard gives cache-tree' '
-       test-scrap-cache-tree &&
+       test-tool scrap-cache-tree &&
        git reset --hard &&
        test_cache_tree
 '
@@ -246,9 +246,9 @@ test_expect_success 'switching trees does not invalidate shared index' '
        git update-index --split-index &&
        >split &&
        git add split &&
-       test-dump-split-index .git/index | grep -v ^own >before &&
+       test-tool dump-split-index .git/index | grep -v ^own >before &&
        git commit -m "as-is" &&
-       test-dump-split-index .git/index | grep -v ^own >after &&
+       test-tool dump-split-index .git/index | grep -v ^own >after &&
        test_cmp before after
 '
 
index 410d5768ca11b1d7e322c135cf18f60f41685b68..f99529d83853e2c468b1c948f3ec4408a58fb919 100755 (executable)
@@ -9,172 +9,172 @@ tu="$TEST_DIRECTORY/t0110/url"
 # Note that only file: URLs should be allowed without a host
 
 test_expect_success 'url scheme' '
-       ! test-urlmatch-normalization "" &&
-       ! test-urlmatch-normalization "_" &&
-       ! test-urlmatch-normalization "scheme" &&
-       ! test-urlmatch-normalization "scheme:" &&
-       ! test-urlmatch-normalization "scheme:/" &&
-       ! test-urlmatch-normalization "scheme://" &&
-       ! test-urlmatch-normalization "file" &&
-       ! test-urlmatch-normalization "file:" &&
-       ! test-urlmatch-normalization "file:/" &&
-       test-urlmatch-normalization "file://" &&
-       ! test-urlmatch-normalization "://acme.co" &&
-       ! test-urlmatch-normalization "x_test://acme.co" &&
-       ! test-urlmatch-normalization "-test://acme.co" &&
-       ! test-urlmatch-normalization "0test://acme.co" &&
-       ! test-urlmatch-normalization "+test://acme.co" &&
-       ! test-urlmatch-normalization ".test://acme.co" &&
-       ! test-urlmatch-normalization "schem%6e://" &&
-       test-urlmatch-normalization "x-Test+v1.0://acme.co" &&
-       test "$(test-urlmatch-normalization -p "AbCdeF://x.Y")" = "abcdef://x.y/"
+       ! test-tool urlmatch-normalization "" &&
+       ! test-tool urlmatch-normalization "_" &&
+       ! test-tool urlmatch-normalization "scheme" &&
+       ! test-tool urlmatch-normalization "scheme:" &&
+       ! test-tool urlmatch-normalization "scheme:/" &&
+       ! test-tool urlmatch-normalization "scheme://" &&
+       ! test-tool urlmatch-normalization "file" &&
+       ! test-tool urlmatch-normalization "file:" &&
+       ! test-tool urlmatch-normalization "file:/" &&
+       test-tool urlmatch-normalization "file://" &&
+       ! test-tool urlmatch-normalization "://acme.co" &&
+       ! test-tool urlmatch-normalization "x_test://acme.co" &&
+       ! test-tool urlmatch-normalization "-test://acme.co" &&
+       ! test-tool urlmatch-normalization "0test://acme.co" &&
+       ! test-tool urlmatch-normalization "+test://acme.co" &&
+       ! test-tool urlmatch-normalization ".test://acme.co" &&
+       ! test-tool urlmatch-normalization "schem%6e://" &&
+       test-tool urlmatch-normalization "x-Test+v1.0://acme.co" &&
+       test "$(test-tool urlmatch-normalization -p "AbCdeF://x.Y")" = "abcdef://x.y/"
 '
 
 test_expect_success 'url authority' '
-       ! test-urlmatch-normalization "scheme://user:pass@" &&
-       ! test-urlmatch-normalization "scheme://?" &&
-       ! test-urlmatch-normalization "scheme://#" &&
-       ! test-urlmatch-normalization "scheme:///" &&
-       ! test-urlmatch-normalization "scheme://:" &&
-       ! test-urlmatch-normalization "scheme://:555" &&
-       test-urlmatch-normalization "file://user:pass@" &&
-       test-urlmatch-normalization "file://?" &&
-       test-urlmatch-normalization "file://#" &&
-       test-urlmatch-normalization "file:///" &&
-       test-urlmatch-normalization "file://:" &&
-       ! test-urlmatch-normalization "file://:555" &&
-       test-urlmatch-normalization "scheme://user:pass@host" &&
-       test-urlmatch-normalization "scheme://@host" &&
-       test-urlmatch-normalization "scheme://%00@host" &&
-       ! test-urlmatch-normalization "scheme://%%@host" &&
-       ! test-urlmatch-normalization "scheme://host_" &&
-       test-urlmatch-normalization "scheme://user:pass@host/" &&
-       test-urlmatch-normalization "scheme://@host/" &&
-       test-urlmatch-normalization "scheme://host/" &&
-       test-urlmatch-normalization "scheme://host?x" &&
-       test-urlmatch-normalization "scheme://host#x" &&
-       test-urlmatch-normalization "scheme://host/@" &&
-       test-urlmatch-normalization "scheme://host?@x" &&
-       test-urlmatch-normalization "scheme://host#@x" &&
-       test-urlmatch-normalization "scheme://[::1]" &&
-       test-urlmatch-normalization "scheme://[::1]/" &&
-       ! test-urlmatch-normalization "scheme://hos%41/" &&
-       test-urlmatch-normalization "scheme://[invalid....:/" &&
-       test-urlmatch-normalization "scheme://invalid....:]/" &&
-       ! test-urlmatch-normalization "scheme://invalid....:[/" &&
-       ! test-urlmatch-normalization "scheme://invalid....:["
+       ! test-tool urlmatch-normalization "scheme://user:pass@" &&
+       ! test-tool urlmatch-normalization "scheme://?" &&
+       ! test-tool urlmatch-normalization "scheme://#" &&
+       ! test-tool urlmatch-normalization "scheme:///" &&
+       ! test-tool urlmatch-normalization "scheme://:" &&
+       ! test-tool urlmatch-normalization "scheme://:555" &&
+       test-tool urlmatch-normalization "file://user:pass@" &&
+       test-tool urlmatch-normalization "file://?" &&
+       test-tool urlmatch-normalization "file://#" &&
+       test-tool urlmatch-normalization "file:///" &&
+       test-tool urlmatch-normalization "file://:" &&
+       ! test-tool urlmatch-normalization "file://:555" &&
+       test-tool urlmatch-normalization "scheme://user:pass@host" &&
+       test-tool urlmatch-normalization "scheme://@host" &&
+       test-tool urlmatch-normalization "scheme://%00@host" &&
+       ! test-tool urlmatch-normalization "scheme://%%@host" &&
+       ! test-tool urlmatch-normalization "scheme://host_" &&
+       test-tool urlmatch-normalization "scheme://user:pass@host/" &&
+       test-tool urlmatch-normalization "scheme://@host/" &&
+       test-tool urlmatch-normalization "scheme://host/" &&
+       test-tool urlmatch-normalization "scheme://host?x" &&
+       test-tool urlmatch-normalization "scheme://host#x" &&
+       test-tool urlmatch-normalization "scheme://host/@" &&
+       test-tool urlmatch-normalization "scheme://host?@x" &&
+       test-tool urlmatch-normalization "scheme://host#@x" &&
+       test-tool urlmatch-normalization "scheme://[::1]" &&
+       test-tool urlmatch-normalization "scheme://[::1]/" &&
+       ! test-tool urlmatch-normalization "scheme://hos%41/" &&
+       test-tool urlmatch-normalization "scheme://[invalid....:/" &&
+       test-tool urlmatch-normalization "scheme://invalid....:]/" &&
+       ! test-tool urlmatch-normalization "scheme://invalid....:[/" &&
+       ! test-tool urlmatch-normalization "scheme://invalid....:["
 '
 
 test_expect_success 'url port checks' '
-       test-urlmatch-normalization "xyz://q@some.host:" &&
-       test-urlmatch-normalization "xyz://q@some.host:456/" &&
-       ! test-urlmatch-normalization "xyz://q@some.host:0" &&
-       ! test-urlmatch-normalization "xyz://q@some.host:0000000" &&
-       test-urlmatch-normalization "xyz://q@some.host:0000001?" &&
-       test-urlmatch-normalization "xyz://q@some.host:065535#" &&
-       test-urlmatch-normalization "xyz://q@some.host:65535" &&
-       ! test-urlmatch-normalization "xyz://q@some.host:65536" &&
-       ! test-urlmatch-normalization "xyz://q@some.host:99999" &&
-       ! test-urlmatch-normalization "xyz://q@some.host:100000" &&
-       ! test-urlmatch-normalization "xyz://q@some.host:100001" &&
-       test-urlmatch-normalization "http://q@some.host:80" &&
-       test-urlmatch-normalization "https://q@some.host:443" &&
-       test-urlmatch-normalization "http://q@some.host:80/" &&
-       test-urlmatch-normalization "https://q@some.host:443?" &&
-       ! test-urlmatch-normalization "http://q@:8008" &&
-       ! test-urlmatch-normalization "http://:8080" &&
-       ! test-urlmatch-normalization "http://:" &&
-       test-urlmatch-normalization "xyz://q@some.host:456/" &&
-       test-urlmatch-normalization "xyz://[::1]:456/" &&
-       test-urlmatch-normalization "xyz://[::1]:/" &&
-       ! test-urlmatch-normalization "xyz://[::1]:000/" &&
-       ! test-urlmatch-normalization "xyz://[::1]:0%300/" &&
-       ! test-urlmatch-normalization "xyz://[::1]:0x80/" &&
-       ! test-urlmatch-normalization "xyz://[::1]:4294967297/" &&
-       ! test-urlmatch-normalization "xyz://[::1]:030f/"
+       test-tool urlmatch-normalization "xyz://q@some.host:" &&
+       test-tool urlmatch-normalization "xyz://q@some.host:456/" &&
+       ! test-tool urlmatch-normalization "xyz://q@some.host:0" &&
+       ! test-tool urlmatch-normalization "xyz://q@some.host:0000000" &&
+       test-tool urlmatch-normalization "xyz://q@some.host:0000001?" &&
+       test-tool urlmatch-normalization "xyz://q@some.host:065535#" &&
+       test-tool urlmatch-normalization "xyz://q@some.host:65535" &&
+       ! test-tool urlmatch-normalization "xyz://q@some.host:65536" &&
+       ! test-tool urlmatch-normalization "xyz://q@some.host:99999" &&
+       ! test-tool urlmatch-normalization "xyz://q@some.host:100000" &&
+       ! test-tool urlmatch-normalization "xyz://q@some.host:100001" &&
+       test-tool urlmatch-normalization "http://q@some.host:80" &&
+       test-tool urlmatch-normalization "https://q@some.host:443" &&
+       test-tool urlmatch-normalization "http://q@some.host:80/" &&
+       test-tool urlmatch-normalization "https://q@some.host:443?" &&
+       ! test-tool urlmatch-normalization "http://q@:8008" &&
+       ! test-tool urlmatch-normalization "http://:8080" &&
+       ! test-tool urlmatch-normalization "http://:" &&
+       test-tool urlmatch-normalization "xyz://q@some.host:456/" &&
+       test-tool urlmatch-normalization "xyz://[::1]:456/" &&
+       test-tool urlmatch-normalization "xyz://[::1]:/" &&
+       ! test-tool urlmatch-normalization "xyz://[::1]:000/" &&
+       ! test-tool urlmatch-normalization "xyz://[::1]:0%300/" &&
+       ! test-tool urlmatch-normalization "xyz://[::1]:0x80/" &&
+       ! test-tool urlmatch-normalization "xyz://[::1]:4294967297/" &&
+       ! test-tool urlmatch-normalization "xyz://[::1]:030f/"
 '
 
 test_expect_success 'url port normalization' '
-       test "$(test-urlmatch-normalization -p "http://x:800")" = "http://x:800/" &&
-       test "$(test-urlmatch-normalization -p "http://x:0800")" = "http://x:800/" &&
-       test "$(test-urlmatch-normalization -p "http://x:00000800")" = "http://x:800/" &&
-       test "$(test-urlmatch-normalization -p "http://x:065535")" = "http://x:65535/" &&
-       test "$(test-urlmatch-normalization -p "http://x:1")" = "http://x:1/" &&
-       test "$(test-urlmatch-normalization -p "http://x:80")" = "http://x/" &&
-       test "$(test-urlmatch-normalization -p "http://x:080")" = "http://x/" &&
-       test "$(test-urlmatch-normalization -p "http://x:000000080")" = "http://x/" &&
-       test "$(test-urlmatch-normalization -p "https://x:443")" = "https://x/" &&
-       test "$(test-urlmatch-normalization -p "https://x:0443")" = "https://x/" &&
-       test "$(test-urlmatch-normalization -p "https://x:000000443")" = "https://x/"
+       test "$(test-tool urlmatch-normalization -p "http://x:800")" = "http://x:800/" &&
+       test "$(test-tool urlmatch-normalization -p "http://x:0800")" = "http://x:800/" &&
+       test "$(test-tool urlmatch-normalization -p "http://x:00000800")" = "http://x:800/" &&
+       test "$(test-tool urlmatch-normalization -p "http://x:065535")" = "http://x:65535/" &&
+       test "$(test-tool urlmatch-normalization -p "http://x:1")" = "http://x:1/" &&
+       test "$(test-tool urlmatch-normalization -p "http://x:80")" = "http://x/" &&
+       test "$(test-tool urlmatch-normalization -p "http://x:080")" = "http://x/" &&
+       test "$(test-tool urlmatch-normalization -p "http://x:000000080")" = "http://x/" &&
+       test "$(test-tool urlmatch-normalization -p "https://x:443")" = "https://x/" &&
+       test "$(test-tool urlmatch-normalization -p "https://x:0443")" = "https://x/" &&
+       test "$(test-tool urlmatch-normalization -p "https://x:000000443")" = "https://x/"
 '
 
 test_expect_success 'url general escapes' '
-       ! test-urlmatch-normalization "http://x.y?%fg" &&
-       test "$(test-urlmatch-normalization -p "X://W/%7e%41^%3a")" = "x://w/~A%5E%3A" &&
-       test "$(test-urlmatch-normalization -p "X://W/:/?#[]@")" = "x://w/:/?#[]@" &&
-       test "$(test-urlmatch-normalization -p "X://W/$&()*+,;=")" = "x://w/$&()*+,;=" &&
-       test "$(test-urlmatch-normalization -p "X://W/'\''")" = "x://w/'\''" &&
-       test "$(test-urlmatch-normalization -p "X://W?'\!'")" = "x://w/?'\!'"
+       ! test-tool urlmatch-normalization "http://x.y?%fg" &&
+       test "$(test-tool urlmatch-normalization -p "X://W/%7e%41^%3a")" = "x://w/~A%5E%3A" &&
+       test "$(test-tool urlmatch-normalization -p "X://W/:/?#[]@")" = "x://w/:/?#[]@" &&
+       test "$(test-tool urlmatch-normalization -p "X://W/$&()*+,;=")" = "x://w/$&()*+,;=" &&
+       test "$(test-tool urlmatch-normalization -p "X://W/'\''")" = "x://w/'\''" &&
+       test "$(test-tool urlmatch-normalization -p "X://W?'\!'")" = "x://w/?'\!'"
 '
 
 test_expect_success !MINGW 'url high-bit escapes' '
-       test "$(test-urlmatch-normalization -p "$(cat "$tu-1")")" = "x://q/%01%02%03%04%05%06%07%08%0E%0F%10%11%12" &&
-       test "$(test-urlmatch-normalization -p "$(cat "$tu-2")")" = "x://q/%13%14%15%16%17%18%19%1B%1C%1D%1E%1F%7F" &&
-       test "$(test-urlmatch-normalization -p "$(cat "$tu-3")")" = "x://q/%80%81%82%83%84%85%86%87%88%89%8A%8B%8C%8D%8E%8F" &&
-       test "$(test-urlmatch-normalization -p "$(cat "$tu-4")")" = "x://q/%90%91%92%93%94%95%96%97%98%99%9A%9B%9C%9D%9E%9F" &&
-       test "$(test-urlmatch-normalization -p "$(cat "$tu-5")")" = "x://q/%A0%A1%A2%A3%A4%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF" &&
-       test "$(test-urlmatch-normalization -p "$(cat "$tu-6")")" = "x://q/%B0%B1%B2%B3%B4%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF" &&
-       test "$(test-urlmatch-normalization -p "$(cat "$tu-7")")" = "x://q/%C0%C1%C2%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF" &&
-       test "$(test-urlmatch-normalization -p "$(cat "$tu-8")")" = "x://q/%D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC%DD%DE%DF" &&
-       test "$(test-urlmatch-normalization -p "$(cat "$tu-9")")" = "x://q/%E0%E1%E2%E3%E4%E5%E6%E7%E8%E9%EA%EB%EC%ED%EE%EF" &&
-       test "$(test-urlmatch-normalization -p "$(cat "$tu-10")")" = "x://q/%F0%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE%FF"
+       test "$(test-tool urlmatch-normalization -p "$(cat "$tu-1")")" = "x://q/%01%02%03%04%05%06%07%08%0E%0F%10%11%12" &&
+       test "$(test-tool urlmatch-normalization -p "$(cat "$tu-2")")" = "x://q/%13%14%15%16%17%18%19%1B%1C%1D%1E%1F%7F" &&
+       test "$(test-tool urlmatch-normalization -p "$(cat "$tu-3")")" = "x://q/%80%81%82%83%84%85%86%87%88%89%8A%8B%8C%8D%8E%8F" &&
+       test "$(test-tool urlmatch-normalization -p "$(cat "$tu-4")")" = "x://q/%90%91%92%93%94%95%96%97%98%99%9A%9B%9C%9D%9E%9F" &&
+       test "$(test-tool urlmatch-normalization -p "$(cat "$tu-5")")" = "x://q/%A0%A1%A2%A3%A4%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF" &&
+       test "$(test-tool urlmatch-normalization -p "$(cat "$tu-6")")" = "x://q/%B0%B1%B2%B3%B4%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF" &&
+       test "$(test-tool urlmatch-normalization -p "$(cat "$tu-7")")" = "x://q/%C0%C1%C2%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF" &&
+       test "$(test-tool urlmatch-normalization -p "$(cat "$tu-8")")" = "x://q/%D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC%DD%DE%DF" &&
+       test "$(test-tool urlmatch-normalization -p "$(cat "$tu-9")")" = "x://q/%E0%E1%E2%E3%E4%E5%E6%E7%E8%E9%EA%EB%EC%ED%EE%EF" &&
+       test "$(test-tool urlmatch-normalization -p "$(cat "$tu-10")")" = "x://q/%F0%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE%FF"
 '
 
 test_expect_success 'url utf-8 escapes' '
-       test "$(test-urlmatch-normalization -p "$(cat "$tu-11")")" = "x://q/%C2%80%DF%BF%E0%A0%80%EF%BF%BD%F0%90%80%80%F0%AF%BF%BD"
+       test "$(test-tool urlmatch-normalization -p "$(cat "$tu-11")")" = "x://q/%C2%80%DF%BF%E0%A0%80%EF%BF%BD%F0%90%80%80%F0%AF%BF%BD"
 '
 
 test_expect_success 'url username/password escapes' '
-       test "$(test-urlmatch-normalization -p "x://%41%62(^):%70+d@foo")" = "x://Ab(%5E):p+d@foo/"
+       test "$(test-tool urlmatch-normalization -p "x://%41%62(^):%70+d@foo")" = "x://Ab(%5E):p+d@foo/"
 '
 
 test_expect_success 'url normalized lengths' '
-       test "$(test-urlmatch-normalization -l "Http://%4d%65:%4d^%70@The.Host")" = 25 &&
-       test "$(test-urlmatch-normalization -l "http://%41:%42@x.y/%61/")" = 17 &&
-       test "$(test-urlmatch-normalization -l "http://@x.y/^")" = 15
+       test "$(test-tool urlmatch-normalization -l "Http://%4d%65:%4d^%70@The.Host")" = 25 &&
+       test "$(test-tool urlmatch-normalization -l "http://%41:%42@x.y/%61/")" = 17 &&
+       test "$(test-tool urlmatch-normalization -l "http://@x.y/^")" = 15
 '
 
 test_expect_success 'url . and .. segments' '
-       test "$(test-urlmatch-normalization -p "x://y/.")" = "x://y/" &&
-       test "$(test-urlmatch-normalization -p "x://y/./")" = "x://y/" &&
-       test "$(test-urlmatch-normalization -p "x://y/a/.")" = "x://y/a" &&
-       test "$(test-urlmatch-normalization -p "x://y/a/./")" = "x://y/a/" &&
-       test "$(test-urlmatch-normalization -p "x://y/.?")" = "x://y/?" &&
-       test "$(test-urlmatch-normalization -p "x://y/./?")" = "x://y/?" &&
-       test "$(test-urlmatch-normalization -p "x://y/a/.?")" = "x://y/a?" &&
-       test "$(test-urlmatch-normalization -p "x://y/a/./?")" = "x://y/a/?" &&
-       test "$(test-urlmatch-normalization -p "x://y/a/./b/.././../c")" = "x://y/c" &&
-       test "$(test-urlmatch-normalization -p "x://y/a/./b/../.././c/")" = "x://y/c/" &&
-       test "$(test-urlmatch-normalization -p "x://y/a/./b/.././../c/././.././.")" = "x://y/" &&
-       ! test-urlmatch-normalization "x://y/a/./b/.././../c/././.././.." &&
-       test "$(test-urlmatch-normalization -p "x://y/a/./?/././..")" = "x://y/a/?/././.." &&
-       test "$(test-urlmatch-normalization -p "x://y/%2e/")" = "x://y/" &&
-       test "$(test-urlmatch-normalization -p "x://y/%2E/")" = "x://y/" &&
-       test "$(test-urlmatch-normalization -p "x://y/a/%2e./")" = "x://y/" &&
-       test "$(test-urlmatch-normalization -p "x://y/b/.%2E/")" = "x://y/" &&
-       test "$(test-urlmatch-normalization -p "x://y/c/%2e%2E/")" = "x://y/"
+       test "$(test-tool urlmatch-normalization -p "x://y/.")" = "x://y/" &&
+       test "$(test-tool urlmatch-normalization -p "x://y/./")" = "x://y/" &&
+       test "$(test-tool urlmatch-normalization -p "x://y/a/.")" = "x://y/a" &&
+       test "$(test-tool urlmatch-normalization -p "x://y/a/./")" = "x://y/a/" &&
+       test "$(test-tool urlmatch-normalization -p "x://y/.?")" = "x://y/?" &&
+       test "$(test-tool urlmatch-normalization -p "x://y/./?")" = "x://y/?" &&
+       test "$(test-tool urlmatch-normalization -p "x://y/a/.?")" = "x://y/a?" &&
+       test "$(test-tool urlmatch-normalization -p "x://y/a/./?")" = "x://y/a/?" &&
+       test "$(test-tool urlmatch-normalization -p "x://y/a/./b/.././../c")" = "x://y/c" &&
+       test "$(test-tool urlmatch-normalization -p "x://y/a/./b/../.././c/")" = "x://y/c/" &&
+       test "$(test-tool urlmatch-normalization -p "x://y/a/./b/.././../c/././.././.")" = "x://y/" &&
+       ! test-tool urlmatch-normalization "x://y/a/./b/.././../c/././.././.." &&
+       test "$(test-tool urlmatch-normalization -p "x://y/a/./?/././..")" = "x://y/a/?/././.." &&
+       test "$(test-tool urlmatch-normalization -p "x://y/%2e/")" = "x://y/" &&
+       test "$(test-tool urlmatch-normalization -p "x://y/%2E/")" = "x://y/" &&
+       test "$(test-tool urlmatch-normalization -p "x://y/a/%2e./")" = "x://y/" &&
+       test "$(test-tool urlmatch-normalization -p "x://y/b/.%2E/")" = "x://y/" &&
+       test "$(test-tool urlmatch-normalization -p "x://y/c/%2e%2E/")" = "x://y/"
 '
 
 # http://@foo specifies an empty user name but does not specify a password
 # http://foo  specifies neither a user name nor a password
 # So they should not be equivalent
 test_expect_success 'url equivalents' '
-       test-urlmatch-normalization "httP://x" "Http://X/" &&
-       test-urlmatch-normalization "Http://%4d%65:%4d^%70@The.Host" "hTTP://Me:%4D^p@the.HOST:80/" &&
-       ! test-urlmatch-normalization "https://@x.y/^" "httpS://x.y:443/^" &&
-       test-urlmatch-normalization "https://@x.y/^" "httpS://@x.y:0443/^" &&
-       test-urlmatch-normalization "https://@x.y/^/../abc" "httpS://@x.y:0443/abc" &&
-       test-urlmatch-normalization "https://@x.y/^/.." "httpS://@x.y:0443/"
+       test-tool urlmatch-normalization "httP://x" "Http://X/" &&
+       test-tool urlmatch-normalization "Http://%4d%65:%4d^%70@The.Host" "hTTP://Me:%4D^p@the.HOST:80/" &&
+       ! test-tool urlmatch-normalization "https://@x.y/^" "httpS://x.y:443/^" &&
+       test-tool urlmatch-normalization "https://@x.y/^" "httpS://@x.y:0443/^" &&
+       test-tool urlmatch-normalization "https://@x.y/^/../abc" "httpS://@x.y:0443/abc" &&
+       test-tool urlmatch-normalization "https://@x.y/^/.." "httpS://@x.y:0443/"
 '
 
 test_done
index b19f3326946203409fe0e428b9fc73d34134d756..2ac3b940c611db08fd48e5782db13d2f8f1d48ec 100755 (executable)
@@ -282,7 +282,7 @@ test_expect_success "--batch-check with multiple sha1s gives correct format" '
 '
 
 test_expect_success 'setup blobs which are likely to delta' '
-       test-genrandom foo 10240 >foo &&
+       test-tool genrandom foo 10240 >foo &&
        { cat foo; echo plus; } >foo-plus &&
        git add foo foo-plus &&
        git commit -m foo &&
index c167f606ca7b8c1628ac8d00507d50f032278730..0c6f48f3024c81de765a8acb489e2d5e3ec42a56 100755 (executable)
@@ -15,8 +15,11 @@ test_description='sparse checkout tests
 . "$TEST_DIRECTORY"/lib-read-tree.sh
 
 test_expect_success 'setup' '
+       test_commit init &&
+       echo modified >>init.t &&
+
        cat >expected <<-EOF &&
-       100644 77f0ba1734ed79d12881f81b36ee134de6a3327b 0       init.t
+       100644 $(git hash-object init.t) 0      init.t
        100644 $EMPTY_BLOB 0    sub/added
        100644 $EMPTY_BLOB 0    sub/addedtoo
        100644 $EMPTY_BLOB 0    subsub/added
@@ -28,8 +31,6 @@ test_expect_success 'setup' '
        H subsub/added
        EOF
 
-       test_commit init &&
-       echo modified >>init.t &&
        mkdir sub subsub &&
        touch sub/added sub/addedtoo subsub/added &&
        git add init.t sub/added sub/addedtoo subsub/added &&
index 6fd264cff0d6de1961656c2cd1193d8ce37e9a1f..f9eb143f43420b0e2f2b864b4f83f78de7886a7b 100755 (executable)
@@ -103,9 +103,9 @@ test_expect_success 'packsize limit' '
                # mid1 and mid2 will fit within 256k limit but
                # appending mid3 will bust the limit and will
                # result in a separate packfile.
-               test-genrandom "a" $(( 66 * 1024 )) >mid1 &&
-               test-genrandom "b" $(( 80 * 1024 )) >mid2 &&
-               test-genrandom "c" $(( 128 * 1024 )) >mid3 &&
+               test-tool genrandom "a" $(( 66 * 1024 )) >mid1 &&
+               test-tool genrandom "b" $(( 80 * 1024 )) >mid2 &&
+               test-tool genrandom "c" $(( 128 * 1024 )) >mid3 &&
                git add mid1 mid2 mid3 &&
 
                count=0
index 4f8e6f5fde3295cc91d2feb1fd85fa007e56016c..e95b1e67da7089a434fc5e8d687b2e2d5e39da01 100755 (executable)
@@ -914,7 +914,7 @@ test_expect_success 'get --expiry-date' '
        invalid1 = "abc"
        EOF
        cat >expect <<-EOF &&
-       $(test-date timestamp $rel)
+       $(test-tool date timestamp $rel)
        1275666415
        1510441871
        1510348087
@@ -1587,10 +1587,10 @@ test_expect_success '--show-origin stdin with file include' '
 '
 
 test_expect_success !MINGW '--show-origin blob' '
-       cat >expect <<-\EOF &&
-               blob:a9d9f9e555b5c6f07cbe09d3f06fe3df11e09c08   user.custom=true
-       EOF
        blob=$(git hash-object -w "$CUSTOM_CONFIG_FILE") &&
+       cat >expect <<-EOF &&
+               blob:$blob      user.custom=true
+       EOF
        git config --blob=$blob --show-origin --list >output &&
        test_cmp expect output
 '
index f5422f1d33f5eac98e6f56ec4bf05f3f8d4c8be2..335d3f3211aa874fd3a8e0d0006dd9fc53a4e589 100755 (executable)
@@ -54,7 +54,7 @@ test_expect_success SETFACL 'Setup test repo' '
 
 test_expect_success SETFACL 'Objects creation does not break ACLs with restrictive umask' '
        # SHA1 for empty blob
-       check_perms_and_acl .git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
+       check_perms_and_acl .git/objects/$(echo $EMPTY_BLOB | sed -e "s,^\(..\),\1/,")
 '
 
 test_expect_success SETFACL 'git gc does not break ACLs with restrictive umask' '
index d9d2f545a4ed735e02f7d5cd6ceee7d873fdec94..f035ee40a313ae25a13bdb6a838eed3b34fd5f9d 100755 (executable)
@@ -224,7 +224,7 @@ test_expect_success 'conditional include, early config reading' '
                echo "[includeIf \"gitdir:foo/\"]path=bar6" >>.git/config &&
                echo "[test]six=6" >.git/bar6 &&
                echo 6 >expect &&
-               test-config read_early_config test.six >actual &&
+               test-tool config read_early_config test.six >actual &&
                test_cmp expect actual
        )
 '
index bafed5c9b88481992ca6cf4cd6c13596c7baf16b..3e00d1af01fb771bd3fd26dcb265a3d80da37934 100755 (executable)
@@ -18,7 +18,7 @@ check_config () {
        then
                printf "%s\n" "$@"
        fi >expect &&
-       test_expect_code $expect_code test-config "$op" "$key" >actual &&
+       test_expect_code $expect_code test-tool config "$op" "$key" >actual &&
        test_cmp expect actual
 }
 
@@ -125,7 +125,7 @@ test_expect_success 'find string value for a key' '
 '
 
 test_expect_success 'check line error when NULL string is queried' '
-       test_expect_code 128 test-config get_string case.foo 2>result &&
+       test_expect_code 128 test-tool config get_string case.foo 2>result &&
        test_i18ngrep "fatal: .*case\.foo.*\.git/config.*line 7" result
 '
 
@@ -155,13 +155,13 @@ test_expect_success 'find value from a configset' '
                baz = ball
        EOF
        echo silk >expect &&
-       test-config configset_get_value my.new config2 .git/config >actual &&
+       test-tool config configset_get_value my.new config2 .git/config >actual &&
        test_cmp expect actual
 '
 
 test_expect_success 'find value with highest priority from a configset' '
        echo hask >expect &&
-       test-config configset_get_value case.baz config2 .git/config >actual &&
+       test-tool config configset_get_value case.baz config2 .git/config >actual &&
        test_cmp expect actual
 '
 
@@ -173,20 +173,20 @@ test_expect_success 'find value_list for a key from a configset' '
        lama
        ball
        EOF
-       test-config configset_get_value case.baz config2 .git/config >actual &&
+       test-tool config configset_get_value case.baz config2 .git/config >actual &&
        test_cmp expect actual
 '
 
 test_expect_success 'proper error on non-existent files' '
        echo "Error (-1) reading configuration file non-existent-file." >expect &&
-       test_expect_code 2 test-config configset_get_value foo.bar non-existent-file 2>actual &&
+       test_expect_code 2 test-tool config configset_get_value foo.bar non-existent-file 2>actual &&
        test_cmp expect actual
 '
 
 test_expect_success 'proper error on directory "files"' '
        echo "Error (-1) reading configuration file a-directory." >expect &&
        mkdir a-directory &&
-       test_expect_code 2 test-config configset_get_value foo.bar a-directory 2>output &&
+       test_expect_code 2 test-tool config configset_get_value foo.bar a-directory 2>output &&
        grep "^warning:" output &&
        grep "^Error" output >actual &&
        test_cmp expect actual
@@ -196,7 +196,7 @@ test_expect_success POSIXPERM,SANITY 'proper error on non-accessible files' '
        chmod -r .git/config &&
        test_when_finished "chmod +r .git/config" &&
        echo "Error (-1) reading configuration file .git/config." >expect &&
-       test_expect_code 2 test-config configset_get_value foo.bar .git/config 2>output &&
+       test_expect_code 2 test-tool config configset_get_value foo.bar .git/config 2>output &&
        grep "^warning:" output &&
        grep "^Error" output >actual &&
        test_cmp expect actual
@@ -207,14 +207,14 @@ test_expect_success 'proper error on error in default config files' '
        test_when_finished "mv .git/config.old .git/config" &&
        echo "[" >>.git/config &&
        echo "fatal: bad config line 34 in file .git/config" >expect &&
-       test_expect_code 128 test-config get_value foo.bar 2>actual &&
+       test_expect_code 128 test-tool config get_value foo.bar 2>actual &&
        test_i18ncmp expect actual
 '
 
 test_expect_success 'proper error on error in custom config files' '
        echo "[" >>syntax-error &&
        echo "fatal: bad config line 1 in file syntax-error" >expect &&
-       test_expect_code 128 test-config configset_get_value foo.bar syntax-error 2>actual &&
+       test_expect_code 128 test-tool config configset_get_value foo.bar syntax-error 2>actual &&
        test_i18ncmp expect actual
 '
 
@@ -267,7 +267,7 @@ test_expect_success 'iteration shows correct origins' '
        name=
        scope=cmdline
        EOF
-       GIT_CONFIG_PARAMETERS=$cmdline_config test-config iterate >actual &&
+       GIT_CONFIG_PARAMETERS=$cmdline_config test-tool config iterate >actual &&
        test_cmp expect actual
 '
 
index 3dda215e8e2f37c049a3169cecdb3e43ddea5dfb..413642aa5672800d1b7be448bc97d175add07ee4 100755 (executable)
@@ -6,7 +6,7 @@ test_description='Test read_early_config()'
 
 test_expect_success 'read early config' '
        test_config early.config correct &&
-       test-config read_early_config early.config >output &&
+       test-tool config read_early_config early.config >output &&
        test correct = "$(cat output)"
 '
 
@@ -15,7 +15,7 @@ test_expect_success 'in a sub-directory' '
        mkdir -p sub &&
        (
                cd sub &&
-               test-config read_early_config early.config
+               test-tool config read_early_config early.config
        ) >output &&
        test sub = "$(cat output)"
 '
@@ -27,7 +27,7 @@ test_expect_success 'ceiling' '
                GIT_CEILING_DIRECTORIES="$PWD" &&
                export GIT_CEILING_DIRECTORIES &&
                cd sub &&
-               test-config read_early_config early.config
+               test-tool config read_early_config early.config
        ) >output &&
        test -z "$(cat output)"
 '
@@ -42,7 +42,7 @@ test_expect_success 'ceiling #2' '
                GIT_CEILING_DIRECTORIES="$PWD" &&
                export GIT_CEILING_DIRECTORIES XDG_CONFIG_HOME &&
                cd sub &&
-               test-config read_early_config early.config
+               test-tool config read_early_config early.config
        ) >output &&
        test xdg = "$(cat output)"
 '
@@ -54,7 +54,7 @@ test_expect_success 'read config file in right order' '
        (
                cd foo &&
                echo "[test]source = repo" >>.git/config &&
-               GIT_CONFIG_PARAMETERS=$cmdline_config test-config \
+               GIT_CONFIG_PARAMETERS=$cmdline_config test-tool config \
                        read_early_config test.source >actual &&
                cat >expected <<-\EOF &&
                home
@@ -71,7 +71,7 @@ test_with_config () {
        (
                cd throwaway &&
                echo "$*" >.git/config &&
-               test-config read_early_config early.config
+               test-tool config read_early_config early.config
        )
 }
 
index e8115df5bad8d9ef46542cfd3c96c32da0bfa4ad..a74c38b5fb22a6d274c26ed008c6bec355801e34 100755 (executable)
@@ -4,7 +4,7 @@ test_description='test main ref store api'
 
 . ./test-lib.sh
 
-RUN="test-ref-store main"
+RUN="test-tool ref-store main"
 
 test_expect_success 'pack_refs(PACK_REFS_ALL | PACK_REFS_PRUNE)' '
        test_commit one &&
@@ -45,7 +45,7 @@ test_expect_success 'rename_refs(master, new-master)' '
 '
 
 test_expect_success 'for_each_ref(refs/heads/)' '
-       $RUN for-each-ref refs/heads/ | cut -c 42- >actual &&
+       $RUN for-each-ref refs/heads/ | cut -d" " -f 2- >actual &&
        cat >expected <<-\EOF &&
        master 0x0
        new-master 0x0
@@ -71,7 +71,7 @@ test_expect_success 'verify_ref(new-master)' '
 '
 
 test_expect_success 'for_each_reflog()' '
-       $RUN for-each-reflog | sort | cut -c 42- >actual &&
+       $RUN for-each-reflog | sort -k2 | cut -c 42- >actual &&
        cat >expected <<-\EOF &&
        HEAD 0x1
        refs/heads/master 0x0
index c32d4cc4652a4496ce8fa6aa1c10c797ae7d760a..e093782cc37c495a122eb8676797b1988b828c29 100755 (executable)
@@ -4,7 +4,7 @@ test_description='test submodule ref store api'
 
 . ./test-lib.sh
 
-RUN="test-ref-store submodule:sub"
+RUN="test-tool ref-store submodule:sub"
 
 test_expect_success 'setup' '
        git init sub &&
index 8842d0329fb7947e811d4ffccff3bba9e8885d5d..2211f9831fb07f933c8c3f0c7cfd89cc5512c253 100755 (executable)
@@ -4,8 +4,8 @@ test_description='test worktree ref store api'
 
 . ./test-lib.sh
 
-RWT="test-ref-store worktree:wt"
-RMAIN="test-ref-store worktree:main"
+RWT="test-tool ref-store worktree:wt"
+RMAIN="test-tool ref-store worktree:main"
 
 test_expect_success 'setup' '
        test_commit first &&
index 6ac7734d79be21a82feeadff10064bb4ca7ad47b..596907758d5d47ae8026098a2ce4acd8c01df6aa 100755 (executable)
@@ -10,6 +10,7 @@ test_expect_success 'setup' '
        git commit -m one
 '
 
+commit=$(git rev-parse --short HEAD)
 cat >expect <<'EOF'
 Reflog: HEAD@{0} (C O Mitter <committer@example.com>)
 Reflog message: commit (initial): one
@@ -20,8 +21,8 @@ test_expect_success 'log -g shows reflog headers' '
        test_cmp expect actual
 '
 
-cat >expect <<'EOF'
-e46513e HEAD@{0}: commit (initial): one
+cat >expect <<EOF
+$commit HEAD@{0}: commit (initial): one
 EOF
 test_expect_success 'oneline reflog format' '
        git log -g -1 --oneline >actual &&
@@ -33,8 +34,8 @@ test_expect_success 'reflog default format' '
        test_cmp expect actual
 '
 
-cat >expect <<'EOF'
-commit e46513e
+cat >expect <<EOF
+commit $commit
 Reflog: HEAD@{0} (C O Mitter <committer@example.com>)
 Reflog message: commit (initial): one
 Author: A U Thor <author@example.com>
@@ -56,8 +57,8 @@ test_expect_success 'using @{now} syntax shows reflog date (multiline)' '
        test_cmp expect actual
 '
 
-cat >expect <<'EOF'
-e46513e HEAD@{Thu Apr 7 15:13:13 2005 -0700}: commit (initial): one
+cat >expect <<EOF
+$commit HEAD@{Thu Apr 7 15:13:13 2005 -0700}: commit (initial): one
 EOF
 test_expect_success 'using @{now} syntax shows reflog date (oneline)' '
        git log -g -1 --oneline HEAD@{now} >actual &&
@@ -82,8 +83,8 @@ test_expect_success 'using --date= shows reflog date (multiline)' '
        test_cmp expect actual
 '
 
-cat >expect <<'EOF'
-e46513e HEAD@{Thu Apr 7 15:13:13 2005 -0700}: commit (initial): one
+cat >expect <<EOF
+$commit HEAD@{Thu Apr 7 15:13:13 2005 -0700}: commit (initial): one
 EOF
 test_expect_success 'using --date= shows reflog date (oneline)' '
        git log -g -1 --oneline --date=default >actual &&
@@ -109,8 +110,8 @@ test_expect_success 'log.date does not invoke "--date" magic (multiline)' '
        test_cmp expect actual
 '
 
-cat >expect <<'EOF'
-e46513e HEAD@{0}: commit (initial): one
+cat >expect <<EOF
+$commit HEAD@{0}: commit (initial): one
 EOF
 test_expect_success 'log.date does not invoke "--date" magic (oneline)' '
        test_config log.date raw &&
index b06210ec5e8ffa30b59314b1c79ebc9bdb8f6476..9c0bc6525034021a1947d07faec84570d0dd629a 100755 (executable)
@@ -341,7 +341,7 @@ test_expect_success 'make_relative_path handles double slashes in GIT_DIR' '
 
 test_expect_success 'relative $GIT_WORK_TREE and git subprocesses' '
        GIT_DIR=repo.git GIT_WORK_TREE=repo.git/work \
-       test-subprocess --setup-work-tree rev-parse --show-toplevel >actual &&
+       test-tool subprocess --setup-work-tree rev-parse --show-toplevel >actual &&
        echo "$(pwd)/repo.git/work" >expected &&
        test_cmp expected actual
 '
@@ -360,7 +360,7 @@ test_expect_success 'GIT_DIR set (1)' '
        (
                cd work &&
                GIT_DIR=../gitfile git rev-parse --git-common-dir >actual &&
-               test-path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect &&
+               test-tool path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect &&
                test_cmp expect actual
        )
 '
@@ -371,7 +371,7 @@ test_expect_success 'GIT_DIR set (2)' '
        (
                cd work &&
                GIT_DIR=../gitfile git rev-parse --git-common-dir >actual &&
-               test-path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect &&
+               test-tool path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect &&
                test_cmp expect actual
        )
 '
@@ -382,7 +382,7 @@ test_expect_success 'Auto discovery' '
        (
                cd work &&
                git rev-parse --git-common-dir >actual &&
-               test-path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect &&
+               test-tool path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect &&
                test_cmp expect actual &&
                echo haha >data1 &&
                git add data1 &&
@@ -400,7 +400,7 @@ test_expect_success '$GIT_DIR/common overrides core.worktree' '
        (
                cd work &&
                git rev-parse --git-common-dir >actual &&
-               test-path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect &&
+               test-tool path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect &&
                test_cmp expect actual &&
                echo haha >data2 &&
                git add data2 &&
@@ -431,4 +431,16 @@ test_expect_success 'error out gracefully on invalid $GIT_WORK_TREE' '
        )
 '
 
+test_expect_success 'refs work with relative gitdir and work tree' '
+       git init relative &&
+       git -C relative commit --allow-empty -m one &&
+       git -C relative commit --allow-empty -m two &&
+
+       GIT_DIR=relative/.git GIT_WORK_TREE=relative git reset HEAD^ &&
+
+       git -C relative log -1 --format=%s >actual &&
+       echo one >expect &&
+       test_cmp expect actual
+'
+
 test_done
index 2ce68cc277a1ed742ce7b644de31a4a847e3529b..93c77eac45321cb24823431c4d89dc393049edbf 100755 (executable)
@@ -209,8 +209,9 @@ test_expect_success '@{u} works when tracking a local branch' '
        test refs/heads/master = "$(full_name @{u})"
 '
 
+commit=$(git rev-parse HEAD)
 cat >expect <<EOF
-commit 8f489d01d0cc65c3b0f09504ec50b5ed02a70bd5
+commit $commit
 Reflog: master@{0} (C O Mitter <committer@example.com>)
 Reflog message: branch: Created from HEAD
 Author: A U Thor <author@example.com>
@@ -224,7 +225,7 @@ test_expect_success 'log -g other@{u}' '
 '
 
 cat >expect <<EOF
-commit 8f489d01d0cc65c3b0f09504ec50b5ed02a70bd5
+commit $commit
 Reflog: master@{Thu Apr 7 15:17:13 2005 -0700} (C O Mitter <committer@example.com>)
 Reflog message: branch: Created from HEAD
 Author: A U Thor <author@example.com>
index 079d2411450ca960d3d82fb9c7d59921c4cbe60a..c4422312f4e482e38172b1ac8b87e29d8708af2e 100755 (executable)
@@ -68,7 +68,7 @@ test_expect_success 'GIT_INDEX_VERSION takes precedence over config' '
                git config --add index.version 2 &&
                git add a 2>&1 &&
                echo 4 >expect &&
-               test-index-version <.git/index >actual &&
+               test-tool index-version <.git/index >actual &&
                test_cmp expect actual
        )
 '
index a66936fe9bde2ba20ab0e57400b6286b0710212a..e4f4c4df4ee3686e5ad1621134a827b941b38bca 100755 (executable)
@@ -11,8 +11,8 @@ sane_unset GIT_FSMONITOR_TEST
 test_expect_success 'enable split index' '
        git config splitIndex.maxPercentChange 100 &&
        git update-index --split-index &&
-       test-dump-split-index .git/index >actual &&
-       indexversion=$(test-index-version <.git/index) &&
+       test-tool dump-split-index .git/index >actual &&
+       indexversion=$(test-tool index-version <.git/index) &&
        if test "$indexversion" = "4"
        then
                own=432ef4b63f32193984f339431fd50ca796493569
@@ -39,7 +39,7 @@ test_expect_success 'add one file' '
        EOF
        test_cmp ls-files.expect ls-files.actual &&
 
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        cat >expect <<-EOF &&
        base $base
        100644 $EMPTY_BLOB 0    one
@@ -57,8 +57,8 @@ test_expect_success 'disable split index' '
        EOF
        test_cmp ls-files.expect ls-files.actual &&
 
-       BASE=$(test-dump-split-index .git/index | grep "^own" | sed "s/own/base/") &&
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       BASE=$(test-tool dump-split-index .git/index | grep "^own" | sed "s/own/base/") &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        cat >expect <<-EOF &&
        not a split index
        EOF
@@ -73,7 +73,7 @@ test_expect_success 'enable split index again, "one" now belongs to base index"'
        EOF
        test_cmp ls-files.expect ls-files.actual &&
 
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        cat >expect <<-EOF &&
        $BASE
        replacements:
@@ -91,7 +91,7 @@ test_expect_success 'modify original file, base index untouched' '
        EOF
        test_cmp ls-files.expect ls-files.actual &&
 
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        q_to_tab >expect <<-EOF &&
        $BASE
        100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
@@ -111,7 +111,7 @@ test_expect_success 'add another file, which stays index' '
        EOF
        test_cmp ls-files.expect ls-files.actual &&
 
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        q_to_tab >expect <<-EOF &&
        $BASE
        100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
@@ -130,7 +130,7 @@ test_expect_success 'remove file not in base index' '
        EOF
        test_cmp ls-files.expect ls-files.actual &&
 
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        q_to_tab >expect <<-EOF &&
        $BASE
        100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
@@ -147,7 +147,7 @@ test_expect_success 'remove file in base index' '
        EOF
        test_cmp ls-files.expect ls-files.actual &&
 
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        cat >expect <<-EOF &&
        $BASE
        replacements:
@@ -165,7 +165,7 @@ test_expect_success 'add original file back' '
        EOF
        test_cmp ls-files.expect ls-files.actual &&
 
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        cat >expect <<-EOF &&
        $BASE
        100644 $EMPTY_BLOB 0    one
@@ -195,7 +195,7 @@ test_expect_success 'unify index, two files remain' '
        EOF
        test_cmp ls-files.expect ls-files.actual &&
 
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        cat >expect <<-EOF &&
        not a split index
        EOF
@@ -229,8 +229,8 @@ test_expect_success 'set core.splitIndex config variable to true' '
        100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       two
        EOF
        test_cmp ls-files.expect ls-files.actual &&
-       BASE=$(test-dump-split-index .git/index | grep "^base") &&
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        cat >expect <<-EOF &&
        $BASE
        replacements:
@@ -248,7 +248,7 @@ test_expect_success 'set core.splitIndex config variable to false' '
        100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       two
        EOF
        test_cmp ls-files.expect ls-files.actual &&
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        cat >expect <<-EOF &&
        not a split index
        EOF
@@ -259,8 +259,8 @@ test_expect_success 'set core.splitIndex config variable to true' '
        git config core.splitIndex true &&
        : >three &&
        git update-index --add three &&
-       BASE=$(test-dump-split-index .git/index | grep "^base") &&
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        cat >expect <<-EOF &&
        $BASE
        replacements:
@@ -269,7 +269,7 @@ test_expect_success 'set core.splitIndex config variable to true' '
        test_cmp expect actual &&
        : >four &&
        git update-index --add four &&
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        cat >expect <<-EOF &&
        $BASE
        100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       four
@@ -283,8 +283,8 @@ test_expect_success 'check behavior with splitIndex.maxPercentChange unset' '
        git config --unset splitIndex.maxPercentChange &&
        : >five &&
        git update-index --add five &&
-       BASE=$(test-dump-split-index .git/index | grep "^base") &&
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        cat >expect <<-EOF &&
        $BASE
        replacements:
@@ -293,7 +293,7 @@ test_expect_success 'check behavior with splitIndex.maxPercentChange unset' '
        test_cmp expect actual &&
        : >six &&
        git update-index --add six &&
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        cat >expect <<-EOF &&
        $BASE
        100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       six
@@ -307,8 +307,8 @@ test_expect_success 'check splitIndex.maxPercentChange set to 0' '
        git config splitIndex.maxPercentChange 0 &&
        : >seven &&
        git update-index --add seven &&
-       BASE=$(test-dump-split-index .git/index | grep "^base") &&
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        cat >expect <<-EOF &&
        $BASE
        replacements:
@@ -317,8 +317,8 @@ test_expect_success 'check splitIndex.maxPercentChange set to 0' '
        test_cmp expect actual &&
        : >eight &&
        git update-index --add eight &&
-       BASE=$(test-dump-split-index .git/index | grep "^base") &&
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        cat >expect <<-EOF &&
        $BASE
        replacements:
@@ -332,12 +332,12 @@ test_expect_success 'shared index files expire after 2 weeks by default' '
        git update-index --add ten &&
        test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
        just_under_2_weeks_ago=$((5-14*86400)) &&
-       test-chmtime =$just_under_2_weeks_ago .git/sharedindex.* &&
+       test-tool chmtime =$just_under_2_weeks_ago .git/sharedindex.* &&
        : >eleven &&
        git update-index --add eleven &&
        test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
        just_over_2_weeks_ago=$((-1-14*86400)) &&
-       test-chmtime =$just_over_2_weeks_ago .git/sharedindex.* &&
+       test-tool chmtime =$just_over_2_weeks_ago .git/sharedindex.* &&
        : >twelve &&
        git update-index --add twelve &&
        test $(ls .git/sharedindex.* | wc -l) -le 2
@@ -345,12 +345,12 @@ test_expect_success 'shared index files expire after 2 weeks by default' '
 
 test_expect_success 'check splitIndex.sharedIndexExpire set to 16 days' '
        git config splitIndex.sharedIndexExpire "16.days.ago" &&
-       test-chmtime =$just_over_2_weeks_ago .git/sharedindex.* &&
+       test-tool chmtime =$just_over_2_weeks_ago .git/sharedindex.* &&
        : >thirteen &&
        git update-index --add thirteen &&
        test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
        just_over_16_days_ago=$((-1-16*86400)) &&
-       test-chmtime =$just_over_16_days_ago .git/sharedindex.* &&
+       test-tool chmtime =$just_over_16_days_ago .git/sharedindex.* &&
        : >fourteen &&
        git update-index --add fourteen &&
        test $(ls .git/sharedindex.* | wc -l) -le 2
@@ -359,13 +359,13 @@ test_expect_success 'check splitIndex.sharedIndexExpire set to 16 days' '
 test_expect_success 'check splitIndex.sharedIndexExpire set to "never" and "now"' '
        git config splitIndex.sharedIndexExpire never &&
        just_10_years_ago=$((-365*10*86400)) &&
-       test-chmtime =$just_10_years_ago .git/sharedindex.* &&
+       test-tool chmtime =$just_10_years_ago .git/sharedindex.* &&
        : >fifteen &&
        git update-index --add fifteen &&
        test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
        git config splitIndex.sharedIndexExpire now &&
        just_1_second_ago=-1 &&
-       test-chmtime =$just_1_second_ago .git/sharedindex.* &&
+       test-tool chmtime =$just_1_second_ago .git/sharedindex.* &&
        : >sixteen &&
        git update-index --add sixteen &&
        test $(ls .git/sharedindex.* | wc -l) -le 2
@@ -435,7 +435,7 @@ test_expect_success 'writing split index with null sha1 does not write cache tre
        commit=$(git commit-tree $tree -p HEAD <msg) &&
        git update-ref HEAD "$commit" &&
        GIT_ALLOW_NULL_SHA1=1 git reset --hard &&
-       (test-dump-cache-tree >cache-tree.out || true) &&
+       (test-tool dump-cache-tree >cache-tree.out || true) &&
        test_line_count = 0 cache-tree.out
 '
 
index bb4f2e0c631f1de7421f50b9fa64f11276fe9645..1fa670625c5be87294eec9c5fe86bf2defff2ce2 100755 (executable)
@@ -189,8 +189,12 @@ test_expect_success 'no advice given for explicit detached head state' '
 # Detached HEAD tests for GIT_PRINT_SHA1_ELLIPSIS (new format)
 test_expect_success 'describe_detached_head prints no SHA-1 ellipsis when not asked to' "
 
+       commit=$(git rev-parse --short=12 master^) &&
+       commit2=$(git rev-parse --short=12 master~2) &&
+       commit3=$(git rev-parse --short=12 master~3) &&
+
        # The first detach operation is more chatty than the following ones.
-       cat >1st_detach <<-'EOF' &&
+       cat >1st_detach <<-EOF &&
        Note: checking out 'HEAD^'.
 
        You are in 'detached HEAD' state. You can look around, make experimental
@@ -202,18 +206,18 @@ test_expect_success 'describe_detached_head prints no SHA-1 ellipsis when not as
 
          git checkout -b <new-branch-name>
 
-       HEAD is now at 7c7cd714e262 three
+       HEAD is now at \$commit three
        EOF
 
        # The remaining ones just show info about previous and current HEADs.
-       cat >2nd_detach <<-'EOF' &&
-       Previous HEAD position was 7c7cd714e262 three
-       HEAD is now at 139b20d8e6c5 two
+       cat >2nd_detach <<-EOF &&
+       Previous HEAD position was \$commit three
+       HEAD is now at \$commit2 two
        EOF
 
-       cat >3rd_detach <<-'EOF' &&
-       Previous HEAD position was 139b20d8e6c5 two
-       HEAD is now at d79ce1670bdc one
+       cat >3rd_detach <<-EOF &&
+       Previous HEAD position was \$commit2 two
+       HEAD is now at \$commit3 one
        EOF
 
        reset &&
@@ -261,8 +265,12 @@ test_expect_success 'describe_detached_head prints no SHA-1 ellipsis when not as
 # Detached HEAD tests for GIT_PRINT_SHA1_ELLIPSIS (old format)
 test_expect_success 'describe_detached_head does print SHA-1 ellipsis when asked to' "
 
+       commit=$(git rev-parse --short=12 master^) &&
+       commit2=$(git rev-parse --short=12 master~2) &&
+       commit3=$(git rev-parse --short=12 master~3) &&
+
        # The first detach operation is more chatty than the following ones.
-       cat >1st_detach <<-'EOF' &&
+       cat >1st_detach <<-EOF &&
        Note: checking out 'HEAD^'.
 
        You are in 'detached HEAD' state. You can look around, make experimental
@@ -274,18 +282,18 @@ test_expect_success 'describe_detached_head does print SHA-1 ellipsis when asked
 
          git checkout -b <new-branch-name>
 
-       HEAD is now at 7c7cd714e262... three
+       HEAD is now at \$commit... three
        EOF
 
        # The remaining ones just show info about previous and current HEADs.
-       cat >2nd_detach <<-'EOF' &&
-       Previous HEAD position was 7c7cd714e262... three
-       HEAD is now at 139b20d8e6c5... two
+       cat >2nd_detach <<-EOF &&
+       Previous HEAD position was \$commit... three
+       HEAD is now at \$commit2... two
        EOF
 
-       cat >3rd_detach <<-'EOF' &&
-       Previous HEAD position was 139b20d8e6c5... two
-       HEAD is now at d79ce1670bdc... one
+       cat >3rd_detach <<-EOF &&
+       Previous HEAD position was \$commit2... two
+       HEAD is now at \$commit3... one
        EOF
 
        reset &&
index f46d0499bc6ea95236f7ca05060b8f8fbbdbbc50..e74d58b9e198a4ea2195d3fc6906e651a0a1d650 100755 (executable)
@@ -68,13 +68,13 @@ test_expect_success 'do not touch files that are already up-to-date' '
        git add file1 file2 &&
        git commit -m base &&
        echo modified >file1 &&
-       test-chmtime =1000000000 file2 &&
+       test-tool chmtime =1000000000 file2 &&
        git update-index -q --refresh &&
        git checkout HEAD -- file1 file2 &&
        echo one >expect &&
        test_cmp expect file1 &&
        echo "1000000000        file2" >expect &&
-       test-chmtime -v +0 file2 >actual &&
+       test-tool chmtime -v +0 file2 >actual &&
        test_cmp expect actual
 '
 
index a0f1e3bb800ec6943648eeffb9e7ca84e328fa41..b7d6d5d45adf6067ab2f39801f658f778f9b2855 100755 (executable)
@@ -78,10 +78,9 @@ test_expect_success 'not prune locked checkout' '
 
 test_expect_success 'not prune recent checkouts' '
        test_when_finished rm -r .git/worktrees &&
-       mkdir zz &&
-       mkdir -p .git/worktrees/jlm &&
-       echo "$(pwd)"/zz >.git/worktrees/jlm/gitdir &&
-       rmdir zz &&
+       git worktree add jlm HEAD &&
+       test -d .git/worktrees/jlm &&
+       rm -rf jlm &&
        git worktree prune --verbose --expire=2.days.ago &&
        test -d .git/worktrees/jlm
 '
index 5d5b3632ba0a7cf5364ab4db1df8ca7ea285b4d5..5f7d45b7b7fa91a497d6f8d96a7235fc0024919e 100755 (executable)
@@ -72,12 +72,11 @@ test_expect_success 'move locked worktree' '
 '
 
 test_expect_success 'move worktree' '
-       toplevel="$(pwd)" &&
        git worktree move source destination &&
        test_path_is_missing source &&
        git worktree list --porcelain >out &&
-       grep "^worktree.*/destination" out &&
-       ! grep "^worktree.*/source" out &&
+       grep "^worktree.*/destination$" out &&
+       ! grep "^worktree.*/source$" out &&
        git -C destination log --format=%s >actual2 &&
        echo init >expected2 &&
        test_cmp expected2 actual2
@@ -93,7 +92,7 @@ test_expect_success 'move worktree to another dir' '
        test_when_finished "git worktree move some-dir/destination destination" &&
        test_path_is_missing destination &&
        git worktree list --porcelain >out &&
-       grep "^worktree.*/some-dir/destination" out &&
+       grep "^worktree.*/some-dir/destination$" out &&
        git -C some-dir/destination log --format=%s >actual2 &&
        echo init >expected2 &&
        test_cmp expected2 actual2
index c8bce8c2e4314aaf466019438818293102c12c9c..685ec45639a5e9a2bf929e10aa30976e9a4c456b 100755 (executable)
@@ -8,19 +8,20 @@ test_description='git update-index --again test.
 
 . ./test-lib.sh
 
-cat > expected <<\EOF
-100644 3b18e512dba79e4c8300dd08aeb37f8e728b8dad 0      file1
-100644 9db8893856a8a02eaa73470054b7c1c5a7c82e47 0      file2
-EOF
-test_expect_success 'update-index --add' \
-       'echo hello world >file1 &&
-        echo goodbye people >file2 &&
-        git update-index --add file1 file2 &&
-        git ls-files -s >current &&
-        cmp current expected'
+test_expect_success 'update-index --add' '
+       echo hello world >file1 &&
+       echo goodbye people >file2 &&
+       git update-index --add file1 file2 &&
+       git ls-files -s >current &&
+       cat >expected <<-EOF &&
+       100644 $(git hash-object file1) 0       file1
+       100644 $(git hash-object file2) 0       file2
+       EOF
+       cmp current expected
+'
 
-test_expect_success 'update-index --again' \
-       'rm -f file1 &&
+test_expect_success 'update-index --again' '
+       rm -f file1 &&
        echo hello everybody >file2 &&
        if git update-index --again
        then
@@ -29,25 +30,23 @@ test_expect_success 'update-index --again' \
        else
                echo happy - failed as expected
        fi &&
-        git ls-files -s >current &&
-        cmp current expected'
+       git ls-files -s >current &&
+       cmp current expected
+'
 
-cat > expected <<\EOF
-100644 0f1ae1422c2bf43f117d3dbd715c988a9ed2103f 0      file2
-EOF
-test_expect_success 'update-index --remove --again' \
-       'git update-index --remove --again &&
-        git ls-files -s >current &&
-        cmp current expected'
+test_expect_success 'update-index --remove --again' '
+       git update-index --remove --again &&
+       git ls-files -s >current &&
+       cat >expected <<-EOF &&
+       100644 $(git hash-object file2) 0       file2
+       EOF
+       cmp current expected
+'
 
 test_expect_success 'first commit' 'git commit -m initial'
 
-cat > expected <<\EOF
-100644 53ab446c3f4e42ce9bb728a0ccb283a101be4979 0      dir1/file3
-100644 0f1ae1422c2bf43f117d3dbd715c988a9ed2103f 0      file2
-EOF
-test_expect_success 'update-index again' \
-       'mkdir -p dir1 &&
+test_expect_success 'update-index again' '
+       mkdir -p dir1 &&
        echo hello world >dir1/file3 &&
        echo goodbye people >file2 &&
        git update-index --add file2 dir1/file3 &&
@@ -55,30 +54,38 @@ test_expect_success 'update-index again' \
        echo happy >dir1/file3 &&
        git update-index --again &&
        git ls-files -s >current &&
-       cmp current expected'
+       cat >expected <<-EOF &&
+       100644 $(git hash-object dir1/file3) 0  dir1/file3
+       100644 $(git hash-object file2) 0       file2
+       EOF
+       cmp current expected
+'
 
-cat > expected <<\EOF
-100644 d7fb3f695f06c759dbf3ab00046e7cc2da22d10f 0      dir1/file3
-100644 0f1ae1422c2bf43f117d3dbd715c988a9ed2103f 0      file2
-EOF
-test_expect_success 'update-index --update from subdir' \
-       'echo not so happy >file2 &&
+file2=$(git hash-object file2)
+test_expect_success 'update-index --update from subdir' '
+       echo not so happy >file2 &&
        (cd dir1 &&
        cat ../file2 >file3 &&
        git update-index --again
        ) &&
        git ls-files -s >current &&
-       cmp current expected'
+       cat >expected <<-EOF &&
+       100644 $(git hash-object dir1/file3) 0  dir1/file3
+       100644 $file2 0 file2
+       EOF
+       test_cmp current expected
+'
 
-cat > expected <<\EOF
-100644 594fb5bb1759d90998e2bf2a38261ae8e243c760 0      dir1/file3
-100644 0f1ae1422c2bf43f117d3dbd715c988a9ed2103f 0      file2
-EOF
-test_expect_success 'update-index --update with pathspec' \
-       'echo very happy >file2 &&
+test_expect_success 'update-index --update with pathspec' '
+       echo very happy >file2 &&
        cat file2 >dir1/file3 &&
        git update-index --again dir1/ &&
        git ls-files -s >current &&
-       cmp current expected'
+       cat >expected <<-EOF &&
+       100644 $(git hash-object dir1/file3) 0  dir1/file3
+       100644 $file2 0 file2
+       EOF
+       cmp current expected
+'
 
 test_done
index cc830da58d920718b7b0a990a359afa9dd783b4c..7e2e7dd4ae5842bc49ccaf5dc116deb3b3d6b993 100755 (executable)
@@ -33,7 +33,7 @@ test_expect_success 'setup' '
 '
 
 test_expect_success 'index is at version 2' '
-       test "$(test-index-version < .git/index)" = 2
+       test "$(test-tool index-version < .git/index)" = 2
 '
 
 test_expect_success 'update-index --skip-worktree' '
@@ -42,7 +42,7 @@ test_expect_success 'update-index --skip-worktree' '
 '
 
 test_expect_success 'index is at version 3 after having some skip-worktree entries' '
-       test "$(test-index-version < .git/index)" = 3
+       test "$(test-tool index-version < .git/index)" = 3
 '
 
 test_expect_success 'ls-files -t' '
@@ -55,7 +55,7 @@ test_expect_success 'update-index --no-skip-worktree' '
 '
 
 test_expect_success 'index version is back to 2 when there is no skip-worktree entry' '
-       test "$(test-index-version < .git/index)" = 2
+       test "$(test-tool index-version < .git/index)" = 2
 '
 
 test_done
index 32ac6e09bdc81acfb8de5cf887302794d20c8ece..1db7e6a1abbebb63f811fa6ecbcd1db67607298e 100755 (executable)
@@ -85,9 +85,9 @@ test_expect_success '--chmod=+x and chmod=-x in the same argument list' '
        >B &&
        git add A B &&
        git update-index --chmod=+x A --chmod=-x B &&
-       cat >expect <<-\EOF &&
-       100755 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       A
-       100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       B
+       cat >expect <<-EOF &&
+       100755 $EMPTY_BLOB 0    A
+       100644 $EMPTY_BLOB 0    B
        EOF
        git ls-files --stage A B >actual &&
        test_cmp expect actual
index bdf5198b7eff11f9a7bfb57239f5905d92fe4bf7..08af596ba6c6b032eb1696c3beaba7c1776b4fd5 100755 (executable)
@@ -4,7 +4,7 @@ test_description='Test the lazy init name hash with various folder structures'
 
 . ./test-lib.sh
 
-if test 1 -eq $($GIT_BUILD_DIR/t/helper/test-online-cpus)
+if test 1 -eq $($GIT_BUILD_DIR/t/helper/test-tool online-cpus)
 then
        skip_all='skipping lazy-init tests, single cpu'
        test_done
@@ -21,7 +21,7 @@ test_expect_success 'no buffer overflow in lazy_init_name_hash' '
        ) |
        sed "s/^/100644 $EMPTY_BLOB     /" |
        git update-index --index-info &&
-       test-lazy-init-name-hash -m
+       test-tool lazy-init-name-hash -m
 '
 
 test_done
index c1fc6ca7301eaa9b15ef091ce592989956efc156..dce102130fb77ddda7cdc9aa9211507d9c2f2e09 100755 (executable)
@@ -79,12 +79,12 @@ match_with_function() {
        if test "$match_expect" = 1
        then
                test_expect_success "$match_function: match '$text' '$pattern'" "
-                       test-wildmatch $match_function '$text' '$pattern'
+                       test-tool wildmatch $match_function '$text' '$pattern'
                "
        elif test "$match_expect" = 0
        then
                test_expect_success "$match_function: no match '$text' '$pattern'" "
-                       test_must_fail test-wildmatch $match_function '$text' '$pattern'
+                       test_must_fail test-tool wildmatch $match_function '$text' '$pattern'
                "
        else
                test_expect_success "PANIC: Test framework error. Unknown matches value $match_expect" 'false'
@@ -148,7 +148,7 @@ match_with_ls_files() {
 match() {
        if test "$#" = 6
        then
-               # When test-wildmatch and git ls-files produce the same
+               # When test-tool wildmatch and git ls-files produce the same
                # result.
                match_glob=$1
                match_file_glob=$match_glob
@@ -204,19 +204,19 @@ match() {
                fi
        '
 
-       # $1: Case sensitive glob match: test-wildmatch & ls-files
+       # $1: Case sensitive glob match: test-tool wildmatch & ls-files
        match_with_function "$text" "$pattern" $match_glob "wildmatch"
        match_with_ls_files "$text" "$pattern" $match_file_glob "wildmatch" " --glob-pathspecs"
 
-       # $2: Case insensitive glob match: test-wildmatch & ls-files
+       # $2: Case insensitive glob match: test-tool wildmatch & ls-files
        match_with_function "$text" "$pattern" $match_iglob "iwildmatch"
        match_with_ls_files "$text" "$pattern" $match_file_iglob "iwildmatch" " --glob-pathspecs --icase-pathspecs"
 
-       # $3: Case sensitive path match: test-wildmatch & ls-files
+       # $3: Case sensitive path match: test-tool wildmatch & ls-files
        match_with_function "$text" "$pattern" $match_pathmatch "pathmatch"
        match_with_ls_files "$text" "$pattern" $match_file_pathmatch "pathmatch" ""
 
-       # $4: Case insensitive path match: test-wildmatch & ls-files
+       # $4: Case insensitive path match: test-tool wildmatch & ls-files
        match_with_function "$text" "$pattern" $match_pathmatchi "ipathmatch"
        match_with_ls_files "$text" "$pattern" $match_file_pathmatchi "ipathmatch" " --icase-pathspecs"
 }
index 6c0b7ea4addc8f1569b1b85f58dd3072fb863f33..c0ef946811dd534dfa5e704c992b6ab1fab82c35 100755 (executable)
@@ -6,6 +6,7 @@
 test_description='git branch assorted tests'
 
 . ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-rebase.sh
 
 test_expect_success 'prepare a trivial repository' '
        echo Hello >A &&
@@ -1246,6 +1247,29 @@ test_expect_success '--merged is incompatible with --no-merged' '
        test_must_fail git branch --merged HEAD --no-merged HEAD
 '
 
+test_expect_success '--list during rebase' '
+       test_when_finished "reset_rebase" &&
+       git checkout master &&
+       FAKE_LINES="1 edit 2" &&
+       export FAKE_LINES &&
+       set_fake_editor &&
+       git rebase -i HEAD~2 &&
+       git branch --list >actual &&
+       test_i18ngrep "rebasing master" actual
+'
+
+test_expect_success '--list during rebase from detached HEAD' '
+       test_when_finished "reset_rebase && git checkout master" &&
+       git checkout master^0 &&
+       oid=$(git rev-parse --short HEAD) &&
+       FAKE_LINES="1 edit 2" &&
+       export FAKE_LINES &&
+       set_fake_editor &&
+       git rebase -i HEAD~2 &&
+       git branch --list >actual &&
+       test_i18ngrep "rebasing detached HEAD $oid" actual
+'
+
 test_expect_success 'tracking with unexpected .fetch refspec' '
        rm -rf a b c d &&
        git init a &&
index 86bf909ee3dfca78f678fdefe961772dcd78d6b1..61748088ebcbed700a570bc0e297f48435844340 100755 (executable)
@@ -22,7 +22,7 @@ test_expect_success 'setup: create a few commits with notes' '
        git commit -m 3rd &&
        COMMIT_FILE=.git/objects/5e/e1c35e83ea47cd3cc4f8cbee0568915fbbbd29 &&
        test -f $COMMIT_FILE &&
-       test-chmtime =+0 $COMMIT_FILE &&
+       test-tool chmtime =+0 $COMMIT_FILE &&
        git notes add -m "Note #3"
 '
 
index 3b905406df79187f70c828f72e9e2dc187f1be57..756de26c19c90429237456d3fb0bbbfd80ccfda9 100755 (executable)
@@ -711,13 +711,13 @@ test_expect_success 'rebase -i continue with unstaged submodule' '
 test_expect_success 'avoid unnecessary reset' '
        git checkout master &&
        git reset --hard &&
-       test-chmtime =123456789 file3 &&
+       test-tool chmtime =123456789 file3 &&
        git update-index --refresh &&
        HEAD=$(git rev-parse HEAD) &&
        set_fake_editor &&
        git rebase -i HEAD~4 &&
        test $HEAD = $(git rev-parse HEAD) &&
-       MTIME=$(test-chmtime -v +0 file3 | sed 's/[^0-9].*$//') &&
+       MTIME=$(test-tool chmtime -v +0 file3 | sed 's/[^0-9].*$//') &&
        test 123456789 = $MTIME
 '
 
@@ -927,10 +927,8 @@ test_expect_success 'rebase --exec works without -i ' '
 test_expect_success 'rebase -i --exec without <CMD>' '
        git reset --hard execute &&
        set_fake_editor &&
-       test_must_fail git rebase -i --exec 2>tmp &&
-       sed -e "1d" tmp >actual &&
-       test_must_fail git rebase -h >expected &&
-       test_cmp expected actual &&
+       test_must_fail git rebase -i --exec 2>actual &&
+       test_i18ngrep "requires a value" actual &&
        git checkout master
 '
 
index 7c91a85f43a7a11295819adc5da5f8e5fca9e4ea..9214d0bb511e24f401188790858dc1e0ca1b92fd 100755 (executable)
@@ -24,7 +24,7 @@ test_expect_success 'interactive rebase --continue works with touched file' '
        git checkout master &&
 
        FAKE_LINES="edit 1" git rebase -i HEAD^ &&
-       test-chmtime =-60 F1 &&
+       test-tool chmtime =-60 F1 &&
        git rebase --continue
 '
 
@@ -36,7 +36,7 @@ test_expect_success 'non-interactive rebase --continue works with touched file'
        test_must_fail git rebase --onto master master topic &&
        echo "Resolved" >F2 &&
        git add F2 &&
-       test-chmtime =-60 F1 &&
+       test-tool chmtime =-60 F1 &&
        git rebase --continue
 '
 
index 68fe2003ef5f74073cafa4741bee31ade85cf5c0..b078f930462d7187546376c9fe2331b3e0303773 100755 (executable)
@@ -199,7 +199,7 @@ test_run_rebase () {
        "
 }
 test_run_rebase success ''
-test_run_rebase failure -m
+test_run_rebase success -m
 test_run_rebase success -i
 test_run_rebase failure -p
 
@@ -214,8 +214,8 @@ test_run_rebase () {
        "
 }
 test_run_rebase success ''
-test_run_rebase failure -m
-test_run_rebase failure -i
+test_run_rebase success -m
+test_run_rebase success -i
 test_run_rebase failure -p
 
 #       m
index 2afb56470184b18da19740f0a68abb31da96fd82..f6993b7e14d91617b337bfaefa717ec8591fb28f 100755 (executable)
@@ -12,6 +12,13 @@ cat >file <<EOF
 a
 EOF
 
+# Expected commit message for initial commit after rebase --signoff
+cat >expected-initial-signed <<EOF
+Initial empty commit
+
+Signed-off-by: $(git var GIT_COMMITTER_IDENT | sed -e "s/>.*/>/")
+EOF
+
 # Expected commit message after rebase --signoff
 cat >expected-signed <<EOF
 first
@@ -43,4 +50,35 @@ test_expect_success 'rebase --no-signoff does not add a sign-off line' '
        test_cmp expected-unsigned actual
 '
 
+test_expect_success 'rebase --exec --signoff adds a sign-off line' '
+       test_when_finished "rm exec" &&
+       git commit --amend -m "first" &&
+       git rebase --exec "touch exec" --signoff HEAD^ &&
+       test_path_is_file exec &&
+       git cat-file commit HEAD | sed -e "1,/^\$/d" >actual &&
+       test_cmp expected-signed actual
+'
+
+test_expect_success 'rebase --root --signoff adds a sign-off line' '
+       git commit --amend -m "first" &&
+       git rebase --root --keep-empty --signoff &&
+       git cat-file commit HEAD^ | sed -e "1,/^\$/d" >actual &&
+       test_cmp expected-initial-signed actual &&
+       git cat-file commit HEAD | sed -e "1,/^\$/d" >actual &&
+       test_cmp expected-signed actual
+'
+
+test_expect_success 'rebase -i --signoff fails' '
+       git commit --amend -m "first" &&
+       git rebase -i --signoff HEAD^ &&
+       git cat-file commit HEAD | sed -e "1,/^\$/d" >actual &&
+       test_cmp expected-signed actual
+'
+
+test_expect_success 'rebase -m --signoff fails' '
+       git commit --amend -m "first" &&
+       git rebase -m --signoff HEAD^ &&
+       git cat-file commit HEAD | sed -e "1,/^\$/d" >actual &&
+       test_cmp expected-signed actual
+'
 test_done
index 783bdbf59db07ebf2afac83165d31b86fd6b95db..ccbc11851497a10c74dcdaba1ed7238aa6b409f7 100755 (executable)
@@ -86,7 +86,7 @@ test_expect_success 'cherry-pick on stat-dirty working tree' '
        (
                cd copy &&
                git checkout initial &&
-               test-chmtime +40 oops &&
+               test-tool chmtime +40 oops &&
                git cherry-pick added
        )
 '
index 0acf4b14614c750d3c2324d8a941aa77d5c7ad56..9f93445f1e496b930f4f7cb53146344315bc1c8e 100755 (executable)
@@ -247,9 +247,9 @@ test_expect_success '--abort after last commit in sequence' '
 test_expect_success 'cherry-pick does not implicitly stomp an existing operation' '
        pristine_detach initial &&
        test_expect_code 1 git cherry-pick base..anotherpick &&
-       test-chmtime -v +0 .git/sequencer >expect &&
+       test-tool chmtime -v +0 .git/sequencer >expect &&
        test_expect_code 128 git cherry-pick unrelatedpick &&
-       test-chmtime -v +0 .git/sequencer >actual &&
+       test-tool chmtime -v +0 .git/sequencer >actual &&
        test_cmp expect actual
 '
 
index 46f15169f55c03742717f36f8d0e99241391b2ea..b8fbdefcdc34ffa6fb54fc1ad375a583a194fb38 100755 (executable)
@@ -232,7 +232,7 @@ test_expect_success 'Call "rm" from outside the work tree' '
 test_expect_success 'refresh index before checking if it is up-to-date' '
 
        git reset --hard &&
-       test-chmtime -86400 frotz/nitfol &&
+       test-tool chmtime -86400 frotz/nitfol &&
        git rm frotz/nitfol &&
        test ! -f frotz/nitfol
 
index 2748805642201d7c514792bab8d8b3940fb4086c..07af05d7aee65c51245431292a21ec38eef19f53 100755 (executable)
@@ -187,7 +187,7 @@ test_expect_success 'git add --refresh with pathspec' '
        echo >foo && echo >bar && echo >baz &&
        git add foo bar baz && H=$(git rev-parse :foo) && git rm -f foo &&
        echo "100644 $H 3       foo" | git update-index --index-info &&
-       test-chmtime -60 bar baz &&
+       test-tool chmtime -60 bar baz &&
        >expect &&
        git add --refresh bar >actual &&
        test_cmp expect actual &&
index bfde4057ad2afcdd3bd38cbb43ffa2ce241aaa67..3ea5b9bb3ff0a4e439b1fc6cd8f9df86386f4126 100755 (executable)
@@ -228,4 +228,56 @@ test_expect_success 'stash previously ignored file' '
        test_path_is_file ignored.d/foo
 '
 
+test_expect_success 'stash -u -- <untracked> doesnt print error' '
+       >untracked &&
+       git stash push -u -- untracked 2>actual &&
+       test_path_is_missing untracked &&
+       test_line_count = 0 actual
+'
+
+test_expect_success 'stash -u -- <untracked> leaves rest of working tree in place' '
+       >tracked &&
+       git add tracked &&
+       >untracked &&
+       git stash push -u -- untracked &&
+       test_path_is_missing untracked &&
+       test_path_is_file tracked
+'
+
+test_expect_success 'stash -u -- <tracked> <untracked> clears changes in both' '
+       >tracked &&
+       git add tracked &&
+       >untracked &&
+       git stash push -u -- tracked untracked &&
+       test_path_is_missing tracked &&
+       test_path_is_missing untracked
+'
+
+test_expect_success 'stash --all -- <ignored> stashes ignored file' '
+       >ignored.d/bar &&
+       git stash push --all -- ignored.d/bar &&
+       test_path_is_missing ignored.d/bar
+'
+
+test_expect_success 'stash --all -- <tracked> <ignored> clears changes in both' '
+       >tracked &&
+       git add tracked &&
+       >ignored.d/bar &&
+       git stash push --all -- tracked ignored.d/bar &&
+       test_path_is_missing tracked &&
+       test_path_is_missing ignored.d/bar
+'
+
+test_expect_success 'stash -u -- <ignored> leaves ignored file alone' '
+       >ignored.d/bar &&
+       git stash push -u -- ignored.d/bar &&
+       test_path_is_file ignored.d/bar
+'
+
+test_expect_success 'stash -u -- <non-existant> shows no changes when there are none' '
+       git stash push -u -- non-existant >actual &&
+       echo "No local changes to save" >expect &&
+       test_i18ncmp expect actual
+'
+
 test_done
index 13e7f621ab79f95cc7c3057d9de5710813049102..cf0f3a1ee75dd28c6b5ce2a5db7c3ad6afafd21f 100755 (executable)
@@ -73,7 +73,7 @@ test_expect_success 'diff identical, but newly created symlink and file' '
        >expected &&
        rm -f frotz nitfol &&
        echo xyzzy >nitfol &&
-       test-chmtime +10 nitfol &&
+       test-tool chmtime +10 nitfol &&
        if test_have_prereq SYMLINKS
        then
                ln -s xyzzy frotz
index 3f9a24fd56c801d1a75abb6cc4f4e8928c2dc427..f8d853595b99bfff64521a502ee062b7e5f35e5f 100755 (executable)
@@ -76,7 +76,7 @@ test_expect_success setup '
 
        mkdir dir3 &&
        cp dir/sub dir3/sub &&
-       test-chmtime +1 dir3/sub &&
+       test-tool chmtime +1 dir3/sub &&
 
        git config log.showroot false &&
        git commit --amend &&
index 2f1737fcef185486dc626d616c37fdadc11deba1..0352bf81a90a38adf14fb7a980c98600e1f650b2 100755 (executable)
@@ -147,7 +147,7 @@ test_expect_success 'git diff --ignore-all-space, both files outside repo' '
 '
 
 test_expect_success 'git diff --quiet ignores stat-change only entries' '
-       test-chmtime +10 a &&
+       test-tool chmtime +10 a &&
        echo modified >>b &&
        test_expect_code 1 git diff --quiet
 '
index 16432781d2e0d52c33dfb1444fcce4459b417e8b..9d8d3c72e7efe68b8e0011c1ec9b77d9a0820b30 100755 (executable)
@@ -171,7 +171,7 @@ test_expect_success 'am --skip leaves index stat info alone' '
        git checkout -f --orphan skip-stat-info &&
        git reset &&
        test_commit skip-should-be-untouched &&
-       test-chmtime =0 skip-should-be-untouched.t &&
+       test-tool chmtime =0 skip-should-be-untouched.t &&
        git update-index --refresh &&
        git diff-files --exit-code --quiet &&
        test_must_fail git am 0001-*.patch &&
@@ -183,7 +183,7 @@ test_expect_success 'am --abort leaves index stat info alone' '
        git checkout -f --orphan abort-stat-info &&
        git reset &&
        test_commit abort-should-be-untouched &&
-       test-chmtime =0 abort-should-be-untouched.t &&
+       test-tool chmtime =0 abort-should-be-untouched.t &&
        git update-index --refresh &&
        git diff-files --exit-code --quiet &&
        test_must_fail git am 0001-*.patch &&
index d97d2bebc9850c8ba96a8263ed081fced2ecc153..deafaa3e07546cea3d0bcf3aa3c00e2ba7e41406 100755 (executable)
@@ -166,7 +166,7 @@ test_expect_success 'first postimage wins' '
        git commit -q -a -m "prefer first over second" &&
        test -f $rr/postimage &&
 
-       oldmtimepost=$(test-chmtime -v -60 $rr/postimage | cut -f 1) &&
+       oldmtimepost=$(test-tool chmtime -v -60 $rr/postimage | cut -f 1) &&
 
        git checkout -b third master &&
        git show second^:a1 | sed "s/To die: t/To die! T/" >a1 &&
@@ -179,7 +179,7 @@ test_expect_success 'first postimage wins' '
 '
 
 test_expect_success 'rerere updates postimage timestamp' '
-       newmtimepost=$(test-chmtime -v +0 $rr/postimage | cut -f 1) &&
+       newmtimepost=$(test-tool chmtime -v +0 $rr/postimage | cut -f 1) &&
        test $oldmtimepost -lt $newmtimepost
 '
 
@@ -220,9 +220,9 @@ test_expect_success 'set up for garbage collection tests' '
        almost_60_days_ago=$((60-60*86400)) &&
        just_over_60_days_ago=$((-1-60*86400)) &&
 
-       test-chmtime =$just_over_60_days_ago $rr/preimage &&
-       test-chmtime =$almost_60_days_ago $rr/postimage &&
-       test-chmtime =$almost_15_days_ago $rr2/preimage
+       test-tool chmtime =$just_over_60_days_ago $rr/preimage &&
+       test-tool chmtime =$almost_60_days_ago $rr/postimage &&
+       test-tool chmtime =$almost_15_days_ago $rr2/preimage
 '
 
 test_expect_success 'gc preserves young or recently used records' '
@@ -232,8 +232,8 @@ test_expect_success 'gc preserves young or recently used records' '
 '
 
 test_expect_success 'old records rest in peace' '
-       test-chmtime =$just_over_60_days_ago $rr/postimage &&
-       test-chmtime =$just_over_15_days_ago $rr2/preimage &&
+       test-tool chmtime =$just_over_60_days_ago $rr/postimage &&
+       test-tool chmtime =$just_over_15_days_ago $rr2/preimage &&
        git rerere gc &&
        ! test -f $rr/preimage &&
        ! test -f $rr2/preimage
@@ -249,8 +249,8 @@ rerere_gc_custom_expiry_test () {
                >"$rr/postimage" &&
 
                two_days_ago=$((-2*86400)) &&
-               test-chmtime =$two_days_ago "$rr/preimage" &&
-               test-chmtime =$two_days_ago "$rr/postimage" &&
+               test-tool chmtime =$two_days_ago "$rr/preimage" &&
+               test-tool chmtime =$two_days_ago "$rr/postimage" &&
 
                find .git/rr-cache -type f | sort >original &&
 
@@ -512,7 +512,7 @@ test_expect_success 'multiple identical conflicts' '
        count_pre_post 2 0 &&
 
        # Pretend that the conflicts were made quite some time ago
-       find .git/rr-cache/ -type f | xargs test-chmtime -172800 &&
+       find .git/rr-cache/ -type f | xargs test-tool chmtime -172800 &&
 
        # Unresolved entries have not expired yet
        git -c gc.rerereresolved=5 -c gc.rerereunresolved=5 rerere gc &&
@@ -568,7 +568,7 @@ test_expect_success 'multiple identical conflicts' '
        git rerere &&
 
        # Pretend that the resolutions are old again
-       find .git/rr-cache/ -type f | xargs test-chmtime -172800 &&
+       find .git/rr-cache/ -type f | xargs test-tool chmtime -172800 &&
 
        # Resolved entries have not expired yet
        git -c gc.rerereresolved=5 -c gc.rerereunresolved=5 rerere gc &&
index da10478f59da1a301edf7def229d37fbc964dce9..ff6649ed9a70721523da3c55142a9622b152243a 100755 (executable)
@@ -127,6 +127,11 @@ test_expect_success !MINGW 'shortlog can read --format=raw output' '
        test_cmp expect out
 '
 
+test_expect_success 'shortlog from non-git directory refuses extra arguments' '
+       test_must_fail env GIT_DIR=non-existing git shortlog foo 2>out &&
+       test_i18ngrep "too many arguments" out
+'
+
 test_expect_success 'shortlog should add newline when input line matches wraplen' '
        cat >expect <<\EOF &&
 A U Thor (2):
index fe2d4f15a73f082c516a03b1877c4cf82982138a..af4d9b88762889fb5d2b390f2251bbb39a52d266 100755 (executable)
@@ -101,7 +101,7 @@ test_expect_success \
      ten=0123456789 && hundred=$ten$ten$ten$ten$ten$ten$ten$ten$ten$ten &&
      echo long filename >a/four$hundred &&
      mkdir a/bin &&
-     test-genrandom "frotz" 500000 >a/bin/sh &&
+     test-tool genrandom "frotz" 500000 >a/bin/sh &&
      printf "A\$Format:%s\$O" "$SUBSTFORMAT" >a/substfile1 &&
      printf "A not substituted O" >a/substfile2 &&
      if test_have_prereq SYMLINKS; then
@@ -192,7 +192,7 @@ test_expect_success \
     'validate file modification time' \
     'mkdir extract &&
      "$TAR" xf b.tar -C extract a/a &&
-     test-chmtime -v +0 extract/a/a |cut -f 1 >b.mtime &&
+     test-tool chmtime -v +0 extract/a/a |cut -f 1 >b.mtime &&
      echo "1117231200" >expected.mtime &&
      test_cmp expected.mtime b.mtime'
 
index 9c68b992511b7098df0570ca37e0add468a8a093..65ff60f2ee9b4af61f3f2d7d0f889fc4529e2b60 100755 (executable)
@@ -16,8 +16,8 @@ test_expect_success \
      perl -e "print \"a\" x 4096;" > a &&
      perl -e "print \"b\" x 4096;" > b &&
      perl -e "print \"c\" x 4096;" > c &&
-     test-genrandom "seed a" 2097152 > a_big &&
-     test-genrandom "seed b" 2097152 > b_big &&
+     test-tool genrandom "seed a" 2097152 > a_big &&
+     test-tool genrandom "seed b" 2097152 > b_big &&
      git update-index --add a a_big b b_big c &&
      cat c >d && echo foo >>d && git update-index --add d &&
      tree=$(git write-tree) &&
@@ -311,8 +311,8 @@ test_expect_success 'unpacking with --strict' '
        rm -f .git/index &&
        tail -n 10 LIST | git update-index --index-info &&
        ST=$(git write-tree) &&
-       PACK5=$( git rev-list --objects "$LIST" "$LI" "$ST" | \
-               git pack-objects test-5 ) &&
+       git rev-list --objects "$LIST" "$LI" "$ST" >actual &&
+       PACK5=$( git pack-objects test-5 <actual ) &&
        PACK6=$( (
                        echo "$LIST"
                        echo "$LI"
@@ -358,8 +358,8 @@ test_expect_success 'index-pack with --strict' '
        rm -f .git/index &&
        tail -n 10 LIST | git update-index --index-info &&
        ST=$(git write-tree) &&
-       PACK5=$( git rev-list --objects "$LIST" "$LI" "$ST" | \
-               git pack-objects test-5 ) &&
+       git rev-list --objects "$LIST" "$LI" "$ST" >actual &&
+       PACK5=$( git pack-objects test-5 <actual ) &&
        PACK6=$( (
                        echo "$LIST"
                        echo "$LI"
index cae8c2e8822ccc1e464e3f5b71c99c1f6b1c2323..76f9798ab958cae2414cbcc496bbb22af85f0ac5 100755 (executable)
@@ -12,7 +12,7 @@ test_expect_success \
      for i in a b c
      do
          echo $i >$i &&
-         test-genrandom "$i" 32768 >>$i &&
+        test-tool genrandom "$i" 32768 >>$i &&
          git update-index --add $i || return 1
      done &&
      echo d >d && cat c >>d && git update-index --add d &&
index d695a6082edf69c6ab377ea825519097f84162f3..bb9b8bb3097c05f6e28c37fa24fa27d5bb5b805d 100755 (executable)
@@ -15,17 +15,17 @@ test_expect_success \
      while test $i -le 100
      do
          iii=$(printf '%03i' $i)
-         test-genrandom "bar" 200 > wide_delta_$iii &&
-         test-genrandom "baz $iii" 50 >> wide_delta_$iii &&
-         test-genrandom "foo"$i 100 > deep_delta_$iii &&
-         test-genrandom "foo"$(expr $i + 1) 100 >> deep_delta_$iii &&
-         test-genrandom "foo"$(expr $i + 2) 100 >> deep_delta_$iii &&
+        test-tool genrandom "bar" 200 > wide_delta_$iii &&
+        test-tool genrandom "baz $iii" 50 >> wide_delta_$iii &&
+        test-tool genrandom "foo"$i 100 > deep_delta_$iii &&
+        test-tool genrandom "foo"$(expr $i + 1) 100 >> deep_delta_$iii &&
+        test-tool genrandom "foo"$(expr $i + 2) 100 >> deep_delta_$iii &&
          echo $iii >file_$iii &&
-         test-genrandom "$iii" 8192 >>file_$iii &&
+        test-tool genrandom "$iii" 8192 >>file_$iii &&
          git update-index --add file_$iii deep_delta_$iii wide_delta_$iii &&
          i=$(expr $i + 1) || return 1
      done &&
-     { echo 101 && test-genrandom 100 8192; } >file_101 &&
+     { echo 101 && test-tool genrandom 100 8192; } >file_101 &&
      git update-index --add file_101 &&
      tree=$(git write-tree) &&
      commit=$(git commit-tree $tree </dev/null) && {
index 5940ce2084a6e9cc935a0e5784ff8b6bff8e035d..3634e258f8bf66c2c1917c1598f6f21486c08684 100755 (executable)
@@ -19,14 +19,14 @@ test_description='resilience to pack corruptions with redundant objects'
 # 3) object header is always 2 bytes.
 
 create_test_files() {
-    test-genrandom "foo" 2000 > file_1 &&
-    test-genrandom "foo" 1800 > file_2 &&
-    test-genrandom "foo" 1800 > file_3 &&
+    test-tool genrandom "foo" 2000 > file_1 &&
+    test-tool genrandom "foo" 1800 > file_2 &&
+    test-tool genrandom "foo" 1800 > file_3 &&
     echo " base " >> file_1 &&
     echo " delta1 " >> file_2 &&
     echo " delta delta2 " >> file_3 &&
-    test-genrandom "bar" 150 >> file_2 &&
-    test-genrandom "baz" 100 >> file_3
+    test-tool genrandom "bar" 150 >> file_2 &&
+    test-tool genrandom "baz" 100 >> file_3
 }
 
 create_new_pack() {
index 6694c19a1eecf10117b843bbacbc5bb47924c9c8..f0f6e2a5f3d015cb8d753c3d965c1c42e27b5784 100755 (executable)
@@ -15,7 +15,7 @@ add_blob() {
        BLOB_FILE=.git/objects/$(echo $BLOB | sed "s/^../&\//") &&
        verbose test $((1 + $before)) = $(git count-objects | sed "s/ .*//") &&
        test_path_is_file $BLOB_FILE &&
-       test-chmtime =+0 $BLOB_FILE
+       test-tool chmtime =+0 $BLOB_FILE
 }
 
 test_expect_success setup '
@@ -33,7 +33,7 @@ test_expect_success 'prune stale packs' '
        orig_pack=$(echo .git/objects/pack/*.pack) &&
        : > .git/objects/tmp_1.pack &&
        : > .git/objects/tmp_2.pack &&
-       test-chmtime =-86501 .git/objects/tmp_1.pack &&
+       test-tool chmtime =-86501 .git/objects/tmp_1.pack &&
        git prune --expire 1.day &&
        test_path_is_file $orig_pack &&
        test_path_is_file .git/objects/tmp_2.pack &&
@@ -47,7 +47,7 @@ test_expect_success 'prune --expire' '
        git prune --expire=1.hour.ago &&
        verbose test $((1 + $before)) = $(git count-objects | sed "s/ .*//") &&
        test_path_is_file $BLOB_FILE &&
-       test-chmtime =-86500 $BLOB_FILE &&
+       test-tool chmtime =-86500 $BLOB_FILE &&
        git prune --expire 1.day &&
        verbose test $before = $(git count-objects | sed "s/ .*//") &&
        test_path_is_missing $BLOB_FILE
@@ -57,11 +57,11 @@ test_expect_success 'prune --expire' '
 test_expect_success 'gc: implicit prune --expire' '
 
        add_blob &&
-       test-chmtime =-$((2*$week-30)) $BLOB_FILE &&
+       test-tool chmtime =-$((2*$week-30)) $BLOB_FILE &&
        git gc &&
        verbose test $((1 + $before)) = $(git count-objects | sed "s/ .*//") &&
        test_path_is_file $BLOB_FILE &&
-       test-chmtime =-$((2*$week+1)) $BLOB_FILE &&
+       test-tool chmtime =-$((2*$week+1)) $BLOB_FILE &&
        git gc &&
        verbose test $before = $(git count-objects | sed "s/ .*//") &&
        test_path_is_missing $BLOB_FILE
@@ -141,7 +141,7 @@ test_expect_success 'prune: do not prune heads listed as an argument' '
 test_expect_success 'gc --no-prune' '
 
        add_blob &&
-       test-chmtime =-$((5001*$day)) $BLOB_FILE &&
+       test-tool chmtime =-$((5001*$day)) $BLOB_FILE &&
        git config gc.pruneExpire 2.days.ago &&
        git gc --no-prune &&
        verbose test 1 = $(git count-objects | sed "s/ .*//") &&
@@ -163,7 +163,7 @@ test_expect_success 'gc respects gc.pruneExpire' '
 test_expect_success 'gc --prune=<date>' '
 
        add_blob &&
-       test-chmtime =-$((5001*$day)) $BLOB_FILE &&
+       test-tool chmtime =-$((5001*$day)) $BLOB_FILE &&
        git gc --prune=5002.days.ago &&
        test_path_is_file $BLOB_FILE &&
        git gc --prune=5000.days.ago &&
@@ -205,7 +205,7 @@ test_expect_success 'prune --expire=never' '
 
 test_expect_success 'gc: prune old objects after local clone' '
        add_blob &&
-       test-chmtime =-$((2*$week+1)) $BLOB_FILE &&
+       test-tool chmtime =-$((2*$week+1)) $BLOB_FILE &&
        git clone --no-hardlinks . aclone &&
        (
                cd aclone &&
index 20e2473a03b645d690b25598bc0cb2e421034b6c..f6d600fd82fd499a80f67f0a4ff1a60b4a1db1b5 100755 (executable)
@@ -284,7 +284,7 @@ test_expect_success JGIT 'jgit can read our bitmaps' '
 '
 
 test_expect_success 'splitting packs does not generate bogus bitmaps' '
-       test-genrandom foo $((1024 * 1024)) >rand &&
+       test-tool genrandom foo $((1024 * 1024)) >rand &&
        git add rand &&
        git commit -m "commit with big file" &&
        git -c pack.packSizeLimit=500k repack -adb &&
index 9372508c993e72ad99da004ca2400df81c721006..4fe4ad9d6166d9a82cb944fadfc0317b5052b973 100755 (executable)
@@ -163,8 +163,8 @@ test_expect_success 'bogus offset inside v2 extended table' '
 
 test_expect_success 'bogus OFS_DELTA in packfile' '
        # Generate a pack with a delta in it.
-       base=$(test-genrandom foo 3000 | git hash-object --stdin -w) &&
-       delta=$(test-genrandom foo 2000 | git hash-object --stdin -w) &&
+       base=$(test-tool genrandom foo 3000 | git hash-object --stdin -w) &&
+       delta=$(test-tool genrandom foo 2000 | git hash-object --stdin -w) &&
        do_pack "$base $delta" --delta-base-offset &&
        rm -f .git/objects/??/* &&
 
index f7dbdfb412f3ee139ce88e56d1cd8be166d3bbd2..f31995d3d28d9fcd590c91aed7686aef87e332af 100755 (executable)
@@ -73,7 +73,7 @@ make_pack () {
 }
 
 test_expect_success 'setup' '
-       test-genrandom base 4096 >base &&
+       test-tool genrandom base 4096 >base &&
        for i in one two
        do
                # we want shared content here to encourage deltas...
index 2ed479b712aed7a8f11c8495c0eba72788eb4f26..0f06c40eb13f31d8f06962dd1c88c5ff5810618f 100755 (executable)
@@ -47,7 +47,7 @@ test_description='pack-objects breaks long cross-pack delta chains'
 # repeatedly-modified file to generate the delta chain).
 
 test_expect_success 'create series of packs' '
-       test-genrandom foo 4096 >content &&
+       test-tool genrandom foo 4096 >content &&
        prev= &&
        for i in $(test_seq 1 10)
        do
index d375d7110d102d6b3ea194e4f09a9b5f391ed496..911eae1bf7518485ace0fbd417e3ea0bbb18a9cf 100755 (executable)
@@ -180,7 +180,7 @@ test_expect_success 'receive-pack runs auto-gc in remote repo' '
            # And create a file that follows the temporary object naming
            # convention for the auto-gc to remove
            : >.git/objects/tmp_test_object &&
-           test-chmtime =-1209601 .git/objects/tmp_test_object
+           test-tool chmtime =-1209601 .git/objects/tmp_test_object
        ) &&
        (
            cd parent &&
index da9ac0055721237f177d3d475e56ddb38b25eff1..ae5a530a2dc61a7926abfd471e3325d1638ca457 100755 (executable)
@@ -840,8 +840,8 @@ test_expect_success C_LOCALE_OUTPUT 'fetch aligned output' '
        test_commit looooooooooooong-tag &&
        (
                cd full-output &&
-               git -c fetch.output=full fetch origin 2>&1 | \
-                       grep -e "->" | cut -c 22- >../actual
+               git -c fetch.output=full fetch origin >actual 2>&1 &&
+               grep -e "->" actual | cut -c 22- >../actual
        ) &&
        cat >expect <<-\EOF &&
        master               -> origin/master
@@ -855,8 +855,8 @@ test_expect_success C_LOCALE_OUTPUT 'fetch compact output' '
        test_commit extraaa &&
        (
                cd compact &&
-               git -c fetch.output=compact fetch origin 2>&1 | \
-                       grep -e "->" | cut -c 22- >../actual
+               git -c fetch.output=compact fetch origin >actual 2>&1 &&
+               grep -e "->" actual | cut -c 22- >../actual
        ) &&
        cat >expect <<-\EOF &&
        master     -> origin/*
index 177897ea0b1e00cc4ec0f0e43510411ab19f1681..82239138d585bb859a1f2f81394cb6b6d8313bf4 100755 (executable)
@@ -1418,7 +1418,7 @@ test_expect_success 'receive.denyCurrentBranch = updateInstead' '
                cd testrepo &&
                git reset --hard HEAD^ &&
                test $(git -C .. rev-parse HEAD^) = $(git rev-parse HEAD) &&
-               test-chmtime +100 path1
+               test-tool chmtime +100 path1
        ) &&
        git push testrepo master &&
        (
index 10cb0be2b7ea42e5a1767edcd3515f933e6ef4af..0b0e987fdb73fcd7d8f54c393ee7deb15a4b5b8c 100755 (executable)
@@ -44,7 +44,7 @@ test_pack_input_limit () {
 }
 
 test_expect_success "create known-size (1024 bytes) commit" '
-       test-genrandom foo 1024 >one-k &&
+       test-tool genrandom foo 1024 >one-k &&
        git add one-k &&
        test_commit one-k
 '
index 113c87007f31abced0d93b3702f0b54f50ff4679..faaa51ccc562545c18180410e68483019a80832d 100755 (executable)
@@ -39,7 +39,7 @@ test_expect_success 'push to repo path with path separator (colon)' '
        # so make it likely for us to generate a delta by having
        # a non-trivial file with multiple versions.
 
-       test-genrandom foo 4096 >file.bin &&
+       test-tool genrandom foo 4096 >file.bin &&
        git add file.bin &&
        git commit -m bin &&
 
index 90e0d6f0fe935970c0941bfef2af39bb15d2f959..84a955770a017e68d0cc1e928929e5a043d64e86 100755 (executable)
@@ -3,10 +3,16 @@
 test_description='test git-http-backend'
 . ./test-lib.sh
 . "$TEST_DIRECTORY"/lib-httpd.sh
+
+if ! test_have_prereq CURL; then
+       skip_all='skipping raw http-backend tests, curl not available'
+       test_done
+fi
+
 start_httpd
 
 GET() {
-       curl --include "$HTTPD_URL/$SMART/repo.git/$1" >out 2>/dev/null &&
+       curl --include "$HTTPD_URL/$SMART/repo.git/$1" >out &&
        tr '\015' Q <out |
        sed '
                s/Q$//
@@ -19,7 +25,7 @@ GET() {
 POST() {
        curl --include --data "$2" \
        --header "Content-Type: application/x-$1-request" \
-       "$HTTPD_URL/smart/repo.git/$1" >out 2>/dev/null &&
+       "$HTTPD_URL/smart/repo.git/$1" >out &&
        tr '\015' Q <out |
        sed '
                s/Q$//
index 191d6d3a780325b6f3e294b6b42540569ef129d1..df822d9a3e9e7c7b4b7031ffa75716cd7ba6103a 100755 (executable)
@@ -21,7 +21,7 @@ test_expect_success CLONE_2GB 'setup' '
         do
                printf "Generating blob $i/$blobcount\r" >&2 &&
                printf "blob\nmark :$i\ndata $blobsize\n" &&
-               #test-genrandom $i $blobsize &&
+               #test-tool genrandom $i $blobsize &&
                printf "%-${blobsize}s" $i &&
                echo "M 100644 :$i $i" >> commit
                i=$(($i+1)) ||
index c01f721f13dba71fae681d6ba5100e02e58de4d8..a1fad6980b936152d599fee8cac82610404a0673 100755 (executable)
@@ -635,10 +635,10 @@ test_expect_success 'setup avoid unnecessary update, normal rename' '
 
 test_expect_success 'avoid unnecessary update, normal rename' '
        git checkout -q avoid-unnecessary-update-1^0 &&
-       test-chmtime =1000000000 rename &&
-       test-chmtime -v +0 rename >expect &&
+       test-tool chmtime =1000000000 rename &&
+       test-tool chmtime -v +0 rename >expect &&
        git merge merge-branch-1 &&
-       test-chmtime -v +0 rename >actual &&
+       test-tool chmtime -v +0 rename >actual &&
        test_cmp expect actual # "rename" should have stayed intact
 '
 
@@ -668,10 +668,10 @@ test_expect_success 'setup to test avoiding unnecessary update, with D/F conflic
 
 test_expect_success 'avoid unnecessary update, with D/F conflict' '
        git checkout -q avoid-unnecessary-update-2^0 &&
-       test-chmtime =1000000000 df &&
-       test-chmtime -v +0 df >expect &&
+       test-tool chmtime =1000000000 df &&
+       test-tool chmtime -v +0 df >expect &&
        git merge merge-branch-2 &&
-       test-chmtime -v +0 df >actual &&
+       test-tool chmtime -v +0 df >actual &&
        test_cmp expect actual # "df" should have stayed intact
 '
 
@@ -700,10 +700,10 @@ test_expect_success 'setup avoid unnecessary update, dir->(file,nothing)' '
 
 test_expect_success 'avoid unnecessary update, dir->(file,nothing)' '
        git checkout -q master^0 &&
-       test-chmtime =1000000000 df &&
-       test-chmtime -v +0 df >expect &&
+       test-tool chmtime =1000000000 df &&
+       test-tool chmtime -v +0 df >expect &&
        git merge side &&
-       test-chmtime -v +0 df >actual &&
+       test-tool chmtime -v +0 df >actual &&
        test_cmp expect actual # "df" should have stayed intact
 '
 
@@ -730,10 +730,10 @@ test_expect_success 'setup avoid unnecessary update, modify/delete' '
 
 test_expect_success 'avoid unnecessary update, modify/delete' '
        git checkout -q master^0 &&
-       test-chmtime =1000000000 file &&
-       test-chmtime -v +0 file >expect &&
+       test-tool chmtime =1000000000 file &&
+       test-tool chmtime -v +0 file >expect &&
        test_must_fail git merge side &&
-       test-chmtime -v +0 file >actual &&
+       test-tool chmtime -v +0 file >actual &&
        test_cmp expect actual # "file" should have stayed intact
 '
 
@@ -759,10 +759,10 @@ test_expect_success 'setup avoid unnecessary update, rename/add-dest' '
 
 test_expect_success 'avoid unnecessary update, rename/add-dest' '
        git checkout -q master^0 &&
-       test-chmtime =1000000000 newfile &&
-       test-chmtime -v +0 newfile >expect &&
+       test-tool chmtime =1000000000 newfile &&
+       test-tool chmtime -v +0 newfile >expect &&
        git merge side &&
-       test-chmtime -v +0 newfile >actual &&
+       test-tool chmtime -v +0 newfile >actual &&
        test_cmp expect actual # "file" should have stayed intact
 '
 
index 41b0be575d523071152c19a224a7ef914ce2ee1a..d5255dd5760389fbbabf1c2ffc787500e4184758 100755 (executable)
@@ -87,7 +87,7 @@ test_expect_success 'background auto gc does not run if gc.log is present and re
        test_must_fail git gc --auto 2>err &&
        test_i18ngrep "^error:" err &&
        test_config gc.logexpiry 5.days &&
-       test-chmtime =-345600 .git/gc.log &&
+       test-tool chmtime =-345600 .git/gc.log &&
        test_must_fail git gc --auto &&
        test_config gc.logexpiry 2.days &&
        run_and_wait_for_auto_gc &&
index 394b169eada7968875e931c5a43f25a808cfc18f..765cced60b1055e1187e1fdc1c1c881814cebbf6 100755 (executable)
@@ -73,7 +73,7 @@ for repack in '' true; do
 
        test_expect_success "simulate time passing ($title)" '
                find .git/objects -type f |
-               xargs test-chmtime -v -86400
+               xargs test-tool chmtime -v -86400
        '
 
        test_expect_success "start writing new commit with old blob ($title)" '
@@ -104,7 +104,7 @@ for repack in '' true; do
        test_expect_success "abandon objects again ($title)" '
                git reset --hard HEAD^ &&
                find .git/objects -type f |
-               xargs test-chmtime -v -86400
+               xargs test-tool chmtime -v -86400
        '
 
        test_expect_success "start writing new commit with same tree ($title)" '
index d4e6485a26eef8985856413a1bf977c95f6ec345..e96cbdb105824bf7edaf5106113b8c534765abff 100755 (executable)
@@ -21,8 +21,8 @@ test_expect_success \
 
 test_expect_success \
     'checking the commit' \
-    'git diff-tree -r -M --name-status  HEAD^ HEAD | \
-    grep "^R100..*path0/COPYING..*path1/COPYING"'
+    'git diff-tree -r -M --name-status  HEAD^ HEAD >actual &&
+    grep "^R100..*path0/COPYING..*path1/COPYING" actual'
 
 test_expect_success \
     'moving the file back into subdirectory' \
@@ -35,8 +35,8 @@ test_expect_success \
 
 test_expect_success \
     'checking the commit' \
-    'git diff-tree -r -M --name-status  HEAD^ HEAD | \
-    grep "^R100..*path1/COPYING..*path0/COPYING"'
+    'git diff-tree -r -M --name-status  HEAD^ HEAD >actual &&
+    grep "^R100..*path1/COPYING..*path0/COPYING" actual'
 
 test_expect_success \
     'mv --dry-run does not move file' \
@@ -122,10 +122,9 @@ test_expect_success \
 
 test_expect_success \
     'checking the commit' \
-    'git diff-tree -r -M --name-status  HEAD^ HEAD | \
-     grep "^R100..*path0/COPYING..*path2/COPYING" &&
-     git diff-tree -r -M --name-status  HEAD^ HEAD | \
-     grep "^R100..*path0/README..*path2/README"'
+    'git diff-tree -r -M --name-status  HEAD^ HEAD >actual &&
+     grep "^R100..*path0/COPYING..*path2/COPYING" actual &&
+     grep "^R100..*path0/README..*path2/README" actual'
 
 test_expect_success \
     'succeed when source is a prefix of destination' \
@@ -141,10 +140,9 @@ test_expect_success \
 
 test_expect_success \
     'checking the commit' \
-    'git diff-tree -r -M --name-status  HEAD^ HEAD | \
-     grep "^R100..*path2/COPYING..*path1/path2/COPYING" &&
-     git diff-tree -r -M --name-status  HEAD^ HEAD | \
-     grep "^R100..*path2/README..*path1/path2/README"'
+    'git diff-tree -r -M --name-status  HEAD^ HEAD >actual &&
+     grep "^R100..*path2/COPYING..*path1/path2/COPYING" actual &&
+     grep "^R100..*path2/README..*path1/path2/README" actual'
 
 test_expect_success \
     'do not move directory over existing directory' \
index 7cb60799be1a109e2210350137c8754a5bc4bb7d..ec4b160ddb9f966044e729f35cc1edfcc79eed14 100755 (executable)
@@ -187,7 +187,8 @@ test_expect_success 'author information is preserved' '
                        test \$GIT_COMMIT != $(git rev-parse master) || \
                        echo Hallo" \
                preserved-author) &&
-       test 1 = $(git rev-list --author="B V Uips" preserved-author | wc -l)
+       git rev-list --author="B V Uips" preserved-author >actual &&
+       test_line_count = 1 actual
 '
 
 test_expect_success "remove a certain author's commits" '
@@ -205,7 +206,8 @@ test_expect_success "remove a certain author's commits" '
        cnt1=$(git rev-list master | wc -l) &&
        cnt2=$(git rev-list removed-author | wc -l) &&
        test $cnt1 -eq $(($cnt2 + 1)) &&
-       test 0 = $(git rev-list --author="B V Uips" removed-author | wc -l)
+       git rev-list --author="B V Uips" removed-author >actual &&
+       test_line_count = 0 actual
 '
 
 test_expect_success 'barf on invalid name' '
@@ -258,7 +260,8 @@ test_expect_success 'Subdirectory filter with disappearing trees' '
        git commit -m "Re-adding foo" &&
 
        git filter-branch -f --subdirectory-filter foo &&
-       test $(git rev-list master | wc -l) = 3
+       git rev-list master >actual &&
+       test_line_count = 3 actual
 '
 
 test_expect_success 'Tag name filtering retains tag message' '
@@ -470,4 +473,18 @@ test_expect_success 'tree-filter deals with object name vs pathname ambiguity' '
        git show HEAD:$ambiguous
 '
 
+test_expect_success 'rewrite repository including refs that point at non-commit object' '
+       test_when_finished "git reset --hard original" &&
+       tree=$(git rev-parse HEAD^{tree}) &&
+       test_when_finished "git replace -d $tree" &&
+       echo A >new &&
+       git add new &&
+       new_tree=$(git write-tree) &&
+       git replace $tree $new_tree &&
+       git tag -a -m "tag to a tree" treetag $new_tree &&
+       git reset --hard HEAD &&
+       git filter-branch -f -- --all >filter-output 2>&1 &&
+       ! fgrep fatal filter-output
+'
+
 test_done
index a39e69a3ebd1c39ddf8feb861f8a39c8315aa7f8..152104412f212190c18279b64e80bb9f58242d47 100755 (executable)
@@ -821,6 +821,21 @@ test_expect_success 'moving the superproject does not break submodules' '
        )
 '
 
+test_expect_success 'moving the submodule does not break the superproject' '
+       (
+               cd addtest2 &&
+               git submodule status
+       ) >actual &&
+       sed -e "s/^ \([^ ]* repo\) .*/-\1/" <actual >expect &&
+       mv addtest2/repo addtest2/repo.bak &&
+       test_when_finished "mv addtest2/repo.bak addtest2/repo" &&
+       (
+               cd addtest2 &&
+               git submodule status
+       ) >actual &&
+       test_cmp expect actual
+'
+
 test_expect_success 'submodule add --name allows to replace a submodule with another at the same path' '
        (
                cd addtest2 &&
index 46c09c77654597b2ee501271b4688cc6137df8f1..0bde5850ac547c90dadd9e21341ebad80a1471e6 100755 (executable)
@@ -41,7 +41,7 @@ test_expect_success 'configuration parsing with error' '
        EOF
        (
                cd repo &&
-               test_must_fail test-submodule-config "" s 2>actual &&
+               test_must_fail test-tool submodule-config "" s 2>actual &&
                test_i18ngrep "bad config" actual
        )
 '
@@ -55,7 +55,7 @@ EOF
 
 test_expect_success 'test parsing and lookup of submodule config by path' '
        (cd super &&
-               test-submodule-config \
+               test-tool submodule-config \
                        HEAD^ a \
                        HEAD b \
                        HEAD^ submodule \
@@ -67,7 +67,7 @@ test_expect_success 'test parsing and lookup of submodule config by path' '
 
 test_expect_success 'test parsing and lookup of submodule config by name' '
        (cd super &&
-               test-submodule-config --name \
+               test-tool submodule-config --name \
                        HEAD^ a \
                        HEAD a \
                        HEAD^ submodule \
@@ -89,7 +89,7 @@ test_expect_success 'error in one submodule config lets continue' '
                git add .gitmodules &&
                mv .gitmodules.bak .gitmodules &&
                git commit -m "add error" &&
-               test-submodule-config \
+               test-tool submodule-config \
                        HEAD b \
                        HEAD submodule \
                                >actual &&
@@ -100,7 +100,7 @@ test_expect_success 'error in one submodule config lets continue' '
 test_expect_success 'error message contains blob reference' '
        (cd super &&
                sha1=$(git rev-parse HEAD) &&
-               test-submodule-config \
+               test-tool submodule-config \
                        HEAD b \
                        HEAD submodule \
                                2>actual_err &&
@@ -114,9 +114,9 @@ test_expect_success 'using different treeishs works' '
                git tag new_tag &&
                tree=$(git rev-parse HEAD^{tree}) &&
                commit=$(git rev-parse HEAD^{commit}) &&
-               test-submodule-config $commit b >expect &&
-               test-submodule-config $tree b >actual.1 &&
-               test-submodule-config new_tag b >actual.2 &&
+               test-tool submodule-config $commit b >expect &&
+               test-tool submodule-config $tree b >actual.1 &&
+               test-tool submodule-config new_tag b >actual.2 &&
                test_cmp expect actual.1 &&
                test_cmp expect actual.2
        )
@@ -130,7 +130,7 @@ test_expect_success 'error in history in fetchrecursesubmodule lets continue' '
                git config --unset -f .gitmodules \
                        submodule.submodule.fetchrecursesubmodules &&
                git commit -m "add error in fetchrecursesubmodules" &&
-               test-submodule-config \
+               test-tool submodule-config \
                        HEAD b \
                        HEAD submodule \
                                >actual &&
index fa61b1a4ee4a1d5ba457cb30e5cc045f724ed503..9dbbd01fc07724e378a864e3fe735269665a9bc3 100755 (executable)
@@ -52,6 +52,18 @@ test_expect_success PERL 'can use paths with --interactive' '
        git reset --hard HEAD^
 '
 
+test_expect_success 'removed files and relative paths' '
+       test_when_finished "rm -rf foo" &&
+       git init foo &&
+       >foo/foo.txt &&
+       git -C foo add foo.txt &&
+       git -C foo commit -m first &&
+       git -C foo rm foo.txt &&
+
+       mkdir -p foo/bar &&
+       git -C foo/bar commit -m second ../foo.txt
+'
+
 test_expect_success 'using invalid commit with -C' '
        test_must_fail git commit --allow-empty -C bogus
 '
index 50052e28727dab74037a115003b6083256d7f344..7afadb175a64c629214b7d6961ac345edb14ed84 100755 (executable)
@@ -1672,12 +1672,12 @@ test_expect_success '"Initial commit" should not be noted in commit template' '
 '
 
 test_expect_success '--no-optional-locks prevents index update' '
-       test-chmtime =1234567890 .git/index &&
+       test-tool chmtime =1234567890 .git/index &&
        git --no-optional-locks status &&
-       test-chmtime -v +0 .git/index >out &&
+       test-tool chmtime -v +0 .git/index >out &&
        grep ^1234567890 out &&
        git status &&
-       test-chmtime -v +0 .git/index >out &&
+       test-tool chmtime -v +0 .git/index >out &&
        ! grep ^1234567890 out
 '
 
index 987573c41fcd4aee3d5f8fd8aa587c97551c1872..8a586ab0210bf6a7fcff7729d46bb882d50fe330 100755 (executable)
@@ -90,7 +90,7 @@ test_expect_success 'unpacked objects receive timestamp of pack file' '
        tmppack=".git/objects/pack/tmp_pack" &&
        ln "$packfile" "$tmppack" &&
        git repack -A -l -d &&
-       test-chmtime -v +0 "$tmppack" "$fsha1path" "$csha1path" "$tsha1path" \
+       test-tool chmtime -v +0 "$tmppack" "$fsha1path" "$csha1path" "$tsha1path" \
                > mtimes &&
        compare_mtimes < mtimes
 '
@@ -103,7 +103,7 @@ test_expect_success 'do not bother loosening old objects' '
        git prune-packed &&
        git cat-file -p $obj1 &&
        git cat-file -p $obj2 &&
-       test-chmtime =-86400 .git/objects/pack/pack-$pack2.pack &&
+       test-tool chmtime =-86400 .git/objects/pack/pack-$pack2.pack &&
        git repack -A -d --unpack-unreachable=1.hour.ago &&
        git cat-file -p $obj1 &&
        test_must_fail git cat-file -p $obj2
@@ -117,7 +117,7 @@ test_expect_success 'keep packed objects found only in index' '
        git reset HEAD^ &&
        git reflog expire --expire=now --all &&
        git add file &&
-       test-chmtime =-86400 .git/objects/pack/* &&
+       test-tool chmtime =-86400 .git/objects/pack/* &&
        git gc --prune=1.hour.ago &&
        git cat-file blob :file
 '
index 0059a1f837882c504e717135c9c92bc5b1d7f62c..0c685d35986eebf4dd72861b650c82fb6b515b51 100755 (executable)
@@ -12,7 +12,7 @@ test_expect_success GETTEXT_LOCALE 'setup' '
 '
 
 test_have_prereq GETTEXT_LOCALE &&
-test-regex "HALLÓ" "Halló" ICASE &&
+test-tool regex "HALLÓ" "Halló" ICASE &&
 test_set_prereq REGEX_LOCALE
 
 test_expect_success REGEX_LOCALE 'grep literal string, no -F' '
index b28a028f5503508a4a09c6a07950027d253a1846..7e8894a4a70648fd12d3ab4425f1beac2c3e4641 100755 (executable)
@@ -4,7 +4,7 @@ test_description='check that example code compiles and runs'
 . ./test-lib.sh
 
 test_expect_success 'decorate' '
-       test-example-decorate
+       test-tool example-decorate
 '
 
 test_done
index 8a8ba65a2ae583aa5d0b0526e604a8f9613b5a5e..c937330a5f3a7f6b5c4d8e406564bd88dd0c889b 100755 (executable)
@@ -288,12 +288,12 @@ test_expect_success 'able to dcommit to a subdirectory' '
 
 test_expect_success 'dcommit should not fail with a touched file' '
        test_commit "commit-new-file-foo2" foo2 &&
-       test-chmtime =-60 foo &&
+       test-tool chmtime =-60 foo &&
        git svn dcommit
 '
 
 test_expect_success 'rebase should not fail with a touched file' '
-       test-chmtime =-60 foo &&
+       test-tool chmtime =-60 foo &&
        git svn rebase
 '
 
index cd480edf1606fda8d973ee3decb8e18e03356153..a735fa37170fca27b48fba218a408cb2ea6bac8a 100755 (executable)
@@ -33,8 +33,8 @@ test_expect_success 'init and fetch a moved directory' '
        git svn fetch -i thunk &&
        test "$(git rev-parse --verify refs/remotes/thunk@2)" \
           = "$(git rev-parse --verify refs/remotes/thunk~1)" &&
-       test "$(git cat-file blob refs/remotes/thunk:readme |\
-                sed -n -e "3p")" = goodbye &&
+       git cat-file blob refs/remotes/thunk:readme >actual &&
+       test "$(sed -n -e "3p" actual)" = goodbye &&
        test -z "$(git config --get svn-remote.svn.fetch \
                 "^trunk:refs/remotes/thunk@2$")"
        '
@@ -48,8 +48,8 @@ test_expect_success 'init and fetch from one svn-remote' '
         git svn fetch -i svn/thunk &&
        test "$(git rev-parse --verify refs/remotes/svn/trunk)" \
           = "$(git rev-parse --verify refs/remotes/svn/thunk~1)" &&
-       test "$(git cat-file blob refs/remotes/svn/thunk:readme |\
-                sed -n -e "3p")" = goodbye
+       git cat-file blob refs/remotes/svn/thunk:readme >actual &&
+       test "$(sed -n -e "3p" actual)" = goodbye
         '
 
 test_expect_success 'follow deleted parent' '
@@ -107,7 +107,8 @@ test_expect_success 'follow deleted directory' '
        git svn init --minimize-url -i glob "$svnrepo"/glob &&
        git svn fetch -i glob &&
        test "$(git cat-file blob refs/remotes/glob:blob/bye)" = hi &&
-       test "$(git ls-tree refs/remotes/glob | wc -l )" -eq 1
+       git ls-tree refs/remotes/glob >actual &&
+       test_line_count = 1 actual
        '
 
 # ref: r9270 of the Subversion repository: (http://svn.collab.net/repos/svn)
@@ -204,8 +205,9 @@ test_expect_success "follow-parent is atomic" '
 test_expect_success "track multi-parent paths" '
        svn_cmd cp -m "resurrect /glob" "$svnrepo"/r9270 "$svnrepo"/glob &&
        git svn multi-fetch &&
-       test $(git cat-file commit refs/remotes/glob | \
-              grep "^parent " | wc -l) -eq 2
+       git cat-file commit refs/remotes/glob >actual &&
+       grep "^parent " actual >actual2 &&
+       test_line_count = 2 actual2
        '
 
 test_expect_success "multi-fetch continues to work" "
index a94286c8ec89823805989f4363072417e9c20165..6990f64364200c75f46d9f6ee3d67ebea3549d5b 100755 (executable)
@@ -47,8 +47,8 @@ test_expect_success 'test refspec globbing' '
        git config --add svn-remote.svn.tags\
                         "tags/*/src/a:refs/remotes/tags/*" &&
        git svn multi-fetch &&
-       git log --pretty=oneline refs/remotes/tags/end | \
-           sed -e "s/^.\{41\}//" > output.end &&
+       git log --pretty=oneline refs/remotes/tags/end >actual &&
+       sed -e "s/^.\{41\}//" actual >output.end &&
        test_cmp expect.end output.end &&
        test "$(git rev-parse refs/remotes/tags/end~1)" = \
                "$(git rev-parse refs/remotes/branches/start)" &&
@@ -75,14 +75,16 @@ test_expect_success 'test left-hand-side only globbing' '
                svn_cmd commit -m "try to try"
        ) &&
        git svn fetch two &&
-       test $(git rev-list refs/remotes/two/tags/end | wc -l) -eq 6 &&
-       test $(git rev-list refs/remotes/two/branches/start | wc -l) -eq 3 &&
+       git rev-list refs/remotes/two/tags/end >actual &&
+       test_line_count = 6 actual &&
+       git rev-list refs/remotes/two/branches/start >actual &&
+       test_line_count = 3 actual &&
        test $(git rev-parse refs/remotes/two/branches/start~2) = \
             $(git rev-parse refs/remotes/two/trunk) &&
        test $(git rev-parse refs/remotes/two/tags/end~3) = \
             $(git rev-parse refs/remotes/two/branches/start) &&
-       git log --pretty=oneline refs/remotes/two/tags/end | \
-           sed -e "s/^.\{41\}//" > output.two &&
+       git log --pretty=oneline refs/remotes/two/tags/end >actual &&
+       sed -e "s/^.\{41\}//" actual >output.two &&
        test_cmp expect.two output.two
        '
 
index 8d99e848d47634ea340885fde48bc798a2c0b7a2..c1e7542a371330ecd6b27899cf3f6d4d07d78a29 100755 (executable)
@@ -47,8 +47,8 @@ test_expect_success 'test refspec globbing' '
        git config --add svn-remote.svn.tags\
                         "tags/*/src/a:refs/remotes/tags/*" &&
        git svn multi-fetch &&
-       git log --pretty=oneline refs/remotes/tags/end | \
-           sed -e "s/^.\{41\}//" > output.end &&
+       git log --pretty=oneline refs/remotes/tags/end >actual &&
+       sed -e "s/^.\{41\}//" actual >output.end &&
        test_cmp expect.end output.end &&
        test "$(git rev-parse refs/remotes/tags/end~1)" = \
                "$(git rev-parse refs/remotes/branches/v1/start)" &&
@@ -75,14 +75,16 @@ test_expect_success 'test left-hand-side only globbing' '
                svn_cmd commit -m "try to try"
        ) &&
        git svn fetch two &&
-       test $(git rev-list refs/remotes/two/tags/end | wc -l) -eq 6 &&
-       test $(git rev-list refs/remotes/two/branches/v1/start | wc -l) -eq 3 &&
+       git rev-list refs/remotes/two/tags/end >actual &&
+       test_line_count = 6 actual &&
+       git rev-list refs/remotes/two/branches/v1/start >actual &&
+       test_line_count = 3 actual &&
        test $(git rev-parse refs/remotes/two/branches/v1/start~2) = \
             $(git rev-parse refs/remotes/two/trunk) &&
        test $(git rev-parse refs/remotes/two/tags/end~3) = \
             $(git rev-parse refs/remotes/two/branches/v1/start) &&
-       git log --pretty=oneline refs/remotes/two/tags/end | \
-           sed -e "s/^.\{41\}//" > output.two &&
+       git log --pretty=oneline refs/remotes/two/tags/end >actual &&
+       sed -e "s/^.\{41\}//" actual >output.two &&
        test_cmp expect.two output.two
        '
 cat > expect.four <<EOF
@@ -124,14 +126,16 @@ test_expect_success 'test another branch' '
        git config --add svn-remote.four.tags \
                         "tags/*:refs/remotes/four/tags/*" &&
        git svn fetch four &&
-       test $(git rev-list refs/remotes/four/tags/next | wc -l) -eq 5 &&
-       test $(git rev-list refs/remotes/four/branches/v2/start | wc -l) -eq 3 &&
+       git rev-list refs/remotes/four/tags/next >actual &&
+       test_line_count = 5 actual &&
+       git rev-list refs/remotes/four/branches/v2/start >actual &&
+       test_line_count = 3 actual &&
        test $(git rev-parse refs/remotes/four/branches/v2/start~2) = \
             $(git rev-parse refs/remotes/four/trunk) &&
        test $(git rev-parse refs/remotes/four/tags/next~2) = \
             $(git rev-parse refs/remotes/four/branches/v2/start) &&
-       git log --pretty=oneline refs/remotes/four/tags/next | \
-           sed -e "s/^.\{41\}//" > output.four &&
+       git log --pretty=oneline refs/remotes/four/tags/next >actual &&
+       sed -e "s/^.\{41\}//" actual >output.four &&
        test_cmp expect.four output.four
        '
 
index dde0a3c2229abab27d1592e740db35ebfed544aa..ad37d980c91dd303ba975bc501748e05fd82efe5 100755 (executable)
@@ -21,37 +21,37 @@ uuid=161ce429-a9dd-4828-af4a-52023f968c89
 
 bar_url=http://mayonaise/svnrepo/bar
 test_expect_success 'verify metadata for /bar' "
-       git cat-file commit refs/remotes/bar | \
-          grep '^git-svn-id: $bar_url@12 $uuid$' &&
-       git cat-file commit refs/remotes/bar~1 | \
-          grep '^git-svn-id: $bar_url@11 $uuid$' &&
-       git cat-file commit refs/remotes/bar~2 | \
-          grep '^git-svn-id: $bar_url@10 $uuid$' &&
-       git cat-file commit refs/remotes/bar~3 | \
-          grep '^git-svn-id: $bar_url@9 $uuid$' &&
-       git cat-file commit refs/remotes/bar~4 | \
-          grep '^git-svn-id: $bar_url@6 $uuid$' &&
-       git cat-file commit refs/remotes/bar~5 | \
-          grep '^git-svn-id: $bar_url@1 $uuid$'
+       git cat-file commit refs/remotes/bar >actual &&
+       grep '^git-svn-id: $bar_url@12 $uuid$' actual &&
+       git cat-file commit refs/remotes/bar~1 >actual &&
+       grep '^git-svn-id: $bar_url@11 $uuid$' actual &&
+       git cat-file commit refs/remotes/bar~2 >actual &&
+       grep '^git-svn-id: $bar_url@10 $uuid$' actual &&
+       git cat-file commit refs/remotes/bar~3 >actual &&
+       grep '^git-svn-id: $bar_url@9 $uuid$' actual &&
+       git cat-file commit refs/remotes/bar~4 >actual &&
+       grep '^git-svn-id: $bar_url@6 $uuid$' actual &&
+       git cat-file commit refs/remotes/bar~5 >actual &&
+       grep '^git-svn-id: $bar_url@1 $uuid$' actual
        "
 
 e_url=http://mayonaise/svnrepo/dir/a/b/c/d/e
 test_expect_success 'verify metadata for /dir/a/b/c/d/e' "
-       git cat-file commit refs/remotes/e | \
-          grep '^git-svn-id: $e_url@1 $uuid$'
+       git cat-file commit refs/remotes/e >actual &&
+       grep '^git-svn-id: $e_url@1 $uuid$' actual
        "
 
 dir_url=http://mayonaise/svnrepo/dir
 test_expect_success 'verify metadata for /dir' "
-       git cat-file commit refs/remotes/dir | \
-          grep '^git-svn-id: $dir_url@2 $uuid$' &&
-       git cat-file commit refs/remotes/dir~1 | \
-          grep '^git-svn-id: $dir_url@1 $uuid$'
+       git cat-file commit refs/remotes/dir >actual &&
+       grep '^git-svn-id: $dir_url@2 $uuid$' actual &&
+       git cat-file commit refs/remotes/dir~1 >actual &&
+       grep '^git-svn-id: $dir_url@1 $uuid$' actual
        "
 
 test_expect_success 'find commit based on SVN revision number' "
-        git svn find-rev r12 |
-           grep $(git rev-parse HEAD)
+       git svn find-rev r12 >actual &&
+       grep $(git rev-parse HEAD) actual
         "
 
 test_expect_success 'empty rebase' "
index 22b6e5ee7d8c274b7fe60c9f10de45eaf4d3c385..6c9307355137fe86ed16552113f0d60b007e3eca 100755 (executable)
@@ -20,32 +20,32 @@ uuid=161ce429-a9dd-4828-af4a-52023f968c89
 
 bar_url=http://mayonaise/svnrepo/bar
 test_expect_success 'verify metadata for /bar' "
-       git cat-file commit refs/remotes/bar | \
-          grep '^git-svn-id: $bar_url@12 $uuid$' &&
-       git cat-file commit refs/remotes/bar~1 | \
-          grep '^git-svn-id: $bar_url@11 $uuid$' &&
-       git cat-file commit refs/remotes/bar~2 | \
-          grep '^git-svn-id: $bar_url@10 $uuid$' &&
-       git cat-file commit refs/remotes/bar~3 | \
-          grep '^git-svn-id: $bar_url@9 $uuid$' &&
-       git cat-file commit refs/remotes/bar~4 | \
-          grep '^git-svn-id: $bar_url@6 $uuid$' &&
-       git cat-file commit refs/remotes/bar~5 | \
-          grep '^git-svn-id: $bar_url@1 $uuid$'
+       git cat-file commit refs/remotes/bar >actual &&
+       grep '^git-svn-id: $bar_url@12 $uuid$' actual &&
+       git cat-file commit refs/remotes/bar~1 >actual &&
+       grep '^git-svn-id: $bar_url@11 $uuid$' actual &&
+       git cat-file commit refs/remotes/bar~2 >actual &&
+       grep '^git-svn-id: $bar_url@10 $uuid$' actual &&
+       git cat-file commit refs/remotes/bar~3 >actual &&
+       grep '^git-svn-id: $bar_url@9 $uuid$' actual &&
+       git cat-file commit refs/remotes/bar~4 >actual &&
+       grep '^git-svn-id: $bar_url@6 $uuid$' actual &&
+       git cat-file commit refs/remotes/bar~5 >actual &&
+       grep '^git-svn-id: $bar_url@1 $uuid$' actual
        "
 
 e_url=http://mayonaise/svnrepo/dir/a/b/c/d/e
 test_expect_success 'verify metadata for /dir/a/b/c/d/e' "
-       git cat-file commit refs/remotes/e | \
-          grep '^git-svn-id: $e_url@1 $uuid$'
+       git cat-file commit refs/remotes/e >actual &&
+       grep '^git-svn-id: $e_url@1 $uuid$' actual
        "
 
 dir_url=http://mayonaise/svnrepo/dir
 test_expect_success 'verify metadata for /dir' "
-       git cat-file commit refs/remotes/dir | \
-          grep '^git-svn-id: $dir_url@2 $uuid$' &&
-       git cat-file commit refs/remotes/dir~1 | \
-          grep '^git-svn-id: $dir_url@1 $uuid$'
+       git cat-file commit refs/remotes/dir >actual &&
+       grep '^git-svn-id: $dir_url@2 $uuid$' actual &&
+       git cat-file commit refs/remotes/dir~1 >actual &&
+       grep '^git-svn-id: $dir_url@1 $uuid$' actual
        "
 
 test_done
index 50bca62def6b0632cd89d1c0cfb2d98b76e6aa1d..32317d6bca5f45314a46082ecd9aa68061853904 100755 (executable)
@@ -68,7 +68,8 @@ test_debug 'gitk --all & sleep 1'
 test_expect_success 'verify pre-merge ancestry' "
        test x\$(git rev-parse --verify refs/heads/svn^2) = \
             x\$(git rev-parse --verify refs/heads/merge) &&
-       git cat-file commit refs/heads/svn^ | grep '^friend$'
+       git cat-file commit refs/heads/svn^ >actual &&
+       grep '^friend$' actual
        "
 
 test_expect_success 'git svn dcommit merges' "
@@ -82,12 +83,13 @@ test_expect_success 'verify post-merge ancestry' "
             x\$(git rev-parse --verify refs/remotes/origin/trunk) &&
        test x\$(git rev-parse --verify refs/heads/svn^2) = \
             x\$(git rev-parse --verify refs/heads/merge) &&
-       git cat-file commit refs/heads/svn^ | grep '^friend$'
+       git cat-file commit refs/heads/svn^ >actual &&
+       grep '^friend$' actual
        "
 
 test_expect_success 'verify merge commit message' "
-       git rev-list --pretty=raw -1 refs/heads/svn | \
-         grep \"    Merge branch 'merge' into svn\"
+       git rev-list --pretty=raw -1 refs/heads/svn >actual &&
+       grep \"    Merge branch 'merge' into svn\" actual
        "
 
 test_done
index 41264818ccdd85abb4b0a17c8a508d4bcbfe57f5..d8262854bbee335aec293b8f75b9979e60b91171 100755 (executable)
@@ -26,11 +26,12 @@ test_expect_success 'start import with incomplete authors file' '
 test_expect_success 'imported 2 revisions successfully' '
        (
                cd x
-               test "$(git rev-list refs/remotes/git-svn | wc -l)" -eq 2 &&
-               git rev-list -1 --pretty=raw refs/remotes/git-svn | \
-                 grep "^author BBBBBBB BBBBBBB <bb@example\.com> " &&
-               git rev-list -1 --pretty=raw refs/remotes/git-svn~1 | \
-                 grep "^author AAAAAAA AAAAAAA <aa@example\.com> "
+               git rev-list refs/remotes/git-svn >actual &&
+               test_line_count = 2 actual &&
+               git rev-list -1 --pretty=raw refs/remotes/git-svn >actual &&
+               grep "^author BBBBBBB BBBBBBB <bb@example\.com> " actual &&
+               git rev-list -1 --pretty=raw refs/remotes/git-svn~1 >actual &&
+               grep "^author AAAAAAA AAAAAAA <aa@example\.com> " actual
        )
        '
 
@@ -43,11 +44,12 @@ test_expect_success 'continues to import once authors have been added' '
        (
                cd x
                git svn fetch --authors-file=../svn-authors &&
-               test "$(git rev-list refs/remotes/git-svn | wc -l)" -eq 4 &&
-               git rev-list -1 --pretty=raw refs/remotes/git-svn | \
-                 grep "^author DDDDDDD DDDDDDD <dd@example\.com> " &&
-               git rev-list -1 --pretty=raw refs/remotes/git-svn~1 | \
-                 grep "^author CCCCCCC CCCCCCC <cc@example\.com> "
+               git rev-list refs/remotes/git-svn >actual &&
+               test_line_count = 4 actual &&
+               git rev-list -1 --pretty=raw refs/remotes/git-svn >actual &&
+               grep "^author DDDDDDD DDDDDDD <dd@example\.com> " actual &&
+               git rev-list -1 --pretty=raw refs/remotes/git-svn~1 >actual &&
+               grep "^author CCCCCCC CCCCCCC <cc@example\.com> " actual
        )
        '
 
@@ -102,12 +104,28 @@ test_expect_success !MINGW 'fresh clone with svn.authors-file in config' '
                test x"$HOME"/svn-authors = x"$(git config svn.authorsfile)" &&
                git svn clone "$svnrepo" gitconfig.clone &&
                cd gitconfig.clone &&
-               nr_ex=$(git log | grep "^Author:.*example.com" | wc -l) &&
-               nr_rev=$(git rev-list HEAD | wc -l) &&
+               git log >actual &&
+               nr_ex=$(grep "^Author:.*example.com" actual | wc -l) &&
+               git rev-list HEAD >actual &&
+               nr_rev=$(wc -l <actual) &&
                test $nr_rev -eq $nr_ex
        )
 '
 
+cat >> svn-authors <<EOF
+ff = FFFFFFF FFFFFFF <>
+EOF
+
+test_expect_success 'authors-file imported user without email' '
+       svn_cmd mkdir -m aa/branches/ff --username ff "$svnrepo/aa/branches/ff" &&
+       (
+               cd aa-work &&
+               git svn fetch --authors-file=../svn-authors &&
+               git rev-list -1 --pretty=raw refs/remotes/origin/ff | \
+                 grep "^author FFFFFFF FFFFFFF <> "
+       )
+       '
+
 test_debug 'GIT_DIR=gitconfig.clone/.git git log'
 
 test_done
index 7d7e9d46bc6bf40f52efffede6b369f052c46843..93ef44fae8f28149344b9125530807ed49727e68 100755 (executable)
@@ -9,7 +9,9 @@ test_description='git svn authors prog tests'
 
 write_script svn-authors-prog "$PERL_PATH" <<-\EOF
        $_ = shift;
-       if (s/-sub$//)  {
+       if (s/-hermit//) {
+               print "$_ <>\n";
+       } elsif (s/-sub$//)  {
                print "$_ <$_\@sub.example.com>\n";
        } else {
                print "$_ <$_\@example.com>\n";
@@ -37,44 +39,67 @@ test_expect_success 'import authors with prog and file' '
 test_expect_success 'imported 6 revisions successfully' '
        (
                cd x
-               test "$(git rev-list refs/remotes/git-svn | wc -l)" -eq 6
+               git rev-list refs/remotes/git-svn >actual &&
+               test_line_count = 6 actual
        )
 '
 
 test_expect_success 'authors-prog ran correctly' '
        (
                cd x
-               git rev-list -1 --pretty=raw refs/remotes/git-svn~1 | \
-                 grep "^author ee-foo <ee-foo@example\.com> " &&
-               git rev-list -1 --pretty=raw refs/remotes/git-svn~2 | \
-                 grep "^author dd <dd@sub\.example\.com> " &&
-               git rev-list -1 --pretty=raw refs/remotes/git-svn~3 | \
-                 grep "^author cc <cc@sub\.example\.com> " &&
-               git rev-list -1 --pretty=raw refs/remotes/git-svn~4 | \
-                 grep "^author bb <bb@example\.com> " &&
-               git rev-list -1 --pretty=raw refs/remotes/git-svn~5 | \
-                 grep "^author aa <aa@example\.com> "
+               git rev-list -1 --pretty=raw refs/remotes/git-svn~1 >actual &&
+               grep "^author ee-foo <ee-foo@example\.com> " actual &&
+               git rev-list -1 --pretty=raw refs/remotes/git-svn~2 >actual &&
+               grep "^author dd <dd@sub\.example\.com> " actual &&
+               git rev-list -1 --pretty=raw refs/remotes/git-svn~3 >actual &&
+               grep "^author cc <cc@sub\.example\.com> " actual &&
+               git rev-list -1 --pretty=raw refs/remotes/git-svn~4 >actual &&
+               grep "^author bb <bb@example\.com> " actual &&
+               git rev-list -1 --pretty=raw refs/remotes/git-svn~5 >actual &&
+               grep "^author aa <aa@example\.com> " actual
        )
 '
 
 test_expect_success 'authors-file overrode authors-prog' '
        (
                cd x
-               git rev-list -1 --pretty=raw refs/remotes/git-svn | \
-                 grep "^author FFFFFFF FFFFFFF <fFf@other\.example\.com> "
+               git rev-list -1 --pretty=raw refs/remotes/git-svn >actual &&
+               grep "^author FFFFFFF FFFFFFF <fFf@other\.example\.com> " actual
        )
 '
 
 git --git-dir=x/.git config --unset svn.authorsfile
 git --git-dir=x/.git config --unset svn.authorsprog
 
+test_expect_success 'authors-prog imported user without email' '
+       svn mkdir -m gg --username gg-hermit "$svnrepo"/gg &&
+       (
+               cd x &&
+               git svn fetch --authors-prog=../svn-authors-prog &&
+               git rev-list -1 --pretty=raw refs/remotes/git-svn | \
+                 grep "^author gg <> "
+       )
+'
+
+test_expect_success 'imported without authors-prog and authors-file' '
+       svn mkdir -m hh --username hh "$svnrepo"/hh &&
+       (
+               uuid=$(svn info "$svnrepo" |
+                       sed -n "s/^Repository UUID: //p") &&
+               cd x &&
+               git svn fetch &&
+               git rev-list -1 --pretty=raw refs/remotes/git-svn | \
+                 grep "^author hh <hh@$uuid> "
+       )
+'
+
 test_expect_success 'authors-prog handled special characters in username' '
        svn mkdir -m bad --username "xyz; touch evil" "$svnrepo"/bad &&
        (
                cd x &&
                git svn --authors-prog=../svn-authors-prog fetch &&
-               git rev-list -1 --pretty=raw refs/remotes/git-svn |
-               grep "^author xyz; touch evil <xyz; touch evil@example\.com> " &&
+               git rev-list -1 --pretty=raw refs/remotes/git-svn >actual &&
+               grep "^author xyz; touch evil <xyz; touch evil@example\.com> " actual &&
                ! test -f evil
        )
 '
index 372ef156850098928ac1ed402ab2228460af3c00..8cb2b5c69cfc89c4613fc3f7e4f2153a251433c7 100755 (executable)
@@ -16,10 +16,10 @@ test_expect_success 'load svn repo' "
        "
 
 test_expect_success 'verify uuid' "
-       git cat-file commit refs/remotes/git-svn~0 | \
-          grep '^git-svn-id: .*@2 $uuid$' &&
-       git cat-file commit refs/remotes/git-svn~1 | \
-          grep '^git-svn-id: .*@1 $uuid$'
+       git cat-file commit refs/remotes/git-svn~0 >actual &&
+       grep '^git-svn-id: .*@2 $uuid$' actual &&
+       git cat-file commit refs/remotes/git-svn~1 >actual &&
+       grep '^git-svn-id: .*@1 $uuid$' actual
        "
 
 test_done
index 8b22f2272cca47cd9187accdaed3ce1f12b6c9e1..bdf6e849993bff79a5e04c5b8a1d7df77118091f 100755 (executable)
@@ -48,8 +48,8 @@ test_expect_success 'test refspec prefixed globbing' '
        git config --add svn-remote.svn.tags\
                         "tags/t_*/src/a:refs/remotes/tags/t_*" &&
        git svn multi-fetch &&
-       git log --pretty=oneline refs/remotes/tags/t_end | \
-           sed -e "s/^.\{41\}//" >output.end &&
+       git log --pretty=oneline refs/remotes/tags/t_end >actual &&
+       sed -e "s/^.\{41\}//" actual >output.end &&
        test_cmp expect.end output.end &&
        test "$(git rev-parse refs/remotes/tags/t_end~1)" = \
                "$(git rev-parse refs/remotes/branches/b_start)" &&
@@ -78,14 +78,16 @@ test_expect_success 'test left-hand-side only prefixed globbing' '
                svn_cmd commit -m "try to try"
        ) &&
        git svn fetch two &&
-       test $(git rev-list refs/remotes/two/tags/t_end | wc -l) -eq 6 &&
-       test $(git rev-list refs/remotes/two/branches/b_start | wc -l) -eq 3 &&
+       git rev-list refs/remotes/two/tags/t_end >actual &&
+       test_line_count = 6 actual &&
+       git rev-list refs/remotes/two/branches/b_start >actual &&
+       test_line_count = 3 actual &&
        test $(git rev-parse refs/remotes/two/branches/b_start~2) = \
             $(git rev-parse refs/remotes/two/trunk) &&
        test $(git rev-parse refs/remotes/two/tags/t_end~3) = \
             $(git rev-parse refs/remotes/two/branches/b_start) &&
-       git log --pretty=oneline refs/remotes/two/tags/t_end | \
-           sed -e "s/^.\{41\}//" >output.two &&
+       git log --pretty=oneline refs/remotes/two/tags/t_end >actual &&
+       sed -e "s/^.\{41\}//" actual >output.two &&
        test_cmp expect.two output.two
        '
 
@@ -118,14 +120,16 @@ test_expect_success 'test prefixed globs match just prefix' '
                svn_cmd up
        ) &&
        git svn fetch three &&
-       test $(git rev-list refs/remotes/three/branches/b_ | wc -l) -eq 2 &&
-       test $(git rev-list refs/remotes/three/tags/t_ | wc -l) -eq 3 &&
+       git rev-list refs/remotes/three/branches/b_ >actual &&
+       test_line_count = 2 actual &&
+       git rev-list refs/remotes/three/tags/t_ >actual &&
+       test_line_count = 3 actual &&
        test $(git rev-parse refs/remotes/three/branches/b_~1) = \
             $(git rev-parse refs/remotes/three/trunk) &&
        test $(git rev-parse refs/remotes/three/tags/t_~1) = \
             $(git rev-parse refs/remotes/three/branches/b_) &&
-       git log --pretty=oneline refs/remotes/three/tags/t_ | \
-           sed -e "s/^.\{41\}//" >output.three &&
+       git log --pretty=oneline refs/remotes/three/tags/t_ >actual &&
+       sed -e "s/^.\{41\}//" actual >output.three &&
        test_cmp expect.three output.three
        '
 
@@ -186,14 +190,16 @@ test_expect_success 'test globbing in the middle of the word' '
                svn_cmd up
        ) &&
        git svn fetch five &&
-       test $(git rev-list refs/remotes/five/branches/abcde | wc -l) -eq 2 &&
-       test $(git rev-list refs/remotes/five/tags/fghij | wc -l) -eq 3 &&
+       git rev-list refs/remotes/five/branches/abcde >actual &&
+       test_line_count = 2 actual &&
+       git rev-list refs/remotes/five/tags/fghij >actual &&
+       test_line_count = 3 actual &&
        test $(git rev-parse refs/remotes/five/branches/abcde~1) = \
             $(git rev-parse refs/remotes/five/trunk) &&
        test $(git rev-parse refs/remotes/five/tags/fghij~1) = \
             $(git rev-parse refs/remotes/five/branches/abcde) &&
-       git log --pretty=oneline refs/remotes/five/tags/fghij | \
-           sed -e "s/^.\{41\}//" >output.five &&
+       git log --pretty=oneline refs/remotes/five/tags/fghij >actual &&
+       sed -e "s/^.\{41\}//" actual >output.five &&
        test_cmp expect.five output.five
        '
 
index e4d06accc458191d0d52fe325b3118ac019e96c2..dc79df7b042b75ca192ff1a860eb0c22a9059a8e 100755 (executable)
@@ -2654,7 +2654,7 @@ test_expect_success 'R: corrupt lines do not mess marks file' '
 ##
 test_expect_success 'R: blob bigger than threshold' '
        blobsize=$((2*1024*1024 + 53)) &&
-       test-genrandom bar $blobsize >expect &&
+       test-tool genrandom bar $blobsize >expect &&
        cat >input <<-INPUT_END &&
        commit refs/heads/big-file
        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
index 866ddf60581e3fea1afdbe28e71e7f3137da5722..d5679ffb873b4657cd953f7b318a231f56671f20 100755 (executable)
@@ -43,20 +43,20 @@ test_expect_success 'fast-export | fast-import' '
        MUSS=$(git rev-parse --verify muss) &&
        mkdir new &&
        git --git-dir=new/.git init &&
-       git fast-export --all |
+       git fast-export --all >actual &&
        (cd new &&
         git fast-import &&
         test $MASTER = $(git rev-parse --verify refs/heads/master) &&
         test $REIN = $(git rev-parse --verify refs/tags/rein) &&
         test $WER = $(git rev-parse --verify refs/heads/wer) &&
-        test $MUSS = $(git rev-parse --verify refs/tags/muss))
+        test $MUSS = $(git rev-parse --verify refs/tags/muss)) <actual
 
 '
 
 test_expect_success 'fast-export master~2..master' '
 
-       git fast-export master~2..master |
-               sed "s/master/partial/" |
+       git fast-export master~2..master >actual &&
+       sed "s/master/partial/" actual |
                (cd new &&
                 git fast-import &&
                 test $MASTER != $(git rev-parse --verify refs/heads/partial) &&
@@ -74,11 +74,12 @@ test_expect_success 'iso-8859-1' '
        test_tick &&
        echo rosten >file &&
        git commit -s -m den file &&
-       git fast-export wer^..wer |
-               sed "s/wer/i18n/" |
+       git fast-export wer^..wer >iso8859-1.fi &&
+       sed "s/wer/i18n/" iso8859-1.fi |
                (cd new &&
                 git fast-import &&
-                git cat-file commit i18n | grep "Áéí óú")
+                git cat-file commit i18n >actual &&
+                grep "Áéí óú" actual)
 
 '
 test_expect_success 'import/export-marks' '
@@ -87,20 +88,14 @@ test_expect_success 'import/export-marks' '
        git fast-export --export-marks=tmp-marks HEAD &&
        test -s tmp-marks &&
        test_line_count = 3 tmp-marks &&
-       test $(
-               git fast-export --import-marks=tmp-marks\
-               --export-marks=tmp-marks HEAD |
-               grep ^commit |
-               wc -l) \
-       -eq 0 &&
+       git fast-export --import-marks=tmp-marks \
+               --export-marks=tmp-marks HEAD >actual &&
+       test $(grep ^commit actual | wc -l) -eq 0 &&
        echo change > file &&
        git commit -m "last commit" file &&
-       test $(
-               git fast-export --import-marks=tmp-marks \
-               --export-marks=tmp-marks HEAD |
-               grep ^commit\  |
-               wc -l) \
-       -eq 1 &&
+       git fast-export --import-marks=tmp-marks \
+               --export-marks=tmp-marks HEAD >actual &&
+       test $(grep ^commit\  actual | wc -l) -eq 1 &&
        test_line_count = 4 tmp-marks
 
 '
@@ -184,7 +179,7 @@ test_expect_success 'submodule fast-export | fast-import' '
        rm -rf new &&
        mkdir new &&
        git --git-dir=new/.git init &&
-       git fast-export --signed-tags=strip --all |
+       git fast-export --signed-tags=strip --all >actual &&
        (cd new &&
         git fast-import &&
         test "$SUBENT1" = "$(git ls-tree refs/heads/master^ sub)" &&
@@ -192,7 +187,7 @@ test_expect_success 'submodule fast-export | fast-import' '
         git checkout master &&
         git submodule init &&
         git submodule update &&
-        cmp sub/file ../sub/file)
+        cmp sub/file ../sub/file) <actual
 
 '
 
@@ -367,12 +362,14 @@ test_expect_success 'path limiting with import-marks does not lose unmodified fi
        echo more content >> file &&
        test_tick &&
        git commit -mnext file &&
-       git fast-export --import-marks=marks simple -- file file0 | grep file0
+       git fast-export --import-marks=marks simple -- file file0 >actual &&
+       grep file0 actual
 '
 
 test_expect_success 'full-tree re-shows unmodified files'        '
        git checkout -f simple &&
-       test $(git fast-export --full-tree simple | grep -c file0) -eq 3
+       git fast-export --full-tree simple >actual &&
+       test $(grep -c file0 actual) -eq 3
 '
 
 test_expect_success 'set-up a few more tags for tag export tests' '
@@ -505,8 +502,8 @@ test_expect_success 'refs are updated even if no commits need to be exported' '
 '
 
 test_expect_success 'use refspec' '
-       git fast-export --refspec refs/heads/master:refs/heads/foobar master | \
-               grep "^commit " | sort | uniq > actual &&
+       git fast-export --refspec refs/heads/master:refs/heads/foobar master >actual2 &&
+       grep "^commit " actual2 | sort | uniq >actual &&
        echo "commit refs/heads/foobar" > expected &&
        test_cmp expected actual
 '
@@ -534,7 +531,8 @@ test_expect_success 'when using -C, do not declare copy when source of copy is a
        git -C src commit -m 2nd_commit &&
 
        test_create_repo dst &&
-       git -C src fast-export --all -C | git -C dst fast-import &&
+       git -C src fast-export --all -C >actual &&
+       git -C dst fast-import <actual &&
        git -C src show >expected &&
        git -C dst show >actual &&
        test_cmp expected actual
index eb9a8ed197b4c6383a4c688f5e5c3a3fcb102b12..1fc9b33aeb5f095816fba72e85c94f0455994418 100755 (executable)
@@ -237,7 +237,7 @@ test_expect_success 'ignore apple' '
        build_gendouble &&
        (
                cd "$cli" &&
-               test-genrandom apple 1024 >double.png &&
+               test-tool genrandom apple 1024 >double.png &&
                "$PYTHON_PATH" "$TRASH_DIRECTORY/gendouble.py" >%double.png &&
                p4 add -t apple double.png &&
                p4 submit -d appledouble
index d950c7d665498c484f83d127cd2363def5169a89..d5c367510049607ce33db73ffc1869a0652fe663 100755 (executable)
@@ -28,7 +28,7 @@ test_expect_success 'shell metachars in filenames' '
                echo f2 >"file with spaces" &&
                git add "file with spaces" &&
                git commit -m "add files" &&
-               P4EDITOR="test-chmtime +5" git p4 submit
+               P4EDITOR="test-tool chmtime +5" git p4 submit
        ) &&
        (
                cd "$cli" &&
@@ -47,7 +47,7 @@ test_expect_success 'deleting with shell metachars' '
                git rm foo\$bar &&
                git rm file\ with\ spaces &&
                git commit -m "remove files" &&
-               P4EDITOR="test-chmtime +5" git p4 submit
+               P4EDITOR="test-tool chmtime +5" git p4 submit
        ) &&
        (
                cd "$cli" &&
index bda222aa0270f3a93fa494b308aa174ebc942eca..783c6ad1653142d174e4ddc6d49e1f631121be51 100755 (executable)
@@ -53,7 +53,7 @@ test_expect_success 'preserve users' '
                git commit --author "Alice <alice@example.com>" -m "a change by alice" file1 &&
                git commit --author "Bob <bob@example.com>" -m "a change by bob" file2 &&
                git config git-p4.skipSubmitEditCheck true &&
-               P4EDITOR="test-chmtime +5" P4USER=alice P4PASSWD=secret &&
+               P4EDITOR="test-tool chmtime +5" P4USER=alice P4PASSWD=secret &&
                export P4EDITOR P4USER P4PASSWD &&
                git p4 commit --preserve-user &&
                p4_check_commit_author file1 alice &&
@@ -71,7 +71,7 @@ test_expect_success 'refuse to preserve users without perms' '
                git config git-p4.skipSubmitEditCheck true &&
                echo "username-noperms: a change by alice" >>file1 &&
                git commit --author "Alice <alice@example.com>" -m "perms: a change by alice" file1 &&
-               P4EDITOR="test-chmtime +5" P4USER=bob P4PASSWD=secret &&
+               P4EDITOR="test-tool chmtime +5" P4USER=bob P4PASSWD=secret &&
                export P4EDITOR P4USER P4PASSWD &&
                test_must_fail git p4 commit --preserve-user &&
                ! git diff --exit-code HEAD..p4/master
@@ -89,7 +89,7 @@ test_expect_success 'preserve user where author is unknown to p4' '
                git commit --author "Bob <bob@example.com>" -m "preserve: a change by bob" file1 &&
                echo "username-unknown: a change by charlie" >>file1 &&
                git commit --author "Charlie <charlie@example.com>" -m "preserve: a change by charlie" file1 &&
-               P4EDITOR="test-chmtime +5" P4USER=alice P4PASSWD=secret &&
+               P4EDITOR="test-tool chmtime +5" P4USER=alice P4PASSWD=secret &&
                export P4EDITOR P4USER P4PASSWD &&
                test_must_fail git p4 commit --preserve-user &&
                ! git diff --exit-code HEAD..p4/master &&
index 6dc6df032ec0c15b39dccd24ade52580fc115add..3c22f74bd436b7c6d94d5c29d5b2e3e3510d58e6 100755 (executable)
@@ -26,7 +26,7 @@ test_expect_success 'EDITOR with options' '
                cd "$git" &&
                echo change >file1 &&
                git commit -m "change" file1 &&
-               P4EDITOR=": >\"$git/touched\" && test-chmtime +5" git p4 submit &&
+               P4EDITOR=": >\"$git/touched\" && test-tool chmtime +5" git p4 submit &&
                test_path_is_file "$git/touched"
        )
 '
index b7f5b1e632fb27a0448239361d6b4207be4b9908..1b34caa1e1a5e86cd2edccbb1559009b35022e10 100755 (executable)
@@ -1454,6 +1454,12 @@ test_expect_success 'completion used <cmd> completion for alias: !f() { : git <c
        EOF
 '
 
+test_expect_success 'completion without explicit _git_xxx function' '
+       test_completion "git version --" <<-\EOF
+       --build-options Z
+       EOF
+'
+
 test_expect_failure 'complete with tilde expansion' '
        git init tmp && cd tmp &&
        test_when_finished "cd .. && rm -rf tmp" &&
index b895366feef6027ac00bf47271b2530e8b7e7162..7d620bf2a9a26c325de035c8d9d85323d5088357 100644 (file)
@@ -782,11 +782,8 @@ verbose () {
 # otherwise.
 
 test_must_be_empty () {
-       if ! test -f "$1"
-       then
-               echo "'$1' is missing"
-               return 1
-       elif test -s "$1"
+       test_path_is_file "$1" &&
+       if test -s "$1"
        then
                echo "'$1' is not empty, it contains:"
                cat "$1"
index 7740d511d289f44bb1313308fe49d5894f64b3c2..ea2bbaaa7ab4dc77d0ef13cafbe45d1b12bd67e8 100644 (file)
@@ -963,10 +963,10 @@ test -d "$GIT_BUILD_DIR"/templates/blt || {
        error "You haven't built things yet, have you?"
 }
 
-if ! test -x "$GIT_BUILD_DIR"/t/helper/test-chmtime
+if ! test -x "$GIT_BUILD_DIR"/t/helper/test-tool
 then
-       echo >&2 'You need to build test-chmtime:'
-       echo >&2 'Run "make t/helper/test-chmtime" in the source (toplevel) directory'
+       echo >&2 'You need to build test-tool:'
+       echo >&2 'Run "make t/helper/test-tool" in the source (toplevel) directory'
        exit 1
 fi
 
@@ -1206,5 +1206,9 @@ test_lazy_prereq LONG_IS_64BIT '
        test 8 -le "$(build_option sizeof-long)"
 '
 
-test_lazy_prereq TIME_IS_64BIT 'test-date is64bit'
-test_lazy_prereq TIME_T_IS_64BIT 'test-date time_t-is64bit'
+test_lazy_prereq TIME_IS_64BIT 'test-tool date is64bit'
+test_lazy_prereq TIME_T_IS_64BIT 'test-tool date time_t-is64bit'
+
+test_lazy_prereq CURL '
+       curl --version
+'
diff --git a/tag.c b/tag.c
index 66210fd4772778ac4c95925ec4670717dd27da62..86b1dcbb8270e944ac643a39835d490bbaf35b20 100644 (file)
--- a/tag.c
+++ b/tag.c
@@ -41,20 +41,20 @@ int gpg_verify_tag(const struct object_id *oid, const char *name_to_report,
        unsigned long size;
        int ret;
 
-       type = sha1_object_info(oid->hash, NULL);
+       type = oid_object_info(oid, NULL);
        if (type != OBJ_TAG)
                return error("%s: cannot verify a non-tag object of type %s.",
                                name_to_report ?
                                name_to_report :
-                               find_unique_abbrev(oid->hash, DEFAULT_ABBREV),
+                               find_unique_abbrev(oid, DEFAULT_ABBREV),
                                type_name(type));
 
-       buf = read_sha1_file(oid->hash, &type, &size);
+       buf = read_object_file(oid, &type, &size);
        if (!buf)
                return error("%s: unable to read file.",
                                name_to_report ?
                                name_to_report :
-                               find_unique_abbrev(oid->hash, DEFAULT_ABBREV));
+                               find_unique_abbrev(oid, DEFAULT_ABBREV));
 
        ret = run_gpg_verify(buf, size, flags);
 
@@ -182,7 +182,7 @@ int parse_tag(struct tag *item)
 
        if (item->object.parsed)
                return 0;
-       data = read_sha1_file(item->object.oid.hash, &type, &size);
+       data = read_object_file(&item->object.oid, &type, &size);
        if (!data)
                return error("Could not read %s",
                             oid_to_hex(&item->object.oid));
index b2d9280f104aec7095dd2b37ff1f7165355b5388..fea3f55545cbf193f823db468c7640bfd48d9bbd 100644 (file)
@@ -6,6 +6,7 @@
 #include "strbuf.h"
 #include "argv-array.h"
 #include "quote.h"
+#include "object-store.h"
 
 struct tmp_objdir {
        struct strbuf path;
diff --git a/trace.c b/trace.c
index 7f3b08e148044c6c94cbef03ae265e134391357a..fc623e91fdd7ed8268922ae0460cfbd6903f3800 100644 (file)
--- a/trace.c
+++ b/trace.c
@@ -26,6 +26,7 @@
 
 struct trace_key trace_default_key = { "GIT_TRACE", 0, 0, 0 };
 struct trace_key trace_perf_key = TRACE_KEY_INIT(PERFORMANCE);
+struct trace_key trace_setup_key = TRACE_KEY_INIT(SETUP);
 
 /* Get a trace file descriptor from "key" env variable. */
 static int get_trace_fd(struct trace_key *key)
@@ -300,11 +301,10 @@ static const char *quote_crnl(const char *path)
 /* FIXME: move prefix to startup_info struct and get rid of this arg */
 void trace_repo_setup(const char *prefix)
 {
-       static struct trace_key key = TRACE_KEY_INIT(SETUP);
        const char *git_work_tree;
        char *cwd;
 
-       if (!trace_want(&key))
+       if (!trace_want(&trace_setup_key))
                return;
 
        cwd = xgetcwd();
@@ -315,11 +315,11 @@ void trace_repo_setup(const char *prefix)
        if (!prefix)
                prefix = "(null)";
 
-       trace_printf_key(&key, "setup: git_dir: %s\n", quote_crnl(get_git_dir()));
-       trace_printf_key(&key, "setup: git_common_dir: %s\n", quote_crnl(get_git_common_dir()));
-       trace_printf_key(&key, "setup: worktree: %s\n", quote_crnl(git_work_tree));
-       trace_printf_key(&key, "setup: cwd: %s\n", quote_crnl(cwd));
-       trace_printf_key(&key, "setup: prefix: %s\n", quote_crnl(prefix));
+       trace_printf_key(&trace_setup_key, "setup: git_dir: %s\n", quote_crnl(get_git_dir()));
+       trace_printf_key(&trace_setup_key, "setup: git_common_dir: %s\n", quote_crnl(get_git_common_dir()));
+       trace_printf_key(&trace_setup_key, "setup: worktree: %s\n", quote_crnl(git_work_tree));
+       trace_printf_key(&trace_setup_key, "setup: cwd: %s\n", quote_crnl(cwd));
+       trace_printf_key(&trace_setup_key, "setup: prefix: %s\n", quote_crnl(prefix));
 
        free(cwd);
 }
diff --git a/trace.h b/trace.h
index 88055abef7342ee638f6597a6628bcdf4baeace9..2b6a1bc17c2cc1a8642d8c7bd460808638f28d77 100644 (file)
--- a/trace.h
+++ b/trace.h
@@ -15,6 +15,7 @@ extern struct trace_key trace_default_key;
 
 #define TRACE_KEY_INIT(name) { "GIT_TRACE_" #name, 0, 0, 0 }
 extern struct trace_key trace_perf_key;
+extern struct trace_key trace_setup_key;
 
 extern void trace_repo_setup(const char *prefix);
 extern int trace_want(struct trace_key *key);
index 00d48b5b565b0edfa826a8c426e76cfc60a2f0a1..94eccf29aa3f9758f5acaa9daddedcd559ad3915 100644 (file)
@@ -18,6 +18,7 @@
 #include "sha1-array.h"
 #include "sigchain.h"
 #include "transport-internal.h"
+#include "object-store.h"
 
 static void set_upstreams(struct transport *transport, struct ref *refs,
        int pretend)
@@ -367,7 +368,7 @@ static void print_ok_ref_status(struct ref *ref, int porcelain, int summary_widt
                char type;
                const char *msg;
 
-               strbuf_add_unique_abbrev(&quickref, ref->old_oid.hash,
+               strbuf_add_unique_abbrev(&quickref, &ref->old_oid,
                                         DEFAULT_ABBREV);
                if (ref->forced_update) {
                        strbuf_addstr(&quickref, "...");
@@ -378,7 +379,7 @@ static void print_ok_ref_status(struct ref *ref, int porcelain, int summary_widt
                        type = ' ';
                        msg = NULL;
                }
-               strbuf_add_unique_abbrev(&quickref, ref->new_oid.hash,
+               strbuf_add_unique_abbrev(&quickref, &ref->new_oid,
                                         DEFAULT_ABBREV);
 
                print_ref_status(type, quickref.buf, ref, ref->peer_ref, msg,
@@ -461,7 +462,7 @@ static int print_one_push_status(struct ref *ref, const char *dest, int count,
 static int measure_abbrev(const struct object_id *oid, int sofar)
 {
        char hex[GIT_MAX_HEXSZ + 1];
-       int w = find_unique_abbrev_r(hex, oid->hash, DEFAULT_ABBREV);
+       int w = find_unique_abbrev_r(hex, oid, DEFAULT_ABBREV);
 
        return (w < sofar) ? sofar : w;
 }
index 63a87ed666bbb10cb3c2bd0e27117ac696e7d1b3..e11b3063afa610239162dc45c24528dd144c4759 100644 (file)
@@ -84,8 +84,7 @@ void *fill_tree_descriptor(struct tree_desc *desc, const struct object_id *oid)
        void *buf = NULL;
 
        if (oid) {
-               buf = read_object_with_reference(oid->hash, tree_type, &size,
-                                                NULL);
+               buf = read_object_with_reference(oid, tree_type, &size, NULL);
                if (!buf)
                        die("unable to read tree %s", oid_to_hex(oid));
        }
@@ -492,7 +491,7 @@ struct dir_state {
        unsigned char sha1[20];
 };
 
-static int find_tree_entry(struct tree_desc *t, const char *name, unsigned char *result, unsigned *mode)
+static int find_tree_entry(struct tree_desc *t, const char *name, struct object_id *result, unsigned *mode)
 {
        int namelen = strlen(name);
        while (t->size) {
@@ -511,7 +510,7 @@ static int find_tree_entry(struct tree_desc *t, const char *name, unsigned char
                if (cmp < 0)
                        break;
                if (entrylen == namelen) {
-                       hashcpy(result, oid->hash);
+                       oidcpy(result, oid);
                        return 0;
                }
                if (name[entrylen] != '/')
@@ -519,27 +518,27 @@ static int find_tree_entry(struct tree_desc *t, const char *name, unsigned char
                if (!S_ISDIR(*mode))
                        break;
                if (++entrylen == namelen) {
-                       hashcpy(result, oid->hash);
+                       oidcpy(result, oid);
                        return 0;
                }
-               return get_tree_entry(oid->hash, name + entrylen, result, mode);
+               return get_tree_entry(oid, name + entrylen, result, mode);
        }
        return -1;
 }
 
-int get_tree_entry(const unsigned char *tree_sha1, const char *name, unsigned char *sha1, unsigned *mode)
+int get_tree_entry(const struct object_id *tree_oid, const char *name, struct object_id *oid, unsigned *mode)
 {
        int retval;
        void *tree;
        unsigned long size;
-       unsigned char root[20];
+       struct object_id root;
 
-       tree = read_object_with_reference(tree_sha1, tree_type, &size, root);
+       tree = read_object_with_reference(tree_oid, tree_type, &size, &root);
        if (!tree)
                return -1;
 
        if (name[0] == '\0') {
-               hashcpy(sha1, root);
+               oidcpy(oid, &root);
                free(tree);
                return 0;
        }
@@ -549,7 +548,7 @@ int get_tree_entry(const unsigned char *tree_sha1, const char *name, unsigned ch
        } else {
                struct tree_desc t;
                init_tree_desc(&t, tree, size);
-               retval = find_tree_entry(&t, name, sha1, mode);
+               retval = find_tree_entry(&t, name, oid, mode);
        }
        free(tree);
        return retval;
@@ -583,14 +582,14 @@ enum follow_symlinks_result get_tree_entry_follow_symlinks(unsigned char *tree_s
        struct dir_state *parents = NULL;
        size_t parents_alloc = 0;
        size_t i, parents_nr = 0;
-       unsigned char current_tree_sha1[20];
+       struct object_id current_tree_oid;
        struct strbuf namebuf = STRBUF_INIT;
        struct tree_desc t;
        int follows_remaining = GET_TREE_ENTRY_FOLLOW_SYMLINKS_MAX_LINKS;
 
        init_tree_desc(&t, NULL, 0UL);
        strbuf_addstr(&namebuf, name);
-       hashcpy(current_tree_sha1, tree_sha1);
+       hashcpy(current_tree_oid.hash, tree_sha1);
 
        while (1) {
                int find_result;
@@ -599,22 +598,22 @@ enum follow_symlinks_result get_tree_entry_follow_symlinks(unsigned char *tree_s
 
                if (!t.buffer) {
                        void *tree;
-                       unsigned char root[20];
+                       struct object_id root;
                        unsigned long size;
-                       tree = read_object_with_reference(current_tree_sha1,
+                       tree = read_object_with_reference(&current_tree_oid,
                                                          tree_type, &size,
-                                                         root);
+                                                         &root);
                        if (!tree)
                                goto done;
 
                        ALLOC_GROW(parents, parents_nr + 1, parents_alloc);
                        parents[parents_nr].tree = tree;
                        parents[parents_nr].size = size;
-                       hashcpy(parents[parents_nr].sha1, root);
+                       hashcpy(parents[parents_nr].sha1, root.hash);
                        parents_nr++;
 
                        if (namebuf.buf[0] == '\0') {
-                               hashcpy(result, root);
+                               hashcpy(result, root.hash);
                                retval = FOUND;
                                goto done;
                        }
@@ -671,14 +670,14 @@ enum follow_symlinks_result get_tree_entry_follow_symlinks(unsigned char *tree_s
 
                /* Look up the first (or only) path component in the tree. */
                find_result = find_tree_entry(&t, namebuf.buf,
-                                             current_tree_sha1, mode);
+                                             &current_tree_oid, mode);
                if (find_result) {
                        goto done;
                }
 
                if (S_ISDIR(*mode)) {
                        if (!remainder) {
-                               hashcpy(result, current_tree_sha1);
+                               hashcpy(result, current_tree_oid.hash);
                                retval = FOUND;
                                goto done;
                        }
@@ -688,7 +687,7 @@ enum follow_symlinks_result get_tree_entry_follow_symlinks(unsigned char *tree_s
                                      1 + first_slash - namebuf.buf);
                } else if (S_ISREG(*mode)) {
                        if (!remainder) {
-                               hashcpy(result, current_tree_sha1);
+                               hashcpy(result, current_tree_oid.hash);
                                retval = FOUND;
                        } else {
                                retval = NOT_DIR;
@@ -714,8 +713,8 @@ enum follow_symlinks_result get_tree_entry_follow_symlinks(unsigned char *tree_s
                         */
                        retval = DANGLING_SYMLINK;
 
-                       contents = read_sha1_file(current_tree_sha1, &type,
-                                                 &link_len);
+                       contents = read_object_file(&current_tree_oid, &type,
+                                                   &link_len);
 
                        if (!contents)
                                goto done;
index b6bd1b4ccfbb8bb69c464ea687c63a2058a424b8..4617deeb0e09e71c7ba7231192ece055eccb2dde 100644 (file)
@@ -79,7 +79,7 @@ struct traverse_info {
        int show_all_errors;
 };
 
-int get_tree_entry(const unsigned char *, const char *, unsigned char *, unsigned *);
+int get_tree_entry(const struct object_id *, const char *, struct object_id *, unsigned *);
 extern char *make_traverse_path(char *path, const struct traverse_info *info, const struct name_entry *n);
 extern void setup_traverse_info(struct traverse_info *info, const char *base);
 
diff --git a/tree.c b/tree.c
index b224115e0f4d61368560eba406a04f0259b7c4f0..1c68ea586bd30d3e3389efa1c83f25ed607d1d80 100644 (file)
--- a/tree.c
+++ b/tree.c
@@ -10,7 +10,7 @@
 const char *tree_type = "tree";
 
 static int read_one_entry_opt(struct index_state *istate,
-                             const unsigned char *sha1,
+                             const struct object_id *oid,
                              const char *base, int baselen,
                              const char *pathname,
                              unsigned mode, int stage, int opt)
@@ -31,16 +31,16 @@ static int read_one_entry_opt(struct index_state *istate,
        ce->ce_namelen = baselen + len;
        memcpy(ce->name, base, baselen);
        memcpy(ce->name + baselen, pathname, len+1);
-       hashcpy(ce->oid.hash, sha1);
+       oidcpy(&ce->oid, oid);
        return add_index_entry(istate, ce, opt);
 }
 
-static int read_one_entry(const unsigned char *sha1, struct strbuf *base,
+static int read_one_entry(const struct object_id *oid, struct strbuf *base,
                          const char *pathname, unsigned mode, int stage,
                          void *context)
 {
        struct index_state *istate = context;
-       return read_one_entry_opt(istate, sha1, base->buf, base->len, pathname,
+       return read_one_entry_opt(istate, oid, base->buf, base->len, pathname,
                                  mode, stage,
                                  ADD_CACHE_OK_TO_ADD|ADD_CACHE_SKIP_DFCHECK);
 }
@@ -49,12 +49,12 @@ static int read_one_entry(const unsigned char *sha1, struct strbuf *base,
  * This is used when the caller knows there is no existing entries at
  * the stage that will conflict with the entry being added.
  */
-static int read_one_entry_quick(const unsigned char *sha1, struct strbuf *base,
+static int read_one_entry_quick(const struct object_id *oid, struct strbuf *base,
                                const char *pathname, unsigned mode, int stage,
                                void *context)
 {
        struct index_state *istate = context;
-       return read_one_entry_opt(istate, sha1, base->buf, base->len, pathname,
+       return read_one_entry_opt(istate, oid, base->buf, base->len, pathname,
                                  mode, stage,
                                  ADD_CACHE_JUST_APPEND);
 }
@@ -83,7 +83,7 @@ static int read_tree_1(struct tree *tree, struct strbuf *base,
                                continue;
                }
 
-               switch (fn(entry.oid->hash, base,
+               switch (fn(entry.oid, base,
                           entry.path, entry.mode, stage, context)) {
                case 0:
                        continue;
@@ -219,7 +219,7 @@ int parse_tree_gently(struct tree *item, int quiet_on_missing)
 
        if (item->object.parsed)
                return 0;
-       buffer = read_sha1_file(item->object.oid.hash, &type, &size);
+       buffer = read_object_file(&item->object.oid, &type, &size);
        if (!buffer)
                return quiet_on_missing ? -1 :
                        error("Could not read %s",
diff --git a/tree.h b/tree.h
index 744e6dc2ac883adfa0e079f5f84f45a45e22b59d..e2a80be4ef87e35d895e8591a0f8a75df347d347 100644 (file)
--- a/tree.h
+++ b/tree.h
@@ -27,7 +27,7 @@ void free_tree_buffer(struct tree *tree);
 struct tree *parse_tree_indirect(const struct object_id *oid);
 
 #define READ_TREE_RECURSIVE 1
-typedef int (*read_tree_fn_t)(const unsigned char *, struct strbuf *, const char *, unsigned int, int, void *);
+typedef int (*read_tree_fn_t)(const struct object_id *, struct strbuf *, const char *, unsigned int, int, void *);
 
 extern int read_tree_recursive(struct tree *tree,
                               const char *base, int baselen,
index 66f4234af1149618b47786f3b623916be7c02c74..50815e5faffba0e9df861dbc4881e9fbffd7a941 100644 (file)
@@ -1188,7 +1188,7 @@ static void abbrev_sha1_in_line(struct strbuf *line)
                strbuf_trim(split[1]);
                if (!get_oid(split[1]->buf, &oid)) {
                        strbuf_reset(split[1]);
-                       strbuf_add_unique_abbrev(split[1], oid.hash,
+                       strbuf_add_unique_abbrev(split[1], &oid,
                                                 DEFAULT_ABBREV);
                        strbuf_addch(split[1], ' ');
                        strbuf_reset(line);
@@ -1350,7 +1350,7 @@ static void show_cherry_pick_in_progress(struct wt_status *s,
                                        const char *color)
 {
        status_printf_ln(s, color, _("You are currently cherry-picking commit %s."),
-                       find_unique_abbrev(state->cherry_pick_head_sha1, DEFAULT_ABBREV));
+                       find_unique_abbrev(&state->cherry_pick_head_oid, DEFAULT_ABBREV));
        if (s->hints) {
                if (has_unmerged(s))
                        status_printf_ln(s, color,
@@ -1369,7 +1369,7 @@ static void show_revert_in_progress(struct wt_status *s,
                                        const char *color)
 {
        status_printf_ln(s, color, _("You are currently reverting commit %s."),
-                        find_unique_abbrev(state->revert_head_sha1, DEFAULT_ABBREV));
+                        find_unique_abbrev(&state->revert_head_oid, DEFAULT_ABBREV));
        if (s->hints) {
                if (has_unmerged(s))
                        status_printf_ln(s, color,
@@ -1422,7 +1422,7 @@ static char *get_branch(const struct worktree *wt, const char *path)
                ;
        else if (!get_oid_hex(sb.buf, &oid)) {
                strbuf_reset(&sb);
-               strbuf_add_unique_abbrev(&sb, oid.hash, DEFAULT_ABBREV);
+               strbuf_add_unique_abbrev(&sb, &oid, DEFAULT_ABBREV);
        } else if (!strcmp(sb.buf, "detached HEAD")) /* rebase */
                goto got_nothing;
        else                    /* bisect */
@@ -1459,7 +1459,7 @@ static int grab_1st_switch(struct object_id *ooid, struct object_id *noid,
        if (!strcmp(cb->buf.buf, "HEAD")) {
                /* HEAD is relative. Resolve it to the right reflog entry. */
                strbuf_reset(&cb->buf);
-               strbuf_add_unique_abbrev(&cb->buf, noid->hash, DEFAULT_ABBREV);
+               strbuf_add_unique_abbrev(&cb->buf, noid, DEFAULT_ABBREV);
        }
        return 1;
 }
@@ -1489,10 +1489,10 @@ static void wt_status_get_detached_from(struct wt_status_state *state)
                state->detached_from = xstrdup(from);
        } else
                state->detached_from =
-                       xstrdup(find_unique_abbrev(cb.noid.hash, DEFAULT_ABBREV));
-       hashcpy(state->detached_sha1, cb.noid.hash);
+                       xstrdup(find_unique_abbrev(&cb.noid, DEFAULT_ABBREV));
+       oidcpy(&state->detached_oid, &cb.noid);
        state->detached_at = !get_oid("HEAD", &oid) &&
-                            !hashcmp(oid.hash, state->detached_sha1);
+                            !oidcmp(&oid, &state->detached_oid);
 
        free(ref);
        strbuf_release(&cb.buf);
@@ -1551,13 +1551,13 @@ void wt_status_get_state(struct wt_status_state *state,
        } else if (!stat(git_path_cherry_pick_head(), &st) &&
                        !get_oid("CHERRY_PICK_HEAD", &oid)) {
                state->cherry_pick_in_progress = 1;
-               hashcpy(state->cherry_pick_head_sha1, oid.hash);
+               oidcpy(&state->cherry_pick_head_oid, &oid);
        }
        wt_status_check_bisect(NULL, state);
        if (!stat(git_path_revert_head(), &st) &&
            !get_oid("REVERT_HEAD", &oid)) {
                state->revert_in_progress = 1;
-               hashcpy(state->revert_head_sha1, oid.hash);
+               oidcpy(&state->revert_head_oid, &oid);
        }
 
        if (get_detached_from)
index ea2456daf24a4a74b3d85b041527ce5f99dc2695..430770b854c41b38b95dae6e8fa8943629a2309b 100644 (file)
@@ -118,9 +118,9 @@ struct wt_status_state {
        char *branch;
        char *onto;
        char *detached_from;
-       unsigned char detached_sha1[20];
-       unsigned char revert_head_sha1[20];
-       unsigned char cherry_pick_head_sha1[20];
+       struct object_id detached_oid;
+       struct object_id revert_head_oid;
+       struct object_id cherry_pick_head_oid;
 };
 
 size_t wt_status_locate_end(const char *s, size_t len);
index 770e1f7f8185e05f2618c261b70a5773041432fb..9315bc0ede11ba0377e27d711e37b6a0ae555c43 100644 (file)
@@ -191,7 +191,7 @@ void read_mmblob(mmfile_t *ptr, const struct object_id *oid)
                return;
        }
 
-       ptr->ptr = read_sha1_file(oid->hash, &type, &size);
+       ptr->ptr = read_object_file(oid, &type, &size);
        if (!ptr->ptr || type != OBJ_BLOB)
                die("unable to read blob object %s", oid_to_hex(oid));
        ptr->size = size;