Merge branch 'nd/resolve-ref'
authorJunio C Hamano <gitster@pobox.com>
Fri, 9 Dec 2011 21:37:14 +0000 (13:37 -0800)
committerJunio C Hamano <gitster@pobox.com>
Fri, 9 Dec 2011 21:37:14 +0000 (13:37 -0800)
* nd/resolve-ref:
Copy resolve_ref() return value for longer use
Convert many resolve_ref() calls to read_ref*() and ref_exists()

Conflicts:
builtin/fmt-merge-msg.c
builtin/merge.c
refs.c

184 files changed:
Documentation/RelNotes/1.7.7.4.txt [new file with mode: 0644]
Documentation/RelNotes/1.7.8.txt
Documentation/RelNotes/1.7.9.txt [new file with mode: 0644]
Documentation/config.txt
Documentation/git-branch.txt
Documentation/git-cherry-pick.txt
Documentation/git-commit-tree.txt
Documentation/git-difftool.txt
Documentation/git-fsck.txt
Documentation/git-pull.txt
Documentation/git-reset.txt
Documentation/git-revert.txt
Documentation/git-symbolic-ref.txt
Documentation/git.txt
Documentation/gitattributes.txt
Documentation/merge-options.txt
Documentation/sequencer.txt
GIT-VERSION-GEN
Makefile
RelNotes
branch.c
branch.h
builtin.h
builtin/apply.c
builtin/archive.c
builtin/branch.c
builtin/checkout.c
builtin/commit-tree.c
builtin/commit.c
builtin/diff.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/merge.c
builtin/name-rev.c
builtin/pack-objects.c
builtin/prune.c
builtin/reflog.c
builtin/revert.c
builtin/stripspace.c
builtin/tag.c
builtin/upload-archive.c
builtin/verify-tag.c
cache.h
commit.c
commit.h
compat/mingw.c
compat/mingw.h
compat/msvc.h
compat/strtoimax.c [new file with mode: 0644]
compat/vcbuild/include/arpa/inet.h [deleted file]
compat/vcbuild/include/grp.h [deleted file]
compat/vcbuild/include/inttypes.h [deleted file]
compat/vcbuild/include/netdb.h [deleted file]
compat/vcbuild/include/netinet/in.h [deleted file]
compat/vcbuild/include/netinet/tcp.h [deleted file]
compat/vcbuild/include/pwd.h [deleted file]
compat/vcbuild/include/sys/ioctl.h [deleted file]
compat/vcbuild/include/sys/select.h [deleted file]
compat/vcbuild/include/sys/socket.h [deleted file]
compat/vcbuild/include/sys/wait.h [deleted file]
compat/vcbuild/include/termios.h [deleted file]
config.c
contrib/fast-import/git-p4
contrib/fast-import/git-p4.txt
convert.c
dir.c
environment.c
fmt-merge-msg.h [new file with mode: 0644]
git-am.sh
git-compat-util.h
git-pull.sh
git-request-pull.sh
git-svn.perl
gpg-interface.c [new file with mode: 0644]
gpg-interface.h [new file with mode: 0644]
http.c
http.h
list-objects.c
mailmap.c
merge-recursive.c
notes-merge.c
object.c
pack-check.c
pack-write.c
pack.h
perl/.gitignore
reachable.c
reachable.h
read-cache.c
refs.c
sequencer.h
sha1_file.c
strbuf.c
strbuf.h
submodule.c
t/t3507-cherry-pick-conflict.sh
t/t3510-cherry-pick-sequence.sh
t/t4018-diff-funcname.sh
t/t4034-diff-words.sh
t/t4034/matlab/expect [new file with mode: 0644]
t/t4034/matlab/post [new file with mode: 0644]
t/t4034/matlab/pre [new file with mode: 0644]
t/t4202-log.sh
t/t5000-tar-tree.sh
t/t5150-request-pull.sh
t/t5501-fetch-push-alternates.sh
t/t5510-fetch.sh
t/t5515/fetch.br-branches-default
t/t5515/fetch.br-branches-default-merge
t/t5515/fetch.br-branches-default-merge_branches-default
t/t5515/fetch.br-branches-default-octopus
t/t5515/fetch.br-branches-default-octopus_branches-default
t/t5515/fetch.br-branches-default_branches-default
t/t5515/fetch.br-branches-one
t/t5515/fetch.br-branches-one-merge
t/t5515/fetch.br-branches-one-merge_branches-one
t/t5515/fetch.br-branches-one-octopus
t/t5515/fetch.br-branches-one-octopus_branches-one
t/t5515/fetch.br-branches-one_branches-one
t/t5515/fetch.br-config-explicit
t/t5515/fetch.br-config-explicit-merge
t/t5515/fetch.br-config-explicit-merge_config-explicit
t/t5515/fetch.br-config-explicit-octopus
t/t5515/fetch.br-config-explicit-octopus_config-explicit
t/t5515/fetch.br-config-explicit_config-explicit
t/t5515/fetch.br-config-glob
t/t5515/fetch.br-config-glob-merge
t/t5515/fetch.br-config-glob-merge_config-glob
t/t5515/fetch.br-config-glob-octopus
t/t5515/fetch.br-config-glob-octopus_config-glob
t/t5515/fetch.br-config-glob_config-glob
t/t5515/fetch.br-remote-explicit
t/t5515/fetch.br-remote-explicit-merge
t/t5515/fetch.br-remote-explicit-merge_remote-explicit
t/t5515/fetch.br-remote-explicit-octopus
t/t5515/fetch.br-remote-explicit-octopus_remote-explicit
t/t5515/fetch.br-remote-explicit_remote-explicit
t/t5515/fetch.br-remote-glob
t/t5515/fetch.br-remote-glob-merge
t/t5515/fetch.br-remote-glob-merge_remote-glob
t/t5515/fetch.br-remote-glob-octopus
t/t5515/fetch.br-remote-glob-octopus_remote-glob
t/t5515/fetch.br-remote-glob_remote-glob
t/t5515/fetch.br-unconfig
t/t5515/fetch.br-unconfig_--tags_.._.git
t/t5515/fetch.br-unconfig_.._.git_one_tag_tag-one_tag_tag-three-file
t/t5515/fetch.br-unconfig_.._.git_tag_tag-one-tree_tag_tag-three-file
t/t5515/fetch.br-unconfig_.._.git_tag_tag-one_tag_tag-three
t/t5515/fetch.br-unconfig_branches-default
t/t5515/fetch.br-unconfig_branches-one
t/t5515/fetch.br-unconfig_config-explicit
t/t5515/fetch.br-unconfig_config-glob
t/t5515/fetch.br-unconfig_remote-explicit
t/t5515/fetch.br-unconfig_remote-glob
t/t5515/fetch.master
t/t5515/fetch.master_--tags_.._.git
t/t5515/fetch.master_.._.git_one_tag_tag-one_tag_tag-three-file
t/t5515/fetch.master_.._.git_tag_tag-one-tree_tag_tag-three-file
t/t5515/fetch.master_.._.git_tag_tag-one_tag_tag-three
t/t5515/fetch.master_branches-default
t/t5515/fetch.master_branches-one
t/t5515/fetch.master_config-explicit
t/t5515/fetch.master_config-glob
t/t5515/fetch.master_remote-explicit
t/t5515/fetch.master_remote-glob
t/t5520-pull.sh
t/t5700-clone-reference.sh
t/t7106-reset-sequence.sh
t/t7600-merge.sh
t/t7604-merge-custom-message.sh
t/t7608-merge-messages.sh
t/t9805-skip-submit-edit.sh [new file with mode: 0755]
tag.c
tree-diff.c
tree-walk.c
tree-walk.h
tree.c
unpack-trees.c
userdiff.c
diff --git a/Documentation/RelNotes/1.7.7.4.txt b/Documentation/RelNotes/1.7.7.4.txt
new file mode 100644 (file)
index 0000000..e523448
--- /dev/null
@@ -0,0 +1,14 @@
+Git v1.7.7.4 Release Notes
+==========================
+
+Fixes since v1.7.7.3
+--------------------
+
+ * A few header dependencies were missing from the Makefile.
+
+ * Some newer parts of the code used C99 __VA_ARGS__ while we still
+   try to cater to older compilers.
+
+ * "git name-rev --all" tried to name all _objects_, naturally failing to
+   describe many blobs and trees, instead of showing only commits as
+   advertised in its documentation.
index b9bb32492f85ea9d80bbf279ea459881048e31f5..b4d90bba0f6c761e61321bb9df8b7a8b3f725272 100644 (file)
@@ -1,5 +1,5 @@
-Git v1.7.8 Release Notes (draft)
-================================
+Git v1.7.8 Release Notes
+========================
 
 Updates since v1.7.7
 --------------------
@@ -29,7 +29,7 @@ Updates since v1.7.7
    files from the index, not from the working tree.
 
  * Variants of "git cherry-pick" and "git revert" that take multiple
-   commits learned to "--continue".
+   commits learned to "--continue" and "--abort".
 
  * "git daemon" gives more human readble error messages to clients
    using ERR packets when appropriate.
@@ -113,9 +113,6 @@ Updates since v1.7.7
    between commits in the superproject that has and does not have the
    submodule in the tree without re-cloning.
 
- * "git upload-archive" (hence "git archive --remote") can be built
-   and used on mingw port of Git.
-
  * "gitweb" leaked unescaped control characters from syntax hiliter
    outputs.
 
@@ -162,11 +159,3 @@ included in this release.
    were misspelled.
    (merge c49904e fc/remote-seturl-usage-fix later to maint).
    (merge 656cdf0 jc/remote-setbranches-usage-fix later to maint).
-
----
-exec >/var/tmp/1
-O=v1.7.8-rc1-23-gdc865af
-echo O=$(git describe --always master)
-git log --first-parent --oneline --reverse ^$O master
-echo
-git shortlog --no-merges ^$O master
diff --git a/Documentation/RelNotes/1.7.9.txt b/Documentation/RelNotes/1.7.9.txt
new file mode 100644 (file)
index 0000000..7f05936
--- /dev/null
@@ -0,0 +1,27 @@
+Git v1.7.9 Release Notes (draft)
+========================
+
+Updates since v1.7.8
+--------------------
+
+ * Porcelain commands like "git reset" did not distinguish deletions
+   and type-changes from ordinary modification, and reported them with
+   the same 'M' moniker. They now use 'D' (for deletion) and 'T' (for
+   type-change) to match "git status -s" and "git diff --name-status".
+
+ * fsck and prune are relatively lengthy operations that still go
+   silent while making the end-user wait. They learned to give progress
+   output like other slow operations.
+
+ * The set of built-in function-header patterns for various languages
+   knows MATLAB.
+
+May also contain documentation updates and code clean-ups.
+
+
+Fixes since v1.7.8
+------------------
+
+ * In some codepaths (notably, checkout and merge), the ignore patterns
+   recorded in $GIT_DIR/info/exclude were not honored. They now are.
+   (merge fc001b5 nd/maint-ignore-exclude later to maint).
index 5a841da6d4cd86c4340abf001f735a37035d198f..8a7d2d4cb1c0dd200b1d7fc98fe3b5e78acba755 100644 (file)
@@ -677,10 +677,12 @@ branch.<name>.mergeoptions::
 branch.<name>.rebase::
        When true, rebase the branch <name> on top of the fetched branch,
        instead of merging the default branch from the default remote when
-       "git pull" is run.
-       *NOTE*: this is a possibly dangerous operation; do *not* use
-       it unless you understand the implications (see linkgit:git-rebase[1]
-       for details).
+       "git pull" is run. See "pull.rebase" for doing this in a non
+       branch-specific manner.
++
+*NOTE*: this is a possibly dangerous operation; do *not* use
+it unless you understand the implications (see linkgit:git-rebase[1]
+for details).
 
 browser.<tool>.cmd::
        Specify the command to invoke the specified browser. The
@@ -1590,6 +1592,16 @@ pretty.<name>::
        Note that an alias with the same name as a built-in format
        will be silently ignored.
 
+pull.rebase::
+       When true, rebase branches on top of the fetched branch, instead
+       of merging the default branch from the default remote when "git
+       pull" is run. See "branch.<name>.rebase" for setting this on a
+       per-branch basis.
++
+*NOTE*: this is a possibly dangerous operation; do *not* use
+it unless you understand the implications (see linkgit:git-rebase[1]
+for details).
+
 pull.octopus::
        The default merge strategy to use when pulling multiple branches
        at once.
index f46013c91fcbbe4eecffe09d9b43c132daea093f..0427e80a35601e689a47299dce9c5517959bddf8 100644 (file)
@@ -14,6 +14,7 @@ SYNOPSIS
 'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]
 'git branch' (-m | -M) [<oldbranch>] <newbranch>
 'git branch' (-d | -D) [-r] <branchname>...
+'git branch' --edit-description [<branchname>]
 
 DESCRIPTION
 -----------
@@ -158,6 +159,10 @@ start-point is either a local or remote-tracking branch.
        like '--track' would when creating the branch, except that where
        branch points to is not changed.
 
+--edit-description::
+       Open an editor and edit the text to explain what the branch is
+       for, to be used by various other commands (e.g. `request-pull`).
+
 --contains <commit>::
        Only list branches which contain the specified commit.
 
index 2660a842fc2ac76660963bc65c95ca47cb0e97cb..fed5097e00b4a031c2992ac3d421f6df975e6152 100644 (file)
@@ -9,8 +9,9 @@ SYNOPSIS
 --------
 [verse]
 'git cherry-pick' [--edit] [-n] [-m parent-number] [-s] [-x] [--ff] <commit>...
-'git cherry-pick' --reset
 'git cherry-pick' --continue
+'git cherry-pick' --quit
+'git cherry-pick' --abort
 
 DESCRIPTION
 -----------
index 02133d5fc9a14df7f4fe24d97bdf9980e77f807a..cfb9906bb52f5bd81301e4859759b17ab124cada 100644 (file)
@@ -9,7 +9,8 @@ git-commit-tree - Create a new commit object
 SYNOPSIS
 --------
 [verse]
-'git commit-tree' <tree> [(-p <parent commit>)...] < changelog
+'git commit-tree' <tree> [(-p <parent>)...] < changelog
+'git commit-tree' [(-p <parent>)...] [(-m <message>)...] [(-F <file>)...] <tree>
 
 DESCRIPTION
 -----------
@@ -17,7 +18,8 @@ This is usually not what an end user wants to run directly.  See
 linkgit:git-commit[1] instead.
 
 Creates a new commit object based on the provided tree object and
-emits the new commit object id on stdout.
+emits the new commit object id on stdout. The log message is read
+from the standard input, unless `-m` or `-F` options are given.
 
 A commit object may have any number of parents. With exactly one
 parent, it is an ordinary commit. Having more than one parent makes
@@ -39,9 +41,17 @@ OPTIONS
 <tree>::
        An existing tree object
 
--p <parent commit>::
+-p <parent>::
        Each '-p' indicates the id of a parent commit object.
 
+-m <message>::
+       A paragraph in the commig log message. This can be given more than
+       once and each <message> becomes its own paragraph.
+
+-F <file>::
+       Read the commit log message from the given file. Use `-` to read
+       from the standard input.
+
 
 Commit Information
 ------------------
index a03515f1eccddded2efbd46ca522f3bac8896d90..19d473c070c4f82dc4b7f04f784bcae835dca6a2 100644 (file)
@@ -31,7 +31,7 @@ OPTIONS
 -t <tool>::
 --tool=<tool>::
        Use the diff tool specified by <tool>.
-       Valid merge tools are:
+       Valid diff tools are:
        araxis, bc3, diffuse, emerge, ecmerge, gvimdiff, kdiff3,
        kompare, meld, opendiff, p4merge, tkdiff, vimdiff and xxdiff.
 +
index a2a508dc2829b88e143ceb5c8e5edf0880263b2b..0a17b4258e2a69a1d2a5e931dd14ac1869876f33 100644 (file)
@@ -10,7 +10,8 @@ SYNOPSIS
 --------
 [verse]
 'git fsck' [--tags] [--root] [--unreachable] [--cache] [--no-reflogs]
-        [--[no-]full] [--strict] [--verbose] [--lost-found] [<object>*]
+        [--[no-]full] [--strict] [--verbose] [--lost-found]
+        [--[no-]progress] [<object>*]
 
 DESCRIPTION
 -----------
@@ -72,6 +73,14 @@ index file, all SHA1 references in .git/refs/*, and all reflogs (unless
        a blob, the contents are written into the file, rather than
        its object name.
 
+--progress::
+--no-progress::
+       Progress status is reported on the standard error stream by
+       default when it is attached to a terminal, unless
+       --no-progress or --verbose is specified. --progress forces
+       progress status even if the standard error stream is not
+       directed to a terminal.
+
 It tests SHA1 and general object sanity, and it does full tracking of
 the resulting reachability and everything else. It prints out any
 corruption it finds (missing or bad objects), and if you use the
index e1da46876682e9d95a7505e1bc116cbe07f2ec61..0f18ec891ac75effb102a445a93bdcf4432bb697 100644 (file)
@@ -108,7 +108,7 @@ include::merge-options.txt[]
        fetched, the rebase uses that information to avoid rebasing
        non-local changes.
 +
-See `branch.<name>.rebase` and `branch.autosetuprebase` in
+See `pull.rebase`, `branch.<name>.rebase` and `branch.autosetuprebase` in
 linkgit:git-config[1] if you want to make `git pull` always use
 `{litdd}rebase` instead of merging.
 +
index b2832fc7eb809af9865d83cdb20829354165f62e..b674866e6d166ccce096b58f7cecdbdb183c0194 100644 (file)
@@ -9,8 +9,8 @@ SYNOPSIS
 --------
 [verse]
 'git reset' [-q] [<commit>] [--] <paths>...
-'git reset' [--patch|-p] [<commit>] [--] [<paths>...]
-'git reset' [--soft | --mixed | --hard | --merge | --keep] [-q] [<commit>]
+'git reset' (--patch | -p) [<commit>] [--] [<paths>...]
+'git reset' (--soft | --mixed | --hard | --merge | --keep) [-q] [<commit>]
 
 DESCRIPTION
 -----------
@@ -34,7 +34,7 @@ Alternatively, using linkgit:git-checkout[1] and specifying a commit, you
 can copy the contents of a path out of a commit to the index and to the
 working tree in one go.
 
-'git reset' --patch|-p [<commit>] [--] [<paths>...]::
+'git reset' (--patch | -p) [<commit>] [--] [<paths>...]::
        Interactively select hunks in the difference between the index
        and <commit> (defaults to HEAD).  The chosen hunks are applied
        in reverse to the index.
@@ -43,7 +43,7 @@ This means that `git reset -p` is the opposite of `git add -p`, i.e.
 you can use it to selectively reset hunks. See the ``Interactive Mode''
 section of linkgit:git-add[1] to learn how to operate the `\--patch` mode.
 
-'git reset' [--<mode>] [<commit>]::
+'git reset' --<mode> [<commit>]::
        This form resets the current branch head to <commit> and
        possibly updates the index (resetting it to the tree of <commit>) and
        the working tree depending on <mode>, which
index f3519413e7e8704deee0197df6876eaed97e28b0..b699a3458eff439b05049dab94610a57ac62fc0a 100644 (file)
@@ -9,8 +9,9 @@ SYNOPSIS
 --------
 [verse]
 'git revert' [--edit | --no-edit] [-n] [-m parent-number] [-s] <commit>...
-'git revert' --reset
 'git revert' --continue
+'git revert' --quit
+'git revert' --abort
 
 DESCRIPTION
 -----------
index 75b1ae5061b78524383221641aee5edd292028e6..a45d4c4f29635a4fdcdeb2d15950925313920741 100644 (file)
@@ -43,12 +43,9 @@ In the past, `.git/HEAD` was a symbolic link pointing at
 `refs/heads/master`.  When we wanted to switch to another branch,
 we did `ln -sf refs/heads/newbranch .git/HEAD`, and when we wanted
 to find out which branch we are on, we did `readlink .git/HEAD`.
-This was fine, and internally that is what still happens by
-default, but on platforms that do not have working symlinks,
-or that do not have the `readlink(1)` command, this was a bit
-cumbersome.  On some platforms, `ln -sf` does not even work as
-advertised (horrors).  Therefore symbolic links are now deprecated
-and symbolic refs are used by default.
+But symbolic links are not entirely portable, so they are now
+deprecated and symbolic refs (as described above) are used by
+default.
 
 'git symbolic-ref' will exit with status 0 if the contents of the
 symbolic ref were printed correctly, with status 1 if the requested
index 5e80cfd71a5529225b607bd3f1732d19f05d0c1d..e869032fc0703aed18d3cb1417eda4341c29e093 100644 (file)
@@ -44,6 +44,11 @@ unreleased) version of git, that is available from 'master'
 branch of the `git.git` repository.
 Documentation for older releases are available here:
 
+* link:v1.7.8/git.html[documentation for release 1.7.8]
+
+* release notes for
+  link:RelNotes/1.7.8.txt[1.7.8].
+
 * link:v1.7.7.1/git.html[documentation for release 1.7.7.1]
 
 * release notes for
index 25e46aeb7a32287c7dc2666d2633c4787ae1c59a..a85b187e0479b99e137160c1190f174d80675fa1 100644 (file)
@@ -500,6 +500,8 @@ patterns are available:
 
 - `java` suitable for source code in the Java language.
 
+- `matlab` suitable for source code in the MATLAB language.
+
 - `objc` suitable for source code in the Objective-C language.
 
 - `pascal` suitable for source code in the Pascal/Delphi language.
index 6bd0b041c3c1c0af5d03fce43d8016706e9256b1..1a5c12e3171ab82f489bcd53657c8a89741a3dab 100644 (file)
@@ -9,7 +9,6 @@ inspect and further tweak the merge result before committing.
 
 --edit::
 -e::
-+
        Invoke editor before committing successful merge to further
        edit the default merge message.
 
index 3e6df338bed519eb74cf233f40589ddbfb0da57b..5747f442f25e6271c7464db78496b85ee058d05f 100644 (file)
@@ -1,9 +1,12 @@
---reset::
-       Forget about the current operation in progress.  Can be used
-       to clear the sequencer state after a failed cherry-pick or
-       revert.
-
 --continue::
        Continue the operation in progress using the information in
        '.git/sequencer'.  Can be used to continue after resolving
        conflicts in a failed cherry-pick or revert.
+
+--quit::
+       Forget about the current operation in progress.  Can be used
+       to clear the sequencer state after a failed cherry-pick or
+       revert.
+
+--abort::
+       Cancel the operation and return to the pre-sequence state.
index c3435b0c4f00e873dc019cf8224543943cf0452f..e18a30a16a6bd671290ac466745c218fed669755 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v1.7.8-rc2
+DEF_VER=v1.7.8.GIT
 
 LF='
 '
index ee34eab8c527da360a24c153a297d7a2f62d2a55..ed8232075e017b43519298083a6c678ea9c806d9 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -57,8 +57,8 @@ all::
 #
 # Define NO_STRLCPY if you don't have strlcpy.
 #
-# Define NO_STRTOUMAX if you don't have strtoumax in the C library.
-# If your compiler also does not support long long or does not have
+# Define NO_STRTOUMAX if you don't have both strtoimax and strtoumax in the
+# C library. If your compiler also does not support long long or does not have
 # strtoull, define NO_STRTOULL.
 #
 # Define NO_SETENV if you don't have setenv in the C library.
@@ -250,6 +250,12 @@ all::
 #   DEFAULT_EDITOR='$GIT_FALLBACK_EDITOR',
 #   DEFAULT_EDITOR='"C:\Program Files\Vim\gvim.exe" --nofork'
 #
+# Define COMPUTE_HEADER_DEPENDENCIES to "yes" if you want dependencies on
+# header files to be automatically computed, to avoid rebuilding objects when
+# an unrelated header file changes.  Define it to "no" to use the hard-coded
+# dependency rules.  The default is "auto", which means to use computed header
+# dependencies if your compiler is detected to support it.
+#
 # Define CHECK_HEADER_DEPENDENCIES to check for problems in the hard-coded
 # dependency rules.
 #
@@ -518,6 +524,7 @@ LIB_H += compat/win32/syslog.h
 LIB_H += compat/win32/poll.h
 LIB_H += compat/win32/dirent.h
 LIB_H += connected.h
+LIB_H += convert.h
 LIB_H += csum-file.h
 LIB_H += decorate.h
 LIB_H += delta.h
@@ -525,9 +532,11 @@ LIB_H += diffcore.h
 LIB_H += diff.h
 LIB_H += dir.h
 LIB_H += exec_cmd.h
+LIB_H += fmt-merge-msg.h
 LIB_H += fsck.h
 LIB_H += gettext.h
 LIB_H += git-compat-util.h
+LIB_H += gpg-interface.h
 LIB_H += graph.h
 LIB_H += grep.h
 LIB_H += hash.h
@@ -621,6 +630,7 @@ LIB_OBJS += entry.o
 LIB_OBJS += environment.o
 LIB_OBJS += exec_cmd.o
 LIB_OBJS += fsck.o
+LIB_OBJS += gpg-interface.o
 LIB_OBJS += graph.o
 LIB_OBJS += grep.o
 LIB_OBJS += hash.o
@@ -1245,21 +1255,32 @@ endif
 endif
 
 ifdef CHECK_HEADER_DEPENDENCIES
-COMPUTE_HEADER_DEPENDENCIES =
+COMPUTE_HEADER_DEPENDENCIES = no
 USE_COMPUTED_HEADER_DEPENDENCIES =
-else
+endif
+
 ifndef COMPUTE_HEADER_DEPENDENCIES
+COMPUTE_HEADER_DEPENDENCIES = auto
+endif
+
+ifeq ($(COMPUTE_HEADER_DEPENDENCIES),auto)
 dep_check = $(shell $(CC) $(ALL_CFLAGS) \
        -c -MF /dev/null -MMD -MP -x c /dev/null -o /dev/null 2>&1; \
        echo $$?)
 ifeq ($(dep_check),0)
-COMPUTE_HEADER_DEPENDENCIES=YesPlease
-endif
+override COMPUTE_HEADER_DEPENDENCIES = yes
+else
+override COMPUTE_HEADER_DEPENDENCIES = no
 endif
 endif
 
-ifdef COMPUTE_HEADER_DEPENDENCIES
+ifeq ($(COMPUTE_HEADER_DEPENDENCIES),yes)
 USE_COMPUTED_HEADER_DEPENDENCIES = YesPlease
+else
+ifneq ($(COMPUTE_HEADER_DEPENDENCIES),no)
+$(error please set COMPUTE_HEADER_DEPENDENCIES to yes, no, or auto \
+(not "$(COMPUTE_HEADER_DEPENDENCIES)"))
+endif
 endif
 
 ifdef SANE_TOOL_PATH
@@ -1460,7 +1481,7 @@ ifdef NO_STRLCPY
 endif
 ifdef NO_STRTOUMAX
        COMPAT_CFLAGS += -DNO_STRTOUMAX
-       COMPAT_OBJS += compat/strtoumax.o
+       COMPAT_OBJS += compat/strtoumax.o compat/strtoimax.o
 endif
 ifdef NO_STRTOULL
        COMPAT_CFLAGS += -DNO_STRTOULL
@@ -1906,7 +1927,7 @@ OBJECTS := $(GIT_OBJS) $(XDIFF_OBJS) $(VCSSVN_OBJS)
 dep_files := $(foreach f,$(OBJECTS),$(dir $f).depend/$(notdir $f).d)
 dep_dirs := $(addsuffix .depend,$(sort $(dir $(OBJECTS))))
 
-ifdef COMPUTE_HEADER_DEPENDENCIES
+ifeq ($(COMPUTE_HEADER_DEPENDENCIES),yes)
 $(dep_dirs):
        @mkdir -p $@
 
@@ -1919,7 +1940,7 @@ Please unset CHECK_HEADER_DEPENDENCIES and try again)
 endif
 endif
 
-ifndef COMPUTE_HEADER_DEPENDENCIES
+ifneq ($(COMPUTE_HEADER_DEPENDENCIES),yes)
 ifndef CHECK_HEADER_DEPENDENCIES
 dep_dirs =
 missing_dep_dirs =
@@ -2009,13 +2030,13 @@ builtin/branch.o builtin/checkout.o builtin/clone.o builtin/reset.o branch.o tra
 builtin/bundle.o bundle.o transport.o: bundle.h
 builtin/bisect--helper.o builtin/rev-list.o bisect.o: bisect.h
 builtin/clone.o builtin/fetch-pack.o transport.o: fetch-pack.h
-builtin/grep.o builtin/pack-objects.o transport-helper.o: thread-utils.h
+builtin/grep.o builtin/pack-objects.o transport-helper.o thread-utils.o: thread-utils.h
 builtin/send-pack.o transport.o: send-pack.h
 builtin/log.o builtin/shortlog.o: shortlog.h
 builtin/prune.o builtin/reflog.o reachable.o: reachable.h
 builtin/commit.o builtin/revert.o wt-status.o: wt-status.h
 builtin/tar-tree.o archive-tar.o: tar.h
-connect.o transport.o http-backend.o: url.h
+connect.o transport.o url.o http-backend.o: url.h
 http-fetch.o http-walker.o remote-curl.o transport.o walker.o: walker.h
 http.o http-walker.o http-push.o http-fetch.o remote-curl.o: http.h url.h
 
index 7d9276973af3a8f455778d2ce3ced66167f46801..766bbaf8f5a90759645200e1fc61e11d9836de49 120000 (symlink)
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/1.7.8.txt
\ No newline at end of file
+Documentation/RelNotes/1.7.9.txt
\ No newline at end of file
index d8098762f62a9dfb991f64702d34047182cfa951..d91a099fdd22b9131a1d2ddaf3778b645c53eca0 100644 (file)
--- a/branch.c
+++ b/branch.c
@@ -136,6 +136,37 @@ static int setup_tracking(const char *new_ref, const char *orig_ref,
        return 0;
 }
 
+struct branch_desc_cb {
+       const char *config_name;
+       const char *value;
+};
+
+static int read_branch_desc_cb(const char *var, const char *value, void *cb)
+{
+       struct branch_desc_cb *desc = cb;
+       if (strcmp(desc->config_name, var))
+               return 0;
+       free((char *)desc->value);
+       return git_config_string(&desc->value, var, value);
+}
+
+int read_branch_desc(struct strbuf *buf, const char *branch_name)
+{
+       struct branch_desc_cb cb;
+       struct strbuf name = STRBUF_INIT;
+       strbuf_addf(&name, "branch.%s.description", branch_name);
+       cb.config_name = name.buf;
+       cb.value = NULL;
+       if (git_config(read_branch_desc_cb, &cb) < 0) {
+               strbuf_release(&name);
+               return -1;
+       }
+       if (cb.value)
+               strbuf_addstr(buf, cb.value);
+       strbuf_release(&name);
+       return 0;
+}
+
 int validate_new_branchname(const char *name, struct strbuf *ref,
                            int force, int attr_only)
 {
@@ -241,6 +272,7 @@ void create_branch(const char *head,
 void remove_branch_state(void)
 {
        unlink(git_path("CHERRY_PICK_HEAD"));
+       unlink(git_path("REVERT_HEAD"));
        unlink(git_path("MERGE_HEAD"));
        unlink(git_path("MERGE_RR"));
        unlink(git_path("MERGE_MSG"));
index 1285158dd4f26e5bbb0e0d7133055f168fee773f..1493f73722161cc191f0c7fd655781d8b748ed41 100644 (file)
--- a/branch.h
+++ b/branch.h
@@ -46,4 +46,9 @@ void remove_branch_state(void);
 #define BRANCH_CONFIG_VERBOSE 01
 extern void install_branch_config(int flag, const char *local, const char *origin, const char *remote);
 
+/*
+ * Read branch description
+ */
+extern int read_branch_desc(struct strbuf *, const char *branch_name);
+
 #endif
index 0e9da9083491eb3c18464b730f481cf74ee82430..e94a5dc8a5557e44d35286ee5f70c7929a4d3a51 100644 (file)
--- a/builtin.h
+++ b/builtin.h
@@ -14,8 +14,14 @@ extern const char git_usage_string[];
 extern const char git_more_info_string[];
 
 extern void prune_packed_objects(int);
+
+struct fmt_merge_msg_opts {
+       unsigned add_title:1;
+       int shortlog_len;
+};
+
 extern int fmt_merge_msg(struct strbuf *in, struct strbuf *out,
-                        int merge_title, int shortlog_len);
+                        struct fmt_merge_msg_opts *);
 extern void commit_notes(struct notes_tree *t, const char *msg);
 
 struct notes_rewrite_cfg {
index 84a8a0b52136c4d1e43ec10f9ef5ed76b7d3c12f..b3b59db534ff0763c822ae9da571d5643a8b709a 100644 (file)
@@ -250,9 +250,6 @@ static int fuzzy_matchlines(const char *s1, size_t n1,
        const char *last2 = s2 + n2 - 1;
        int result = 0;
 
-       if (n1 < 0 || n2 < 0)
-               return 0;
-
        /* ignore line endings */
        while ((*last1 == '\r') || (*last1 == '\n'))
                last1--;
index e405566c5eabe03160e77dec4e7843f35f4e78fb..931956def986bbdf5b77e163f1b18c961e7be09c 100644 (file)
@@ -87,7 +87,6 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
        const char *exec = "git-upload-archive";
        const char *output = NULL;
        const char *remote = NULL;
-       int is_remote = 0;
        struct option local_opts[] = {
                OPT_STRING('o', "output", &output, "file",
                        "write the archive to this file"),
@@ -95,9 +94,6 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
                        "retrieve the archive from remote repository <repo>"),
                OPT_STRING(0, "exec", &exec, "cmd",
                        "path to the remote git-upload-archive command"),
-               { OPTION_BOOLEAN, 0, "remote-request", &is_remote, NULL,
-                       "indicate we are serving a remote request",
-                       PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
                OPT_END()
        };
 
@@ -112,5 +108,5 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
 
        setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
 
-       return write_archive(argc, argv, prefix, 1, output, is_remote);
+       return write_archive(argc, argv, prefix, 1, output, 0);
 }
index 3ef15f7fc5210f30271716378bf6cb8fd6252f1b..e1e486e4c51194e09df3779be254cb72855d1103 100644 (file)
@@ -625,11 +625,49 @@ static int opt_parse_merge_filter(const struct option *opt, const char *arg, int
        return 0;
 }
 
+static const char edit_description[] = "BRANCH_DESCRIPTION";
+
+static int edit_branch_description(const char *branch_name)
+{
+       FILE *fp;
+       int status;
+       struct strbuf buf = STRBUF_INIT;
+       struct strbuf name = STRBUF_INIT;
+
+       read_branch_desc(&buf, branch_name);
+       if (!buf.len || buf.buf[buf.len-1] != '\n')
+               strbuf_addch(&buf, '\n');
+       strbuf_addf(&buf,
+                   "# Please edit the description for the branch\n"
+                   "#   %s\n"
+                   "# Lines starting with '#' will be stripped.\n",
+                   branch_name);
+       fp = fopen(git_path(edit_description), "w");
+       if ((fwrite(buf.buf, 1, buf.len, fp) < buf.len) || fclose(fp)) {
+               strbuf_release(&buf);
+               return error(_("could not write branch description template: %s\n"),
+                            strerror(errno));
+       }
+       strbuf_reset(&buf);
+       if (launch_editor(git_path(edit_description), &buf, NULL)) {
+               strbuf_release(&buf);
+               return -1;
+       }
+       stripspace(&buf, 1);
+
+       strbuf_addf(&name, "branch.%s.description", branch_name);
+       status = git_config_set(name.buf, buf.buf);
+       strbuf_release(&name);
+       strbuf_release(&buf);
+
+       return status;
+}
+
 int cmd_branch(int argc, const char **argv, const char *prefix)
 {
        int delete = 0, rename = 0, force_create = 0, list = 0;
        int verbose = 0, abbrev = -1, detached = 0;
-       int reflog = 0;
+       int reflog = 0, edit_description = 0;
        enum branch_track track;
        int kinds = REF_LOCAL_BRANCH;
        struct commit_list *with_commit = NULL;
@@ -668,6 +706,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
                OPT_BIT('M', NULL, &rename, "move/rename a branch, even if target exists", 2),
                OPT_BOOLEAN(0, "list", &list, "list branch names"),
                OPT_BOOLEAN('l', "create-reflog", &reflog, "create the branch's reflog"),
+               OPT_BOOLEAN(0, "edit-description", &edit_description,
+                           "edit the description for the branch"),
                OPT__FORCE(&force_create, "force creation (when already exists)"),
                {
                        OPTION_CALLBACK, 0, "no-merged", &merge_filter_ref,
@@ -707,7 +747,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
        argc = parse_options(argc, argv, prefix, options, builtin_branch_usage,
                             0);
 
-       if (!delete && !rename && !force_create && argc == 0)
+       if (!delete && !rename && !edit_description && argc == 0)
                list = 1;
 
        if (!!delete + !!rename + !!force_create + !!list > 1)
@@ -721,14 +761,26 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
        else if (list)
                return print_ref_list(kinds, detached, verbose, abbrev,
                                      with_commit, argv);
-       else if (rename) {
+       else if (edit_description) {
+               const char *branch_name;
+               if (detached)
+                       die("Cannot give description to detached HEAD");
+               if (!argc)
+                       branch_name = head;
+               else if (argc == 1)
+                       branch_name = argv[0];
+               else
+                       usage_with_options(builtin_branch_usage, options);
+               if (edit_branch_description(branch_name))
+                       return 1;
+       } else if (rename) {
                if (argc == 1)
                        rename_branch(head, argv[0], rename > 1);
                else if (argc == 2)
                        rename_branch(argv[0], argv[1], rename > 1);
                else
                        usage_with_options(builtin_branch_usage, options);
-       } else if (argc <= 2) {
+       } else if (argc > 0 && argc <= 2) {
                if (kinds != REF_LOCAL_BRANCH)
                        die(_("-a and -r options to 'git branch' do not make sense with a branch name"));
                create_branch(head, argv[0], (argc == 2) ? argv[1] : head,
index c6919f16871a97b4f91fe525e4b8e89f43eecd58..b7c630287dda662630af9883655ed23bd50e7b7e 100644 (file)
@@ -411,7 +411,7 @@ static int merge_working_tree(struct checkout_opts *opts,
                topts.fn = twoway_merge;
                topts.dir = xcalloc(1, sizeof(*topts.dir));
                topts.dir->flags |= DIR_SHOW_IGNORED;
-               topts.dir->exclude_per_dir = ".gitignore";
+               setup_standard_excludes(topts.dir);
                tree = parse_tree_indirect(old->commit ?
                                           old->commit->object.sha1 :
                                           EMPTY_TREE_SHA1_BIN);
index d083795e26e7893c6b7d466f9bcf2be1311cfeb2..b9c331225f0d5c960e9e03f2c92d498f8f01f74c 100644 (file)
@@ -9,7 +9,7 @@
 #include "builtin.h"
 #include "utf8.h"
 
-static const char commit_tree_usage[] = "git commit-tree <sha1> [(-p <sha1>)...] < changelog";
+static const char commit_tree_usage[] = "git commit-tree [(-p <sha1>)...] [-m <message>] [-F <file>] <sha1> <changelog";
 
 static void new_parent(struct commit *parent, struct commit_list **parents_p)
 {
@@ -27,7 +27,7 @@ static void new_parent(struct commit *parent, struct commit_list **parents_p)
 
 int cmd_commit_tree(int argc, const char **argv, const char *prefix)
 {
-       int i;
+       int i, got_tree = 0;
        struct commit_list *parents = NULL;
        unsigned char tree_sha1[20];
        unsigned char commit_sha1[20];
@@ -37,24 +37,66 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
 
        if (argc < 2 || !strcmp(argv[1], "-h"))
                usage(commit_tree_usage);
-       if (get_sha1(argv[1], tree_sha1))
-               die("Not a valid object name %s", argv[1]);
 
-       for (i = 2; i < argc; i += 2) {
-               unsigned char sha1[20];
-               const char *a, *b;
-               a = argv[i]; b = argv[i+1];
-               if (!b || strcmp(a, "-p"))
-                       usage(commit_tree_usage);
+       for (i = 1; i < argc; i++) {
+               const char *arg = argv[i];
+               if (!strcmp(arg, "-p")) {
+                       unsigned char sha1[20];
+                       if (argc <= ++i)
+                               usage(commit_tree_usage);
+                       if (get_sha1(argv[i], sha1))
+                               die("Not a valid object name %s", argv[i]);
+                       assert_sha1_type(sha1, OBJ_COMMIT);
+                       new_parent(lookup_commit(sha1), &parents);
+                       continue;
+               }
+
+               if (!strcmp(arg, "-m")) {
+                       if (argc <= ++i)
+                               usage(commit_tree_usage);
+                       if (buffer.len)
+                               strbuf_addch(&buffer, '\n');
+                       strbuf_addstr(&buffer, argv[i]);
+                       strbuf_complete_line(&buffer);
+                       continue;
+               }
+
+               if (!strcmp(arg, "-F")) {
+                       int fd;
 
-               if (get_sha1(b, sha1))
-                       die("Not a valid object name %s", b);
-               assert_sha1_type(sha1, OBJ_COMMIT);
-               new_parent(lookup_commit(sha1), &parents);
+                       if (argc <= ++i)
+                               usage(commit_tree_usage);
+                       if (buffer.len)
+                               strbuf_addch(&buffer, '\n');
+                       if (!strcmp(argv[i], "-"))
+                               fd = 0;
+                       else {
+                               fd = open(argv[i], O_RDONLY);
+                               if (fd < 0)
+                                       die_errno("git commit-tree: failed to open '%s'",
+                                                 argv[i]);
+                       }
+                       if (strbuf_read(&buffer, fd, 0) < 0)
+                               die_errno("git commit-tree: failed to read '%s'",
+                                         argv[i]);
+                       if (fd && close(fd))
+                               die_errno("git commit-tree: failed to close '%s'",
+                                         argv[i]);
+                       strbuf_complete_line(&buffer);
+                       continue;
+               }
+
+               if (get_sha1(arg, tree_sha1))
+                       die("Not a valid object name %s", arg);
+               if (got_tree)
+                       die("Cannot give more than one trees");
+               got_tree = 1;
        }
 
-       if (strbuf_read(&buffer, 0, 0) < 0)
-               die_errno("git commit-tree: failed to read");
+       if (!buffer.len) {
+               if (strbuf_read(&buffer, 0, 0) < 0)
+                       die_errno("git commit-tree: failed to read");
+       }
 
        if (commit_tree(buffer.buf, tree_sha1, parents, commit_sha1, NULL)) {
                strbuf_release(&buffer);
index f3a6ed2bf5b9ff312dd881e6d44bfcd71fb0b73b..e36e9adf87d76002784eb26107c25e5d91683229 100644 (file)
@@ -1383,6 +1383,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
        int allow_fast_forward = 1;
        struct wt_status s;
        struct commit *current_head = NULL;
+       struct commit_extra_header *extra = NULL;
 
        if (argc == 2 && !strcmp(argv[1], "-h"))
                usage_with_options(builtin_commit_usage, builtin_commit_options);
@@ -1426,7 +1427,6 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
                        pptr = &commit_list_insert(c->item, pptr)->next;
        } else if (whence == FROM_MERGE) {
                struct strbuf m = STRBUF_INIT;
-               struct commit *commit;
                FILE *fp;
 
                if (!reflog_msg)
@@ -1437,11 +1437,12 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
                        die_errno(_("could not open '%s' for reading"),
                                  git_path("MERGE_HEAD"));
                while (strbuf_getline(&m, fp, '\n') != EOF) {
-                       unsigned char sha1[20];
-                       if (get_sha1_hex(m.buf, sha1) < 0)
+                       struct commit *parent;
+
+                       parent = get_merge_parent(m.buf);
+                       if (!parent)
                                die(_("Corrupt MERGE_HEAD file (%s)"), m.buf);
-                       commit = lookup_commit_or_die(sha1, "MERGE_HEAD");
-                       pptr = &commit_list_insert(commit, pptr)->next;
+                       pptr = &commit_list_insert(parent, pptr)->next;
                }
                fclose(fp);
                strbuf_release(&m);
@@ -1484,12 +1485,16 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
                exit(1);
        }
 
-       if (commit_tree(sb.buf, active_cache_tree->sha1, parents, sha1,
-                       author_ident.buf)) {
+       if (amend)
+               extra = read_commit_extra_headers(current_head);
+
+       if (commit_tree_extended(sb.buf, active_cache_tree->sha1, parents, sha1,
+                                author_ident.buf, extra)) {
                rollback_index_files();
                die(_("failed to write commit object"));
        }
        strbuf_release(&author_ident);
+       free_commit_extra_headers(extra);
 
        ref_lock = lock_any_ref_for_update("HEAD",
                                           !current_head
@@ -1515,6 +1520,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
        }
 
        unlink(git_path("CHERRY_PICK_HEAD"));
+       unlink(git_path("REVERT_HEAD"));
        unlink(git_path("MERGE_HEAD"));
        unlink(git_path("MERGE_MSG"));
        unlink(git_path("MERGE_MODE"));
index 1118689fb246b864ce758039543327c4304cdaa4..0fe638fc45c780e53901b8be22d3b4d715be3c30 100644 (file)
@@ -182,7 +182,7 @@ static int builtin_diff_combined(struct rev_info *revs,
                hashcpy((unsigned char *)(parent + i), ent[i].item->sha1);
        diff_tree_combined(parent[0], parent + 1, ents - 1,
                           revs->dense_combined_merges, revs);
-       free(parent);
+       free((void *)parent);
        return 0;
 }
 
index 91731b909aeb22bf8d4e366b8b92281ac0f9ac0c..494a7f9976f870a28dbbbcb4196954a827f6bfdb 100644 (file)
@@ -436,8 +436,7 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
                }
                note[note_len] = '\0';
                fprintf(fp, "%s\t%s\t%s",
-                       sha1_to_hex(commit ? commit->object.sha1 :
-                                   rm->old_sha1),
+                       sha1_to_hex(rm->old_sha1),
                        rm->merge ? "" : "not-for-merge",
                        note);
                for (i = 0; i < url_len; ++i)
index a3ba21520916ce2e244839304def0a748e8a53c7..bdfa0ea05d99089937b9e753cf85a8489a5e27cb 100644 (file)
@@ -5,32 +5,43 @@
 #include "revision.h"
 #include "tag.h"
 #include "string-list.h"
+#include "branch.h"
+#include "fmt-merge-msg.h"
+#include "gpg-interface.h"
 
 static const char * const fmt_merge_msg_usage[] = {
        "git fmt-merge-msg [-m <message>] [--log[=<n>]|--no-log] [--file <file>]",
        NULL
 };
 
-static int shortlog_len;
+static int use_branch_desc;
 
-static int fmt_merge_msg_config(const char *key, const char *value, void *cb)
+int fmt_merge_msg_config(const char *key, const char *value, void *cb)
 {
        if (!strcmp(key, "merge.log") || !strcmp(key, "merge.summary")) {
                int is_bool;
-               shortlog_len = git_config_bool_or_int(key, value, &is_bool);
-               if (!is_bool && shortlog_len < 0)
+               merge_log_config = git_config_bool_or_int(key, value, &is_bool);
+               if (!is_bool && merge_log_config < 0)
                        return error("%s: negative length %s", key, value);
-               if (is_bool && shortlog_len)
-                       shortlog_len = DEFAULT_MERGE_LOG_LEN;
+               if (is_bool && merge_log_config)
+                       merge_log_config = DEFAULT_MERGE_LOG_LEN;
+       } else if (!strcmp(key, "merge.branchdesc")) {
+               use_branch_desc = git_config_bool(key, value);
        }
        return 0;
 }
 
+/* merge data per repository where the merged tips came from */
 struct src_data {
        struct string_list branch, tag, r_branch, generic;
        int head_status;
 };
 
+struct origin_data {
+       unsigned char sha1[20];
+       unsigned is_local_branch:1;
+};
+
 static void init_src_data(struct src_data *data)
 {
        data->branch.strdup_strings = 1;
@@ -45,7 +56,7 @@ static struct string_list origins = STRING_LIST_INIT_DUP;
 static int handle_line(char *line)
 {
        int i, len = strlen(line);
-       unsigned char *sha1;
+       struct origin_data *origin_data;
        char *src, *origin;
        struct src_data *src_data;
        struct string_list_item *item;
@@ -61,16 +72,23 @@ static int handle_line(char *line)
                return 2;
 
        line[40] = 0;
-       sha1 = xmalloc(20);
-       i = get_sha1(line, sha1);
+       origin_data = xcalloc(1, sizeof(struct origin_data));
+       i = get_sha1(line, origin_data->sha1);
        line[40] = '\t';
-       if (i)
+       if (i) {
+               free(origin_data);
                return 3;
+       }
 
        if (line[len - 1] == '\n')
                line[len - 1] = 0;
        line += 42;
 
+       /*
+        * At this point, line points at the beginning of comment e.g.
+        * "branch 'frotz' of git://that/repository.git".
+        * Find the repository name and point it with src.
+        */
        src = strstr(line, " of ");
        if (src) {
                *src = 0;
@@ -93,6 +111,7 @@ static int handle_line(char *line)
                origin = src;
                src_data->head_status |= 1;
        } else if (!prefixcmp(line, "branch ")) {
+               origin_data->is_local_branch = 1;
                origin = line + 7;
                string_list_append(&src_data->branch, origin);
                src_data->head_status |= 2;
@@ -119,7 +138,9 @@ static int handle_line(char *line)
                sprintf(new_origin, "%s of %s", origin, src);
                origin = new_origin;
        }
-       string_list_append(&origins, origin)->util = sha1;
+       if (strcmp(".", src))
+               origin_data->is_local_branch = 0;
+       string_list_append(&origins, origin)->util = origin_data;
        return 0;
 }
 
@@ -140,9 +161,30 @@ static void print_joined(const char *singular, const char *plural,
        }
 }
 
-static void shortlog(const char *name, unsigned char *sha1,
-               struct commit *head, struct rev_info *rev, int limit,
-               struct strbuf *out)
+static void add_branch_desc(struct strbuf *out, const char *name)
+{
+       struct strbuf desc = STRBUF_INIT;
+
+       if (!read_branch_desc(&desc, name)) {
+               const char *bp = desc.buf;
+               while (*bp) {
+                       const char *ep = strchrnul(bp, '\n');
+                       if (*ep)
+                               ep++;
+                       strbuf_addf(out, "  : %.*s", (int)(ep - bp), bp);
+                       bp = ep;
+               }
+               if (out->buf[out->len - 1] != '\n')
+                       strbuf_addch(out, '\n');
+       }
+       strbuf_release(&desc);
+}
+
+static void shortlog(const char *name,
+                    struct origin_data *origin_data,
+                    struct commit *head,
+                    struct rev_info *rev, int limit,
+                    struct strbuf *out)
 {
        int i, count = 0;
        struct commit *commit;
@@ -150,6 +192,7 @@ static void shortlog(const char *name, unsigned char *sha1,
        struct string_list subjects = STRING_LIST_INIT_DUP;
        int flags = UNINTERESTING | TREESAME | SEEN | SHOWN | ADDED;
        struct strbuf sb = STRBUF_INIT;
+       const unsigned char *sha1 = origin_data->sha1;
 
        branch = deref_tag(parse_object(sha1), sha1_to_hex(sha1), 40);
        if (!branch || branch->type != OBJ_COMMIT)
@@ -188,6 +231,9 @@ static void shortlog(const char *name, unsigned char *sha1,
        else
                strbuf_addf(out, "\n* %s:\n", name);
 
+       if (origin_data->is_local_branch && use_branch_desc)
+               add_branch_desc(out, name);
+
        for (i = 0; i < subjects.nr; i++)
                if (i >= limit)
                        strbuf_addf(out, "  ...\n");
@@ -203,7 +249,7 @@ static void shortlog(const char *name, unsigned char *sha1,
        string_list_clear(&subjects, 0);
 }
 
-static void do_fmt_merge_msg_title(struct strbuf *out,
+static void fmt_merge_msg_title(struct strbuf *out,
        const char *current_branch) {
        int i = 0;
        char *sep = "";
@@ -256,8 +302,73 @@ static void do_fmt_merge_msg_title(struct strbuf *out,
                strbuf_addf(out, " into %s\n", current_branch);
 }
 
-static int do_fmt_merge_msg(int merge_title, struct strbuf *in,
-       struct strbuf *out, int shortlog_len) {
+static void fmt_tag_signature(struct strbuf *tagbuf,
+                             struct strbuf *sig,
+                             const char *buf,
+                             unsigned long len)
+{
+       const char *tag_body = strstr(buf, "\n\n");
+       if (tag_body) {
+               tag_body += 2;
+               strbuf_add(tagbuf, tag_body, buf + len - tag_body);
+       }
+       strbuf_complete_line(tagbuf);
+       strbuf_add_lines(tagbuf, "# ", sig->buf, sig->len);
+}
+
+static void fmt_merge_msg_sigs(struct strbuf *out)
+{
+       int i, tag_number = 0, first_tag = 0;
+       struct strbuf tagbuf = STRBUF_INIT;
+
+       for (i = 0; i < origins.nr; i++) {
+               unsigned char *sha1 = origins.items[i].util;
+               enum object_type type;
+               unsigned long size, len;
+               char *buf = read_sha1_file(sha1, &type, &size);
+               struct strbuf sig = STRBUF_INIT;
+
+               if (!buf || type != OBJ_TAG)
+                       goto next;
+               len = parse_signature(buf, size);
+
+               if (size == len)
+                       ; /* merely annotated */
+               else if (verify_signed_buffer(buf, len, buf + len, size - len, &sig)) {
+                       if (!sig.len)
+                               strbuf_addstr(&sig, "gpg verification failed.\n");
+               }
+
+               if (!tag_number++) {
+                       fmt_tag_signature(&tagbuf, &sig, buf, len);
+                       first_tag = i;
+               } else {
+                       if (tag_number == 2) {
+                               struct strbuf tagline = STRBUF_INIT;
+                               strbuf_addf(&tagline, "\n# %s\n",
+                                           origins.items[first_tag].string);
+                               strbuf_insert(&tagbuf, 0, tagline.buf,
+                                             tagline.len);
+                               strbuf_release(&tagline);
+                       }
+                       strbuf_addf(&tagbuf, "\n# %s\n",
+                                   origins.items[i].string);
+                       fmt_tag_signature(&tagbuf, &sig, buf, len);
+               }
+               strbuf_release(&sig);
+       next:
+               free(buf);
+       }
+       if (tagbuf.len) {
+               strbuf_addch(out, '\n');
+               strbuf_addbuf(out, &tagbuf);
+       }
+       strbuf_release(&tagbuf);
+}
+
+int fmt_merge_msg(struct strbuf *in, struct strbuf *out,
+                 struct fmt_merge_msg_opts *opts)
+{
        int i = 0, pos = 0;
        unsigned char head_sha1[20];
        const char *current_branch;
@@ -284,15 +395,13 @@ static int do_fmt_merge_msg(int merge_title, struct strbuf *in,
                        die ("Error in line %d: %.*s", i, len, p);
        }
 
-       if (!srcs.nr) {
-               free((char*)current_branch);
-               return 0;
-       }
+       if (opts->add_title && srcs.nr)
+               fmt_merge_msg_title(out, current_branch);
 
-       if (merge_title)
-               do_fmt_merge_msg_title(out, current_branch);
+       if (origins.nr)
+               fmt_merge_msg_sigs(out);
 
-       if (shortlog_len) {
+       if (opts->shortlog_len) {
                struct commit *head;
                struct rev_info rev;
 
@@ -306,22 +415,21 @@ static int do_fmt_merge_msg(int merge_title, struct strbuf *in,
                        strbuf_addch(out, '\n');
 
                for (i = 0; i < origins.nr; i++)
-                       shortlog(origins.items[i].string, origins.items[i].util,
-                                       head, &rev, shortlog_len, out);
+                       shortlog(origins.items[i].string,
+                                origins.items[i].util,
+                                head, &rev, opts->shortlog_len, out);
        }
+
+       strbuf_complete_line(out);
        free((char *)current_branch);
        return 0;
 }
 
-int fmt_merge_msg(struct strbuf *in, struct strbuf *out,
-                 int merge_title, int shortlog_len) {
-       return do_fmt_merge_msg(merge_title, in, out, shortlog_len);
-}
-
 int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
 {
        const char *inpath = NULL;
        const char *message = NULL;
+       int shortlog_len = -1;
        struct option options[] = {
                { OPTION_INTEGER, 0, "log", &shortlog_len, "n",
                  "populate log with at most <n> entries from shortlog",
@@ -339,20 +447,15 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
        FILE *in = stdin;
        struct strbuf input = STRBUF_INIT, output = STRBUF_INIT;
        int ret;
+       struct fmt_merge_msg_opts opts;
 
        git_config(fmt_merge_msg_config, NULL);
        argc = parse_options(argc, argv, prefix, options, fmt_merge_msg_usage,
                             0);
        if (argc > 0)
                usage_with_options(fmt_merge_msg_usage, options);
-       if (message && !shortlog_len) {
-               char nl = '\n';
-               write_in_full(STDOUT_FILENO, message, strlen(message));
-               write_in_full(STDOUT_FILENO, &nl, 1);
-               return 0;
-       }
        if (shortlog_len < 0)
-               die("Negative --log=%d", shortlog_len);
+               shortlog_len = (merge_log_config > 0) ? merge_log_config : 0;
 
        if (inpath && strcmp(inpath, "-")) {
                in = fopen(inpath, "r");
@@ -365,10 +468,12 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
 
        if (message)
                strbuf_addstr(&output, message);
-       ret = fmt_merge_msg(&input, &output,
-                           message ? 0 : 1,
-                           shortlog_len);
 
+       memset(&opts, 0, sizeof(opts));
+       opts.add_title = !message;
+       opts.shortlog_len = shortlog_len;
+
+       ret = fmt_merge_msg(&input, &output, &opts);
        if (ret)
                return ret;
        write_in_full(STDOUT_FILENO, output.buf, output.len);
index df1a88b51ae7773a15276d144113c0002fddb1cd..30d0dc82f053a5cbdfabcf474be816484ef3ca2b 100644 (file)
@@ -11,6 +11,7 @@
 #include "fsck.h"
 #include "parse-options.h"
 #include "dir.h"
+#include "progress.h"
 
 #define REACHABLE 0x0001
 #define SEEN      0x0002
@@ -27,8 +28,10 @@ static const char *head_points_at;
 static int errors_found;
 static int write_lost_and_found;
 static int verbose;
+static int show_progress = -1;
 #define ERROR_OBJECT 01
 #define ERROR_REACHABLE 02
+#define ERROR_PACK 04
 
 #ifdef NO_D_INO_IN_DIRENT
 #define SORT_DIRENT 0
@@ -137,7 +140,11 @@ static int traverse_one_object(struct object *obj)
 
 static int traverse_reachable(void)
 {
+       struct progress *progress = NULL;
+       unsigned int nr = 0;
        int result = 0;
+       if (show_progress)
+               progress = start_progress_delay("Checking connectivity", 0, 0, 2);
        while (pending.nr) {
                struct object_array_entry *entry;
                struct object *obj;
@@ -145,7 +152,9 @@ static int traverse_reachable(void)
                entry = pending.objects + --pending.nr;
                obj = entry->item;
                result |= traverse_one_object(obj);
+               display_progress(progress, ++nr);
        }
+       stop_progress(&progress);
        return !!result;
 }
 
@@ -281,14 +290,8 @@ static void check_connectivity(void)
        }
 }
 
-static int fsck_sha1(const unsigned char *sha1)
+static int fsck_obj(struct object *obj)
 {
-       struct object *obj = parse_object(sha1);
-       if (!obj) {
-               errors_found |= ERROR_OBJECT;
-               return error("%s: object corrupt or missing",
-                            sha1_to_hex(sha1));
-       }
        if (obj->flags & SEEN)
                return 0;
        obj->flags |= SEEN;
@@ -331,6 +334,29 @@ static int fsck_sha1(const unsigned char *sha1)
        return 0;
 }
 
+static int fsck_sha1(const unsigned char *sha1)
+{
+       struct object *obj = parse_object(sha1);
+       if (!obj) {
+               errors_found |= ERROR_OBJECT;
+               return error("%s: object corrupt or missing",
+                            sha1_to_hex(sha1));
+       }
+       return fsck_obj(obj);
+}
+
+static int fsck_obj_buffer(const unsigned char *sha1, enum object_type type,
+                          unsigned long size, void *buffer, int *eaten)
+{
+       struct object *obj;
+       obj = parse_object_buffer(sha1, type, size, buffer, eaten);
+       if (!obj) {
+               errors_found |= ERROR_OBJECT;
+               return error("%s: object corrupt or missing", sha1_to_hex(sha1));
+       }
+       return fsck_obj(obj);
+}
+
 /*
  * This is the sorting chunk size: make it reasonably
  * big so that we can sort well..
@@ -512,15 +538,20 @@ static void get_default_heads(void)
 static void fsck_object_dir(const char *path)
 {
        int i;
+       struct progress *progress = NULL;
 
        if (verbose)
                fprintf(stderr, "Checking object directory\n");
 
+       if (show_progress)
+               progress = start_progress("Checking object directories", 256);
        for (i = 0; i < 256; i++) {
                static char dir[4096];
                sprintf(dir, "%s/%02x", path, i);
                fsck_dir(i, dir);
+               display_progress(progress, i+1);
        }
+       stop_progress(&progress);
        fsck_sha1_list();
 }
 
@@ -591,6 +622,7 @@ static struct option fsck_opts[] = {
        OPT_BOOLEAN(0, "strict", &check_strict, "enable more strict checking"),
        OPT_BOOLEAN(0, "lost-found", &write_lost_and_found,
                                "write dangling objects in .git/lost-found"),
+       OPT_BOOL(0, "progress", &show_progress, "show progress"),
        OPT_END(),
 };
 
@@ -603,6 +635,12 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
        read_replace_refs = 0;
 
        argc = parse_options(argc, argv, prefix, fsck_opts, fsck_usage, 0);
+
+       if (show_progress == -1)
+               show_progress = isatty(2);
+       if (verbose)
+               show_progress = 0;
+
        if (write_lost_and_found) {
                check_full = 1;
                include_reflogs = 0;
@@ -622,20 +660,28 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
 
        if (check_full) {
                struct packed_git *p;
+               uint32_t total = 0, count = 0;
+               struct progress *progress = NULL;
 
                prepare_packed_git();
-               for (p = packed_git; p; p = p->next)
-                       /* verify gives error messages itself */
-                       verify_pack(p);
 
+               if (show_progress) {
+                       for (p = packed_git; p; p = p->next) {
+                               if (open_pack_index(p))
+                                       continue;
+                               total += p->num_objects;
+                       }
+
+                       progress = start_progress("Checking objects", total);
+               }
                for (p = packed_git; p; p = p->next) {
-                       uint32_t j, num;
-                       if (open_pack_index(p))
-                               continue;
-                       num = p->num_objects;
-                       for (j = 0; j < num; j++)
-                               fsck_sha1(nth_packed_object_sha1(p, j));
+                       /* verify gives error messages itself */
+                       if (verify_pack(p, fsck_obj_buffer,
+                                       progress, count))
+                               errors_found |= ERROR_PACK;
+                       count += p->num_objects;
                }
+               stop_progress(&progress);
        }
 
        heads = 0;
index 0498094711d1addd40f526f0c76dd8ddb76ef550..271376d82b4391318fda9d5cfd5a0764d3768117 100644 (file)
@@ -32,7 +32,7 @@ static const char *prune_expire = "2.weeks.ago";
 static const char *argv_pack_refs[] = {"pack-refs", "--all", "--prune", NULL};
 static const char *argv_reflog[] = {"reflog", "expire", "--all", NULL};
 static const char *argv_repack[MAX_ADD] = {"repack", "-d", "-l", NULL};
-static const char *argv_prune[] = {"prune", "--expire", NULL, NULL};
+static const char *argv_prune[] = {"prune", "--expire", NULL, NULL, NULL};
 static const char *argv_rerere[] = {"rerere", "gc", NULL};
 
 static int gc_config(const char *var, const char *value, void *cb)
@@ -243,6 +243,8 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
 
        if (prune_expire) {
                argv_prune[2] = prune_expire;
+               if (quiet)
+                       argv_prune[3] = "--no-progress";
                if (run_command_v_opt(argv_prune, RUN_GIT_CMD))
                        return error(FAILED_RUN, argv_prune[0]);
        }
index 3d7329d78c6e3ec31ed8ce03b8928c9ed24afb9e..988ea1d3324d6e32fcfd3b97da0fad5ae41b592c 100644 (file)
@@ -557,18 +557,19 @@ static int grep_cache(struct grep_opt *opt, const struct pathspec *pathspec, int
 static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
                     struct tree_desc *tree, struct strbuf *base, int tn_len)
 {
-       int hit = 0, match = 0;
+       int hit = 0;
+       enum interesting match = entry_not_interesting;
        struct name_entry entry;
        int old_baselen = base->len;
 
        while (tree_entry(tree, &entry)) {
-               int te_len = tree_entry_len(entry.path, entry.sha1);
+               int te_len = tree_entry_len(&entry);
 
-               if (match != 2) {
+               if (match != all_entries_interesting) {
                        match = tree_entry_interesting(&entry, base, tn_len, pathspec);
-                       if (match < 0)
+                       if (match == all_entries_not_interesting)
                                break;
-                       if (match == 0)
+                       if (match == entry_not_interesting)
                                continue;
                }
 
index 0945adbb3bb188b612341c31c8986fabb491928d..98025da7670aaa9f79bfc7faa3a26c4079682fbb 100644 (file)
@@ -1122,8 +1122,10 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
                if (!index_name)
                        die("--verify with no packfile name given");
                read_idx_option(&opts, index_name);
-               opts.flags |= WRITE_IDX_VERIFY;
+               opts.flags |= WRITE_IDX_VERIFY | WRITE_IDX_STRICT;
        }
+       if (strict)
+               opts.flags |= WRITE_IDX_STRICT;
 
        curr_pack = open_pack_file(pack_name);
        parse_pack_header();
index f5d49305903911eb7aa0fb3f73e0fd950b896228..4395f3e47168b2b6274026867bddb472dc244f36 100644 (file)
@@ -19,6 +19,7 @@
 #include "remote.h"
 #include "string-list.h"
 #include "parse-options.h"
+#include "branch.h"
 
 /* Set a default date-time format for git log ("log.date" config variable) */
 static const char *default_date_mode = NULL;
@@ -746,10 +747,24 @@ static void print_signature(void)
                printf("-- \n%s\n\n", signature);
 }
 
+static void add_branch_description(struct strbuf *buf, const char *branch_name)
+{
+       struct strbuf desc = STRBUF_INIT;
+       if (!branch_name || !*branch_name)
+               return;
+       read_branch_desc(&desc, branch_name);
+       if (desc.len) {
+               strbuf_addch(buf, '\n');
+               strbuf_add(buf, desc.buf, desc.len);
+               strbuf_addch(buf, '\n');
+       }
+}
+
 static void make_cover_letter(struct rev_info *rev, int use_stdout,
                              int numbered, int numbered_files,
                              struct commit *origin,
                              int nr, struct commit **list, struct commit *head,
+                             const char *branch_name,
                              int quiet)
 {
        const char *committer;
@@ -807,6 +822,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
        pp_user_info(&pp, NULL, &sb, committer, encoding);
        pp_title_line(&pp, &msg, &sb, encoding, need_8bit_cte);
        pp_remainder(&pp, &msg, &sb, 0);
+       add_branch_description(&sb, branch_name);
        printf("%s\n", sb.buf);
 
        strbuf_release(&sb);
@@ -1006,6 +1022,35 @@ static int cc_callback(const struct option *opt, const char *arg, int unset)
        return 0;
 }
 
+static char *find_branch_name(struct rev_info *rev)
+{
+       int i, positive = -1;
+       unsigned char branch_sha1[20];
+       struct strbuf buf = STRBUF_INIT;
+       const char *branch;
+
+       for (i = 0; i < rev->cmdline.nr; i++) {
+               if (rev->cmdline.rev[i].flags & UNINTERESTING)
+                       continue;
+               if (positive < 0)
+                       positive = i;
+               else
+                       return NULL;
+       }
+       if (positive < 0)
+               return NULL;
+       strbuf_addf(&buf, "refs/heads/%s", rev->cmdline.rev[positive].name);
+       branch = resolve_ref(buf.buf, branch_sha1, 1, NULL);
+       if (!branch ||
+           prefixcmp(branch, "refs/heads/") ||
+           hashcmp(rev->cmdline.rev[positive].item->sha1, branch_sha1))
+               branch = NULL;
+       strbuf_release(&buf);
+       if (branch)
+               return xstrdup(rev->cmdline.rev[positive].name);
+       return NULL;
+}
+
 int cmd_format_patch(int argc, const char **argv, const char *prefix)
 {
        struct commit *commit;
@@ -1027,6 +1072,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
        struct strbuf buf = STRBUF_INIT;
        int use_patch_format = 0;
        int quiet = 0;
+       char *branch_name = NULL;
        const struct option builtin_format_patch_options[] = {
                { OPTION_CALLBACK, 'n', "numbered", &numbered, NULL,
                            "use [PATCH n/m] even with a single patch",
@@ -1217,8 +1263,16 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
                         * origin" that prepares what the origin side still
                         * does not have.
                         */
+                       unsigned char sha1[20];
+                       const char *ref;
+
                        rev.pending.objects[0].item->flags |= UNINTERESTING;
                        add_head_to_pending(&rev);
+                       ref = resolve_ref("HEAD", sha1, 1, NULL);
+                       if (ref && !prefixcmp(ref, "refs/heads/"))
+                               branch_name = xstrdup(ref + strlen("refs/heads/"));
+                       else
+                               branch_name = xstrdup(""); /* no branch */
                }
                /*
                 * Otherwise, it is "format-patch -22 HEAD", and/or
@@ -1234,16 +1288,26 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
        rev.show_root_diff = 1;
 
        if (cover_letter) {
-               /* remember the range */
+               /*
+                * NEEDSWORK:randomly pick one positive commit to show
+                * diffstat; this is often the tip and the command
+                * happens to do the right thing in most cases, but a
+                * complex command like "--cover-letter a b c ^bottom"
+                * picks "c" and shows diffstat between bottom..c
+                * which may not match what the series represents at
+                * all and totally broken.
+                */
                int i;
                for (i = 0; i < rev.pending.nr; i++) {
                        struct object *o = rev.pending.objects[i].item;
                        if (!(o->flags & UNINTERESTING))
                                head = (struct commit *)o;
                }
-               /* We can't generate a cover letter without any patches */
+               /* There is nothing to show; it is not an error, though. */
                if (!head)
                        return 0;
+               if (!branch_name)
+                       branch_name = find_branch_name(&rev);
        }
 
        if (ignore_if_in_upstream) {
@@ -1294,7 +1358,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
                if (thread)
                        gen_message_id(&rev, "cover");
                make_cover_letter(&rev, use_stdout, numbered, numbered_files,
-                                 origin, nr, list, head, quiet);
+                                 origin, nr, list, head, branch_name, quiet);
                total++;
                start_number--;
        }
@@ -1366,6 +1430,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
                        fclose(stdout);
        }
        free(list);
+       free(branch_name);
        string_list_clear(&extra_to, 0);
        string_list_clear(&extra_cc, 0);
        string_list_clear(&extra_hdr, 0);
index 9cda40003e7af5ff55acd2793248f78916ff433d..a1c85344b2b54f957ea69ace864ea99b7d295405 100644 (file)
@@ -26,6 +26,7 @@
 #include "merge-recursive.h"
 #include "resolve-undo.h"
 #include "remote.h"
+#include "fmt-merge-msg.h"
 
 #define DEFAULT_TWOHEAD (1<<0)
 #define DEFAULT_OCTOPUS (1<<1)
@@ -44,7 +45,7 @@ static const char * const builtin_merge_usage[] = {
        NULL
 };
 
-static int show_diffstat = 1, shortlog_len, squash;
+static int show_diffstat = 1, shortlog_len = -1, squash;
 static int option_commit = 1, allow_fast_forward = 1;
 static int fast_forward_only, option_edit;
 static int allow_trivial = 1, have_message;
@@ -316,13 +317,15 @@ static void squash_message(struct commit *commit)
        struct rev_info rev;
        struct strbuf out = STRBUF_INIT;
        struct commit_list *j;
+       const char *filename;
        int fd;
        struct pretty_print_context ctx = {0};
 
        printf(_("Squash commit -- not updating HEAD\n"));
-       fd = open(git_path("SQUASH_MSG"), O_WRONLY | O_CREAT, 0666);
+       filename = git_path("SQUASH_MSG");
+       fd = open(filename, O_WRONLY | O_CREAT, 0666);
        if (fd < 0)
-               die_errno(_("Could not write to '%s'"), git_path("SQUASH_MSG"));
+               die_errno(_("Could not write to '%s'"), filename);
 
        init_revisions(&rev, NULL);
        rev.ignore_merges = 1;
@@ -406,20 +409,10 @@ static void finish(struct commit *head_commit,
        strbuf_release(&reflog_message);
 }
 
-static struct object *want_commit(const char *name)
-{
-       struct object *obj;
-       unsigned char sha1[20];
-       if (get_sha1(name, sha1))
-               return NULL;
-       obj = parse_object(sha1);
-       return peel_to_type(name, 0, obj, OBJ_COMMIT);
-}
-
 /* Get the name for the merge commit's message. */
 static void merge_name(const char *remote, struct strbuf *msg)
 {
-       struct object *remote_head;
+       struct commit *remote_head;
        unsigned char branch_head[20];
        struct strbuf buf = STRBUF_INIT;
        struct strbuf bname = STRBUF_INIT;
@@ -431,7 +424,7 @@ static void merge_name(const char *remote, struct strbuf *msg)
        remote = bname.buf;
 
        memset(branch_head, 0, sizeof(branch_head));
-       remote_head = want_commit(remote);
+       remote_head = get_merge_parent(remote);
        if (!remote_head)
                die(_("'%s' does not point to a commit"), remote);
 
@@ -441,6 +434,11 @@ static void merge_name(const char *remote, struct strbuf *msg)
                                    sha1_to_hex(branch_head), remote);
                        goto cleanup;
                }
+               if (!prefixcmp(found_ref, "refs/tags/")) {
+                       strbuf_addf(msg, "%s\t\ttag '%s' of .\n",
+                                   sha1_to_hex(branch_head), remote);
+                       goto cleanup;
+               }
                if (!prefixcmp(found_ref, "refs/remotes/")) {
                        strbuf_addf(msg, "%s\t\tremote-tracking branch '%s' of .\n",
                                    sha1_to_hex(branch_head), remote);
@@ -482,7 +480,7 @@ static void merge_name(const char *remote, struct strbuf *msg)
                if (ref_exists(truname.buf)) {
                        strbuf_addf(msg,
                                    "%s\t\tbranch '%s'%s of .\n",
-                                   sha1_to_hex(remote_head->sha1),
+                                   sha1_to_hex(remote_head->object.sha1),
                                    truname.buf + 11,
                                    (early ? " (early part)" : ""));
                        strbuf_release(&truname);
@@ -492,14 +490,16 @@ static void merge_name(const char *remote, struct strbuf *msg)
 
        if (!strcmp(remote, "FETCH_HEAD") &&
                        !access(git_path("FETCH_HEAD"), R_OK)) {
+               const char *filename;
                FILE *fp;
                struct strbuf line = STRBUF_INIT;
                char *ptr;
 
-               fp = fopen(git_path("FETCH_HEAD"), "r");
+               filename = git_path("FETCH_HEAD");
+               fp = fopen(filename, "r");
                if (!fp)
                        die_errno(_("could not open '%s' for reading"),
-                                 git_path("FETCH_HEAD"));
+                                 filename);
                strbuf_getline(&line, fp, '\n');
                fclose(fp);
                ptr = strstr(line.buf, "\tnot-for-merge\t");
@@ -510,7 +510,7 @@ static void merge_name(const char *remote, struct strbuf *msg)
                goto cleanup;
        }
        strbuf_addf(msg, "%s\t\tcommit '%s'\n",
-               sha1_to_hex(remote_head->sha1), remote);
+               sha1_to_hex(remote_head->object.sha1), remote);
 cleanup:
        strbuf_release(&buf);
        strbuf_release(&bname);
@@ -538,6 +538,8 @@ static void parse_branch_merge_options(char *bmo)
 
 static int git_merge_config(const char *k, const char *v, void *cb)
 {
+       int status;
+
        if (branch && !prefixcmp(k, "branch.") &&
                !prefixcmp(k + 7, branch) &&
                !strcmp(k + 7 + strlen(branch), ".mergeoptions")) {
@@ -554,15 +556,7 @@ static int git_merge_config(const char *k, const char *v, void *cb)
                return git_config_string(&pull_octopus, k, v);
        else if (!strcmp(k, "merge.renormalize"))
                option_renormalize = git_config_bool(k, v);
-       else if (!strcmp(k, "merge.log") || !strcmp(k, "merge.summary")) {
-               int is_bool;
-               shortlog_len = git_config_bool_or_int(k, v, &is_bool);
-               if (!is_bool && shortlog_len < 0)
-                       return error(_("%s: negative length %s"), k, v);
-               if (is_bool && shortlog_len)
-                       shortlog_len = DEFAULT_MERGE_LOG_LEN;
-               return 0;
-       } else if (!strcmp(k, "merge.ff")) {
+       else if (!strcmp(k, "merge.ff")) {
                int boolval = git_config_maybe_bool(k, v);
                if (0 <= boolval) {
                        allow_fast_forward = boolval;
@@ -575,6 +569,9 @@ static int git_merge_config(const char *k, const char *v, void *cb)
                default_to_upstream = git_config_bool(k, v);
                return 0;
        }
+       status = fmt_merge_msg_config(k, v, cb);
+       if (status)
+               return status;
        return git_diff_ui_config(k, v, cb);
 }
 
@@ -714,7 +711,7 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
                                die(_("Unknown option for merge-recursive: -X%s"), xopts[x]);
 
                o.branch1 = head_arg;
-               o.branch2 = remoteheads->item->util;
+               o.branch2 = merge_remote_util(remoteheads->item)->name;
 
                for (j = common; j; j = j->next)
                        commit_list_insert(j->item, &reversed);
@@ -771,7 +768,7 @@ int checkout_fast_forward(const unsigned char *head, const unsigned char *remote
        memset(&t, 0, sizeof(t));
        memset(&dir, 0, sizeof(dir));
        dir.flags |= DIR_SHOW_IGNORED;
-       dir.exclude_per_dir = ".gitignore";
+       setup_standard_excludes(&dir);
        opts.dir = &dir;
 
        opts.head_idx = 1;
@@ -847,20 +844,22 @@ static void add_strategies(const char *string, unsigned attr)
 
 static void write_merge_msg(struct strbuf *msg)
 {
-       int fd = open(git_path("MERGE_MSG"), O_WRONLY | O_CREAT, 0666);
+       const char *filename = git_path("MERGE_MSG");
+       int fd = open(filename, O_WRONLY | O_CREAT, 0666);
        if (fd < 0)
                die_errno(_("Could not open '%s' for writing"),
-                         git_path("MERGE_MSG"));
+                         filename);
        if (write_in_full(fd, msg->buf, msg->len) != msg->len)
-               die_errno(_("Could not write to '%s'"), git_path("MERGE_MSG"));
+               die_errno(_("Could not write to '%s'"), filename);
        close(fd);
 }
 
 static void read_merge_msg(struct strbuf *msg)
 {
+       const char *filename = git_path("MERGE_MSG");
        strbuf_reset(msg);
-       if (strbuf_read_file(msg, git_path("MERGE_MSG"), 0) < 0)
-               die_errno(_("Could not read from '%s'"), git_path("MERGE_MSG"));
+       if (strbuf_read_file(msg, filename, 0) < 0)
+               die_errno(_("Could not read from '%s'"), filename);
 }
 
 static void write_merge_state(void);
@@ -948,13 +947,14 @@ static int finish_automerge(struct commit *head,
 
 static int suggest_conflicts(int renormalizing)
 {
+       const char *filename;
        FILE *fp;
        int pos;
 
-       fp = fopen(git_path("MERGE_MSG"), "a");
+       filename = git_path("MERGE_MSG");
+       fp = fopen(filename, "a");
        if (!fp)
-               die_errno(_("Could not open '%s' for writing"),
-                         git_path("MERGE_MSG"));
+               die_errno(_("Could not open '%s' for writing"), filename);
        fprintf(fp, "\nConflicts:\n");
        for (pos = 0; pos < active_nr; pos++) {
                struct cache_entry *ce = active_cache[pos];
@@ -1046,31 +1046,40 @@ static int setup_with_upstream(const char ***argv)
 
 static void write_merge_state(void)
 {
+       const char *filename;
        int fd;
        struct commit_list *j;
        struct strbuf buf = STRBUF_INIT;
 
-       for (j = remoteheads; j; j = j->next)
-               strbuf_addf(&buf, "%s\n",
-                       sha1_to_hex(j->item->object.sha1));
-       fd = open(git_path("MERGE_HEAD"), O_WRONLY | O_CREAT, 0666);
+       for (j = remoteheads; j; j = j->next) {
+               unsigned const char *sha1;
+               struct commit *c = j->item;
+               if (c->util && merge_remote_util(c)->obj) {
+                       sha1 = merge_remote_util(c)->obj->sha1;
+               } else {
+                       sha1 = c->object.sha1;
+               }
+               strbuf_addf(&buf, "%s\n", sha1_to_hex(sha1));
+       }
+       filename = git_path("MERGE_HEAD");
+       fd = open(filename, O_WRONLY | O_CREAT, 0666);
        if (fd < 0)
-               die_errno(_("Could not open '%s' for writing"),
-                         git_path("MERGE_HEAD"));
+               die_errno(_("Could not open '%s' for writing"), filename);
        if (write_in_full(fd, buf.buf, buf.len) != buf.len)
-               die_errno(_("Could not write to '%s'"), git_path("MERGE_HEAD"));
+               die_errno(_("Could not write to '%s'"), filename);
        close(fd);
        strbuf_addch(&merge_msg, '\n');
        write_merge_msg(&merge_msg);
-       fd = open(git_path("MERGE_MODE"), O_WRONLY | O_CREAT | O_TRUNC, 0666);
+
+       filename = git_path("MERGE_MODE");
+       fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
        if (fd < 0)
-               die_errno(_("Could not open '%s' for writing"),
-                         git_path("MERGE_MODE"));
+               die_errno(_("Could not open '%s' for writing"), filename);
        strbuf_reset(&buf);
        if (!allow_fast_forward)
                strbuf_addf(&buf, "no-ff");
        if (write_in_full(fd, buf.buf, buf.len) != buf.len)
-               die_errno(_("Could not write to '%s'"), git_path("MERGE_MODE"));
+               die_errno(_("Could not write to '%s'"), filename);
        close(fd);
 }
 
@@ -1112,6 +1121,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
                parse_branch_merge_options(branch_mergeoptions);
        argc = parse_options(argc, argv, prefix, builtin_merge_options,
                        builtin_merge_usage, 0);
+       if (shortlog_len < 0)
+               shortlog_len = (merge_log_config > 0) ? merge_log_config : 0;
 
        if (verbosity < 0 && show_progress == -1)
                show_progress = 0;
@@ -1164,9 +1175,12 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
                die(_("You cannot combine --no-ff with --ff-only."));
 
        if (!abort_current_merge) {
-               if (!argc && default_to_upstream)
-                       argc = setup_with_upstream(&argv);
-               else if (argc == 1 && !strcmp(argv[0], "-"))
+               if (!argc) {
+                       if (default_to_upstream)
+                               argc = setup_with_upstream(&argv);
+                       else
+                               die(_("No commit specified and merge.defaultToUpstream not set."));
+               } else if (argc == 1 && !strcmp(argv[0], "-"))
                        argv[0] = "@{-1}";
        }
        if (!argc)
@@ -1189,7 +1203,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
                argv += 2;
                argc -= 2;
        } else if (!head_commit) {
-               struct object *remote_head;
+               struct commit *remote_head;
                /*
                 * If the merged head is a valid one there is no reason
                 * to forbid "git merge" into a branch yet to be born.
@@ -1203,12 +1217,12 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
                if (!allow_fast_forward)
                        die(_("Non-fast-forward commit does not make sense into "
                            "an empty head"));
-               remote_head = want_commit(argv[0]);
+               remote_head = get_merge_parent(argv[0]);
                if (!remote_head)
                        die(_("%s - not something we can merge"), argv[0]);
-               read_empty(remote_head->sha1, 0);
-               update_ref("initial pull", "HEAD", remote_head->sha1, NULL, 0,
-                               DIE_ON_ERR);
+               read_empty(remote_head->object.sha1, 0);
+               update_ref("initial pull", "HEAD", remote_head->object.sha1,
+                          NULL, 0, DIE_ON_ERR);
                goto done;
        } else {
                struct strbuf merge_names = STRBUF_INIT;
@@ -1217,19 +1231,20 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
                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.
+                * All the rest are the commits being merged; prepare
+                * the standard merge summary message to be appended
+                * to the given message.
                 */
                for (i = 0; i < argc; i++)
                        merge_name(argv[i], &merge_names);
 
                if (!have_message || shortlog_len) {
-                       fmt_merge_msg(&merge_names, &merge_msg, !have_message,
-                                     shortlog_len);
+                       struct fmt_merge_msg_opts opts;
+                       memset(&opts, 0, sizeof(opts));
+                       opts.add_title = !have_message;
+                       opts.shortlog_len = shortlog_len;
+
+                       fmt_merge_msg(&merge_names, &merge_msg, &opts);
                        if (merge_msg.len)
                                strbuf_setlen(&merge_msg, merge_msg.len - 1);
                }
@@ -1246,19 +1261,20 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
        strbuf_reset(&buf);
 
        for (i = 0; i < argc; i++) {
-               struct object *o;
-               struct commit *commit;
-
-               o = want_commit(argv[i]);
-               if (!o)
+               struct commit *commit = get_merge_parent(argv[i]);
+               if (!commit)
                        die(_("%s - not something we can merge"), argv[i]);
-               commit = lookup_commit(o->sha1);
-               commit->util = (void *)argv[i];
                remotes = &commit_list_insert(commit, remotes)->next;
-
-               strbuf_addf(&buf, "GITHEAD_%s", sha1_to_hex(o->sha1));
+               strbuf_addf(&buf, "GITHEAD_%s",
+                           sha1_to_hex(commit->object.sha1));
                setenv(buf.buf, argv[i], 1);
                strbuf_reset(&buf);
+               if (merge_remote_util(commit) &&
+                   merge_remote_util(commit)->obj &&
+                   merge_remote_util(commit)->obj->type == OBJ_TAG) {
+                       option_edit = 1;
+                       allow_fast_forward = 0;
+               }
        }
 
        if (!use_strategies) {
@@ -1302,7 +1318,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
                        !hashcmp(common->item->object.sha1, head_commit->object.sha1)) {
                /* Again the most common case of merging one remote. */
                struct strbuf msg = STRBUF_INIT;
-               struct object *o;
+               struct commit *commit;
                char hex[41];
 
                strcpy(hex, find_unique_abbrev(head_commit->object.sha1, DEFAULT_ABBREV));
@@ -1316,19 +1332,19 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
                if (have_message)
                        strbuf_addstr(&msg,
                                " (no commit created; -m option ignored)");
-               o = want_commit(sha1_to_hex(remoteheads->item->object.sha1));
-               if (!o) {
+               commit = remoteheads->item;
+               if (!commit) {
                        ret = 1;
                        goto done;
                }
 
                if (checkout_fast_forward(head_commit->object.sha1,
-                                         remoteheads->item->object.sha1)) {
+                                         commit->object.sha1)) {
                        ret = 1;
                        goto done;
                }
 
-               finish(head_commit, o->sha1, msg.buf);
+               finish(head_commit, commit->object.sha1, msg.buf);
                drop_save();
                goto done;
        } else if (!remoteheads->next && common->next)
index 7864056f1ee64b896a7378cc76555e2cf7c3fd89..1b374583c2751801dfae1d0d1861d28f81c7ad7b 100644 (file)
@@ -291,7 +291,7 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
                max = get_max_object_index();
                for (i = 0; i < max; i++) {
                        struct object *obj = get_indexed_object(i);
-                       if (!obj)
+                       if (!obj || obj->type != OBJ_COMMIT)
                                continue;
                        show_name(obj, NULL,
                                  always, allow_undefined, data.name_only);
index 824ecee20b94c471083ad8c7f697b39fbb7cb2b8..b1895aaaa1520ef910504c3beee685f95e72ec6b 100644 (file)
@@ -409,25 +409,56 @@ static unsigned long write_object(struct sha1file *f,
        return hdrlen + datalen;
 }
 
-static int write_one(struct sha1file *f,
-                              struct object_entry *e,
-                              off_t *offset)
+enum write_one_status {
+       WRITE_ONE_SKIP = -1, /* already written */
+       WRITE_ONE_BREAK = 0, /* writing this will bust the limit; not written */
+       WRITE_ONE_WRITTEN = 1, /* normal */
+       WRITE_ONE_RECURSIVE = 2 /* already scheduled to be written */
+};
+
+static enum write_one_status write_one(struct sha1file *f,
+                                      struct object_entry *e,
+                                      off_t *offset)
 {
        unsigned long size;
+       int recursing;
 
-       /* offset is non zero if object is written already. */
-       if (e->idx.offset || e->preferred_base)
-               return -1;
+       /*
+        * we set offset to 1 (which is an impossible value) to mark
+        * the fact that this object is involved in "write its base
+        * first before writing a deltified object" recursion.
+        */
+       recursing = (e->idx.offset == 1);
+       if (recursing) {
+               warning("recursive delta detected for object %s",
+                       sha1_to_hex(e->idx.sha1));
+               return WRITE_ONE_RECURSIVE;
+       } else if (e->idx.offset || e->preferred_base) {
+               /* offset is non zero if object is written already. */
+               return WRITE_ONE_SKIP;
+       }
 
        /* if we are deltified, write out base object first. */
-       if (e->delta && !write_one(f, e->delta, offset))
-               return 0;
+       if (e->delta) {
+               e->idx.offset = 1; /* now recurse */
+               switch (write_one(f, e->delta, offset)) {
+               case WRITE_ONE_RECURSIVE:
+                       /* we cannot depend on this one */
+                       e->delta = NULL;
+                       break;
+               default:
+                       break;
+               case WRITE_ONE_BREAK:
+                       e->idx.offset = recursing;
+                       return WRITE_ONE_BREAK;
+               }
+       }
 
        e->idx.offset = *offset;
        size = write_object(f, e, *offset);
        if (!size) {
-               e->idx.offset = 0;
-               return 0;
+               e->idx.offset = recursing;
+               return WRITE_ONE_BREAK;
        }
        written_list[nr_written++] = &e->idx;
 
@@ -435,7 +466,7 @@ static int write_one(struct sha1file *f,
        if (signed_add_overflows(*offset, size))
                die("pack too large for current definition of off_t");
        *offset += size;
-       return 1;
+       return WRITE_ONE_WRITTEN;
 }
 
 static int mark_tagged(const char *path, const unsigned char *sha1, int flag,
@@ -640,7 +671,7 @@ static void write_pack_file(void)
                nr_written = 0;
                for (; i < nr_objects; i++) {
                        struct object_entry *e = write_order[i];
-                       if (!write_one(f, e, &offset))
+                       if (write_one(f, e, &offset) == WRITE_ONE_BREAK)
                                break;
                        display_progress(progress_state, written);
                }
@@ -1015,7 +1046,7 @@ static void add_pbase_object(struct tree_desc *tree,
        while (tree_entry(tree,&entry)) {
                if (S_ISGITLINK(entry.mode))
                        continue;
-               cmp = tree_entry_len(entry.path, entry.sha1) != cmplen ? 1 :
+               cmp = tree_entry_len(&entry) != cmplen ? 1 :
                      memcmp(name, entry.path, cmplen);
                if (cmp > 0)
                        continue;
index e65690ba370511072dfa1e64838eef5e5686aac9..58d7cb83240ecef7ab3ff82f3aa92959ec7a62fe 100644 (file)
@@ -5,6 +5,7 @@
 #include "builtin.h"
 #include "reachable.h"
 #include "parse-options.h"
+#include "progress.h"
 #include "dir.h"
 
 static const char * const prune_usage[] = {
@@ -14,6 +15,7 @@ static const char * const prune_usage[] = {
 static int show_only;
 static int verbose;
 static unsigned long expire;
+static int show_progress = -1;
 
 static int prune_tmp_object(const char *path, const char *filename)
 {
@@ -124,9 +126,11 @@ static void remove_temporary_files(const char *path)
 int cmd_prune(int argc, const char **argv, const char *prefix)
 {
        struct rev_info revs;
+       struct progress *progress = NULL;
        const struct option options[] = {
                OPT__DRY_RUN(&show_only, "do not remove, show only"),
                OPT__VERBOSE(&verbose, "report pruned objects"),
+               OPT_BOOL(0, "progress", &show_progress, "show progress"),
                OPT_DATE(0, "expire", &expire,
                         "expire objects older than <time>"),
                OPT_END()
@@ -152,7 +156,14 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
                else
                        die("unrecognized argument: %s", name);
        }
-       mark_reachable_objects(&revs, 1);
+
+       if (show_progress == -1)
+               show_progress = isatty(2);
+       if (show_progress)
+               progress = start_progress_delay("Checking connectivity", 0, 0, 2);
+
+       mark_reachable_objects(&revs, 1, progress);
+       stop_progress(&progress);
        prune_object_dir(get_object_directory());
 
        prune_packed_objects(show_only);
index 3a9c80f3dbfe26d5623c118fc0fcaa257e01b973..062d7dad1b5af720e70adcaa05b60bf68977b05c 100644 (file)
@@ -647,7 +647,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
                init_revisions(&cb.revs, prefix);
                if (cb.verbose)
                        printf("Marking reachable objects...");
-               mark_reachable_objects(&cb.revs, 0);
+               mark_reachable_objects(&cb.revs, 0, NULL);
                if (cb.verbose)
                        putchar('\n');
        }
index 87df70edc33fcc71177b863e6ced870330e505d0..1ea525c10e4c00b66006bf46465ebd490823f25f 100644 (file)
@@ -40,7 +40,12 @@ static const char * const cherry_pick_usage[] = {
 };
 
 enum replay_action { REVERT, CHERRY_PICK };
-enum replay_subcommand { REPLAY_NONE, REPLAY_RESET, REPLAY_CONTINUE };
+enum replay_subcommand {
+       REPLAY_NONE,
+       REPLAY_REMOVE_STATE,
+       REPLAY_CONTINUE,
+       REPLAY_ROLLBACK
+};
 
 struct replay_opts {
        enum replay_action action;
@@ -133,11 +138,13 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
 {
        const char * const * usage_str = revert_or_cherry_pick_usage(opts);
        const char *me = action_name(opts);
-       int reset = 0;
+       int remove_state = 0;
        int contin = 0;
+       int rollback = 0;
        struct option options[] = {
-               OPT_BOOLEAN(0, "reset", &reset, "forget the current operation"),
-               OPT_BOOLEAN(0, "continue", &contin, "continue the current operation"),
+               OPT_BOOLEAN(0, "quit", &remove_state, "end revert or cherry-pick sequence"),
+               OPT_BOOLEAN(0, "continue", &contin, "resume revert or cherry-pick sequence"),
+               OPT_BOOLEAN(0, "abort", &rollback, "cancel revert or cherry-pick sequence"),
                OPT_BOOLEAN('n', "no-commit", &opts->no_commit, "don't automatically commit"),
                OPT_BOOLEAN('e', "edit", &opts->edit, "edit the commit message"),
                OPT_NOOP_NOARG('r', NULL),
@@ -168,25 +175,32 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
 
        /* Check for incompatible subcommands */
        verify_opt_mutually_compatible(me,
-                               "--reset", reset,
+                               "--quit", remove_state,
                                "--continue", contin,
+                               "--abort", rollback,
                                NULL);
 
        /* Set the subcommand */
-       if (reset)
-               opts->subcommand = REPLAY_RESET;
+       if (remove_state)
+               opts->subcommand = REPLAY_REMOVE_STATE;
        else if (contin)
                opts->subcommand = REPLAY_CONTINUE;
+       else if (rollback)
+               opts->subcommand = REPLAY_ROLLBACK;
        else
                opts->subcommand = REPLAY_NONE;
 
        /* Check for incompatible command line arguments */
        if (opts->subcommand != REPLAY_NONE) {
                char *this_operation;
-               if (opts->subcommand == REPLAY_RESET)
-                       this_operation = "--reset";
-               else
+               if (opts->subcommand == REPLAY_REMOVE_STATE)
+                       this_operation = "--quit";
+               else if (opts->subcommand == REPLAY_CONTINUE)
                        this_operation = "--continue";
+               else {
+                       assert(opts->subcommand == REPLAY_ROLLBACK);
+                       this_operation = "--abort";
+               }
 
                verify_opt_compatible(me, this_operation,
                                "--no-commit", opts->no_commit,
@@ -286,19 +300,20 @@ static char *get_encoding(const char *message)
        return NULL;
 }
 
-static void write_cherry_pick_head(struct commit *commit)
+static void write_cherry_pick_head(struct commit *commit, const char *pseudoref)
 {
+       const char *filename;
        int fd;
        struct strbuf buf = STRBUF_INIT;
 
        strbuf_addf(&buf, "%s\n", sha1_to_hex(commit->object.sha1));
 
-       fd = open(git_path("CHERRY_PICK_HEAD"), O_WRONLY | O_CREAT, 0666);
+       filename = git_path("%s", pseudoref);
+       fd = open(filename, O_WRONLY | O_CREAT, 0666);
        if (fd < 0)
-               die_errno(_("Could not open '%s' for writing"),
-                         git_path("CHERRY_PICK_HEAD"));
+               die_errno(_("Could not open '%s' for writing"), filename);
        if (write_in_full(fd, buf.buf, buf.len) != buf.len || close(fd))
-               die_errno(_("Could not write to '%s'"), git_path("CHERRY_PICK_HEAD"));
+               die_errno(_("Could not write to '%s'"), filename);
        strbuf_release(&buf);
 }
 
@@ -331,7 +346,7 @@ static void write_message(struct strbuf *msgbuf, const char *filename)
        int msg_fd = hold_lock_file_for_update(&msg_file, filename,
                                               LOCK_DIE_ON_ERROR);
        if (write_in_full(msg_fd, msgbuf->buf, msgbuf->len) < 0)
-               die_errno(_("Could not write to %s."), filename);
+               die_errno(_("Could not write to %s"), filename);
        strbuf_release(msgbuf);
        if (commit_lock_file(&msg_file) < 0)
                die(_("Error wrapping up %s"), filename);
@@ -593,7 +608,9 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
         * write it at all.
         */
        if (opts->action == CHERRY_PICK && !opts->no_commit && (res == 0 || res == 1))
-               write_cherry_pick_head(commit);
+               write_cherry_pick_head(commit, "CHERRY_PICK_HEAD");
+       if (opts->action == REVERT && ((opts->no_commit && res == 0) || res == 1))
+               write_cherry_pick_head(commit, "REVERT_HEAD");
 
        if (res) {
                error(opts->action == REVERT
@@ -767,7 +784,7 @@ static void read_populate_todo(struct commit_list **todo_list,
 
        fd = open(todo_file, O_RDONLY);
        if (fd < 0)
-               die_errno(_("Could not open %s."), todo_file);
+               die_errno(_("Could not open %s"), todo_file);
        if (strbuf_read(&buf, fd, 0) < 0) {
                close(fd);
                strbuf_release(&buf);
@@ -842,10 +859,13 @@ static int create_seq_dir(void)
 {
        const char *seq_dir = git_path(SEQ_DIR);
 
-       if (file_exists(seq_dir))
-               return error(_("%s already exists."), seq_dir);
+       if (file_exists(seq_dir)) {
+               error(_("a cherry-pick or revert is already in progress"));
+               advise(_("try \"git cherry-pick (--continue | --quit | --abort)\""));
+               return -1;
+       }
        else if (mkdir(seq_dir, 0777) < 0)
-               die_errno(_("Could not create sequencer directory '%s'."), seq_dir);
+               die_errno(_("Could not create sequencer directory %s"), seq_dir);
        return 0;
 }
 
@@ -859,11 +879,77 @@ static void save_head(const char *head)
        fd = hold_lock_file_for_update(&head_lock, head_file, LOCK_DIE_ON_ERROR);
        strbuf_addf(&buf, "%s\n", head);
        if (write_in_full(fd, buf.buf, buf.len) < 0)
-               die_errno(_("Could not write to %s."), head_file);
+               die_errno(_("Could not write to %s"), head_file);
        if (commit_lock_file(&head_lock) < 0)
                die(_("Error wrapping up %s."), head_file);
 }
 
+static int reset_for_rollback(const unsigned char *sha1)
+{
+       const char *argv[4];    /* reset --merge <arg> + NULL */
+       argv[0] = "reset";
+       argv[1] = "--merge";
+       argv[2] = sha1_to_hex(sha1);
+       argv[3] = NULL;
+       return run_command_v_opt(argv, RUN_GIT_CMD);
+}
+
+static int rollback_single_pick(void)
+{
+       unsigned char head_sha1[20];
+
+       if (!file_exists(git_path("CHERRY_PICK_HEAD")) &&
+           !file_exists(git_path("REVERT_HEAD")))
+               return error(_("no cherry-pick or revert in progress"));
+       if (!resolve_ref("HEAD", head_sha1, 0, NULL))
+               return error(_("cannot resolve HEAD"));
+       if (is_null_sha1(head_sha1))
+               return error(_("cannot abort from a branch yet to be born"));
+       return reset_for_rollback(head_sha1);
+}
+
+static int sequencer_rollback(struct replay_opts *opts)
+{
+       const char *filename;
+       FILE *f;
+       unsigned char sha1[20];
+       struct strbuf buf = STRBUF_INIT;
+
+       filename = git_path(SEQ_HEAD_FILE);
+       f = fopen(filename, "r");
+       if (!f && errno == ENOENT) {
+               /*
+                * There is no multiple-cherry-pick in progress.
+                * If CHERRY_PICK_HEAD or REVERT_HEAD indicates
+                * a single-cherry-pick in progress, abort that.
+                */
+               return rollback_single_pick();
+       }
+       if (!f)
+               return error(_("cannot open %s: %s"), filename,
+                                               strerror(errno));
+       if (strbuf_getline(&buf, f, '\n')) {
+               error(_("cannot read %s: %s"), filename, ferror(f) ?
+                       strerror(errno) : _("unexpected end of file"));
+               fclose(f);
+               goto fail;
+       }
+       fclose(f);
+       if (get_sha1_hex(buf.buf, sha1) || buf.buf[40] != '\0') {
+               error(_("stored pre-cherry-pick HEAD file '%s' is corrupt"),
+                       filename);
+               goto fail;
+       }
+       if (reset_for_rollback(sha1))
+               goto fail;
+       remove_sequencer_state(1);
+       strbuf_release(&buf);
+       return 0;
+fail:
+       strbuf_release(&buf);
+       return -1;
+}
+
 static void save_todo(struct commit_list *todo_list, struct replay_opts *opts)
 {
        const char *todo_file = git_path(SEQ_TODO_FILE);
@@ -876,7 +962,7 @@ static void save_todo(struct commit_list *todo_list, struct replay_opts *opts)
                die(_("Could not format %s."), todo_file);
        if (write_in_full(fd, buf.buf, buf.len) < 0) {
                strbuf_release(&buf);
-               die_errno(_("Could not write to %s."), todo_file);
+               die_errno(_("Could not write to %s"), todo_file);
        }
        if (commit_lock_file(&todo_lock) < 0) {
                strbuf_release(&buf);
@@ -964,43 +1050,41 @@ static int pick_revisions(struct replay_opts *opts)
         * cherry-pick should be handled differently from an existing
         * one that is being continued
         */
-       if (opts->subcommand == REPLAY_RESET) {
+       if (opts->subcommand == REPLAY_REMOVE_STATE) {
                remove_sequencer_state(1);
                return 0;
-       } else if (opts->subcommand == REPLAY_CONTINUE) {
+       }
+       if (opts->subcommand == REPLAY_ROLLBACK)
+               return sequencer_rollback(opts);
+       if (opts->subcommand == REPLAY_CONTINUE) {
                if (!file_exists(git_path(SEQ_TODO_FILE)))
-                       goto error;
+                       return error(_("No %s in progress"), action_name(opts));
                read_populate_opts(&opts);
                read_populate_todo(&todo_list, opts);
 
                /* Verify that the conflict has been resolved */
                if (!index_differs_from("HEAD", 0))
                        todo_list = todo_list->next;
-       } else {
-               /*
-                * Start a new cherry-pick/ revert sequence; but
-                * first, make sure that an existing one isn't in
-                * progress
-                */
+               return pick_commits(todo_list, opts);
+       }
 
-               walk_revs_populate_todo(&todo_list, opts);
-               if (create_seq_dir() < 0) {
-                       error(_("A cherry-pick or revert is in progress."));
-                       advise(_("Use --continue to continue the operation"));
-                       advise(_("or --reset to forget about it"));
-                       return -1;
-               }
-               if (get_sha1("HEAD", sha1)) {
-                       if (opts->action == REVERT)
-                               return error(_("Can't revert as initial commit"));
-                       return error(_("Can't cherry-pick into empty head"));
-               }
-               save_head(sha1_to_hex(sha1));
-               save_opts(opts);
+       /*
+        * Start a new cherry-pick/ revert sequence; but
+        * first, make sure that an existing one isn't in
+        * progress
+        */
+
+       walk_revs_populate_todo(&todo_list, opts);
+       if (create_seq_dir() < 0)
+               return -1;
+       if (get_sha1("HEAD", sha1)) {
+               if (opts->action == REVERT)
+                       return error(_("Can't revert as initial commit"));
+               return error(_("Can't cherry-pick into empty head"));
        }
+       save_head(sha1_to_hex(sha1));
+       save_opts(opts);
        return pick_commits(todo_list, opts);
-error:
-       return error(_("No %s in progress"), action_name(opts));
 }
 
 int cmd_revert(int argc, const char **argv, const char *prefix)
index 4d3b93fedb5f2eca68edca15ca1e10cb60176d36..1288ffcc52530f8ef9561acd2eb2ec5322c9e230 100644 (file)
@@ -22,8 +22,6 @@ static size_t cleanup(char *line, size_t len)
  * Remove empty lines from the beginning and end
  * and also trailing spaces from every line.
  *
- * Note that the buffer will not be NUL-terminated.
- *
  * Turn multiple consecutive empty lines between paragraphs
  * into just one empty line.
  *
index 439249d466ccb9d3e4d78764b8b4b8c44536a7b5..efb98726955837294190fcef365e45b0dd5f5396 100644 (file)
@@ -14,6 +14,7 @@
 #include "parse-options.h"
 #include "diff.h"
 #include "revision.h"
+#include "gpg-interface.h"
 
 static const char * const git_tag_usage[] = {
        "git tag [-a|-s|-u <key-id>] [-f] [-m <msg>|-F <file>] <tagname> [<head>]",
@@ -23,8 +24,6 @@ static const char * const git_tag_usage[] = {
        NULL
 };
 
-static char signingkey[1000];
-
 struct tag_filter {
        const char **patterns;
        int lines;
@@ -208,60 +207,7 @@ static int verify_tag(const char *name, const char *ref,
 
 static int do_sign(struct strbuf *buffer)
 {
-       struct child_process gpg;
-       const char *args[4];
-       char *bracket;
-       int len;
-       int i, j;
-
-       if (!*signingkey) {
-               if (strlcpy(signingkey, git_committer_info(IDENT_ERROR_ON_NO_NAME),
-                               sizeof(signingkey)) > sizeof(signingkey) - 1)
-                       return error(_("committer info too long."));
-               bracket = strchr(signingkey, '>');
-               if (bracket)
-                       bracket[1] = '\0';
-       }
-
-       /* When the username signingkey is bad, program could be terminated
-        * because gpg exits without reading and then write gets SIGPIPE. */
-       signal(SIGPIPE, SIG_IGN);
-
-       memset(&gpg, 0, sizeof(gpg));
-       gpg.argv = args;
-       gpg.in = -1;
-       gpg.out = -1;
-       args[0] = "gpg";
-       args[1] = "-bsau";
-       args[2] = signingkey;
-       args[3] = NULL;
-
-       if (start_command(&gpg))
-               return error(_("could not run gpg."));
-
-       if (write_in_full(gpg.in, buffer->buf, buffer->len) != buffer->len) {
-               close(gpg.in);
-               close(gpg.out);
-               finish_command(&gpg);
-               return error(_("gpg did not accept the tag data"));
-       }
-       close(gpg.in);
-       len = strbuf_read(buffer, gpg.out, 1024);
-       close(gpg.out);
-
-       if (finish_command(&gpg) || !len || len < 0)
-               return error(_("gpg failed to sign the tag"));
-
-       /* Strip CR from the line endings, in case we are on Windows. */
-       for (i = j = 0; i < buffer->len; i++)
-               if (buffer->buf[i] != '\r') {
-                       if (i != j)
-                               buffer->buf[j] = buffer->buf[i];
-                       j++;
-               }
-       strbuf_setlen(buffer, j);
-
-       return 0;
+       return sign_buffer(buffer, buffer, get_signing_key());
 }
 
 static const char tag_template[] =
@@ -270,21 +216,11 @@ static const char tag_template[] =
        "# Write a tag message\n"
        "#\n");
 
-static void set_signingkey(const char *value)
-{
-       if (strlcpy(signingkey, value, sizeof(signingkey)) >= sizeof(signingkey))
-               die(_("signing key value too long (%.10s...)"), value);
-}
-
 static int git_tag_config(const char *var, const char *value, void *cb)
 {
-       if (!strcmp(var, "user.signingkey")) {
-               if (!value)
-                       return config_error_nonbool(var);
-               set_signingkey(value);
-               return 0;
-       }
-
+       int status = git_gpg_config(var, value, cb);
+       if (status)
+               return status;
        return git_default_config(var, value, cb);
 }
 
@@ -463,7 +399,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
 
        if (keyid) {
                sign = 1;
-               set_signingkey(keyid);
+               set_signing_key(keyid);
        }
        if (sign)
                annotate = 1;
index c57e8bd8c870175a1fce6cc75ceeb677a6895b46..2d0b38333eadef0a5c6501e5a3046ebc2afa048e 100644 (file)
@@ -6,7 +6,6 @@
 #include "archive.h"
 #include "pkt-line.h"
 #include "sideband.h"
-#include "run-command.h"
 
 static const char upload_archive_usage[] =
        "git upload-archive <repo>";
@@ -19,17 +18,28 @@ static const char lostchild[] =
 
 #define MAX_ARGS (64)
 
-static void prepare_argv(const char **sent_argv, const char **argv)
+static int run_upload_archive(int argc, const char **argv, const char *prefix)
 {
+       const char *sent_argv[MAX_ARGS];
        const char *arg_cmd = "argument ";
        char *p, buf[4096];
        int sent_argc;
        int len;
 
+       if (argc != 2)
+               usage(upload_archive_usage);
+
+       if (strlen(argv[1]) + 1 > sizeof(buf))
+               die("insanely long repository name");
+
+       strcpy(buf, argv[1]); /* enter-repo smudges its argument */
+
+       if (!enter_repo(buf, 0))
+               die("'%s' does not appear to be a git repository", buf);
+
        /* put received options in sent_argv[] */
-       sent_argc = 2;
-       sent_argv[0] = "archive";
-       sent_argv[1] = "--remote-request";
+       sent_argc = 1;
+       sent_argv[0] = "git-upload-archive";
        for (p = buf;;) {
                /* This will die if not enough free space in buf */
                len = packet_read_line(0, p, (buf + sizeof buf) - p);
@@ -52,6 +62,9 @@ static void prepare_argv(const char **sent_argv, const char **argv)
                *p++ = 0;
        }
        sent_argv[sent_argc] = NULL;
+
+       /* parse all options sent by the client */
+       return write_archive(sent_argc, sent_argv, prefix, 0, NULL, 1);
 }
 
 __attribute__((format (printf, 1, 2)))
@@ -83,25 +96,38 @@ static ssize_t process_input(int child_fd, int band)
 
 int cmd_upload_archive(int argc, const char **argv, const char *prefix)
 {
-       const char *sent_argv[MAX_ARGS];
-       struct child_process cld = { sent_argv };
-       cld.out = cld.err = -1;
-       cld.git_cmd = 1;
-
-       if (argc != 2)
-               usage(upload_archive_usage);
-
-       if (!enter_repo(argv[1], 0))
-               die("'%s' does not appear to be a git repository", argv[1]);
-
-       prepare_argv(sent_argv, argv);
-       if (start_command(&cld)) {
+       pid_t writer;
+       int fd1[2], fd2[2];
+       /*
+        * Set up sideband subprocess.
+        *
+        * We (parent) monitor and read from child, sending its fd#1 and fd#2
+        * multiplexed out to our fd#1.  If the child dies, we tell the other
+        * end over channel #3.
+        */
+       if (pipe(fd1) < 0 || pipe(fd2) < 0) {
+               int err = errno;
+               packet_write(1, "NACK pipe failed on the remote side\n");
+               die("upload-archive: %s", strerror(err));
+       }
+       writer = fork();
+       if (writer < 0) {
                int err = errno;
                packet_write(1, "NACK fork failed on the remote side\n");
                die("upload-archive: %s", strerror(err));
        }
+       if (!writer) {
+               /* child - connect fd#1 and fd#2 to the pipe */
+               dup2(fd1[1], 1);
+               dup2(fd2[1], 2);
+               close(fd1[1]); close(fd2[1]);
+               close(fd1[0]); close(fd2[0]); /* we do not read from pipe */
+
+               exit(run_upload_archive(argc, argv, prefix));
+       }
 
        /* parent - read from child, multiplex and send out to fd#1 */
+       close(fd1[1]); close(fd2[1]); /* we do not write to pipe */
        packet_write(1, "ACK\n");
        packet_flush(1);
 
@@ -109,9 +135,9 @@ int cmd_upload_archive(int argc, const char **argv, const char *prefix)
                struct pollfd pfd[2];
                int status;
 
-               pfd[0].fd = cld.out;
+               pfd[0].fd = fd1[0];
                pfd[0].events = POLLIN;
-               pfd[1].fd = cld.err;
+               pfd[1].fd = fd2[0];
                pfd[1].events = POLLIN;
                if (poll(pfd, 2, -1) < 0) {
                        if (errno != EINTR) {
@@ -130,7 +156,7 @@ int cmd_upload_archive(int argc, const char **argv, const char *prefix)
                        if (process_input(pfd[0].fd, 1))
                                continue;
 
-               if (waitpid(cld.pid, &status, 0) < 0)
+               if (waitpid(writer, &status, 0) < 0)
                        error_clnt("%s", lostchild);
                else if (!WIFEXITED(status) || WEXITSTATUS(status) > 0)
                        error_clnt("%s", deadchild);
index 313476604967bb2962350c82d45ffad04eab09e1..28c21743381db95f6ddb4b185ec34cdbff686866 100644 (file)
@@ -11,6 +11,7 @@
 #include "run-command.h"
 #include <signal.h>
 #include "parse-options.h"
+#include "gpg-interface.h"
 
 static const char * const verify_tag_usage[] = {
                "git verify-tag [-v|--verbose] <tag>...",
@@ -19,42 +20,16 @@ static const char * const verify_tag_usage[] = {
 
 static int run_gpg_verify(const char *buf, unsigned long size, int verbose)
 {
-       struct child_process gpg;
-       const char *args_gpg[] = {"gpg", "--verify", "FILE", "-", NULL};
-       char path[PATH_MAX];
-       size_t len;
-       int fd, ret;
+       int len;
 
-       fd = git_mkstemp(path, PATH_MAX, ".git_vtag_tmpXXXXXX");
-       if (fd < 0)
-               return error("could not create temporary file '%s': %s",
-                                               path, strerror(errno));
-       if (write_in_full(fd, buf, size) < 0)
-               return error("failed writing temporary file '%s': %s",
-                                               path, strerror(errno));
-       close(fd);
-
-       /* find the length without signature */
        len = parse_signature(buf, size);
        if (verbose)
                write_in_full(1, buf, len);
 
-       memset(&gpg, 0, sizeof(gpg));
-       gpg.argv = args_gpg;
-       gpg.in = -1;
-       args_gpg[2] = path;
-       if (start_command(&gpg)) {
-               unlink(path);
-               return error("could not run gpg.");
-       }
-
-       write_in_full(gpg.in, buf, len);
-       close(gpg.in);
-       ret = finish_command(&gpg);
+       if (size == len)
+               return error("no signature found");
 
-       unlink_or_warn(path);
-
-       return ret;
+       return verify_signed_buffer(buf, len, buf + len, size - len, NULL);
 }
 
 static int verify_tag(const char *name, int verbose)
diff --git a/cache.h b/cache.h
index 5badece71b1e473b6a2c0f0e446e5ce030b2ecd5..8c98d056674c9a426215bf93398fe922a1a90679 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -306,7 +306,7 @@ static inline unsigned int canon_mode(unsigned int mode)
 }
 
 #define flexible_size(STRUCT,len) ((offsetof(struct STRUCT,name) + (len) + 8) & ~7)
-#define cache_entry_size(len) flexible_size(cache_entry,len)
+#define cache_entry_size(len) (offsetof(struct cache_entry,name) + (len) + 1)
 #define ondisk_cache_entry_size(len) flexible_size(ondisk_cache_entry,len)
 #define ondisk_cache_entry_extended_size(len) flexible_size(ondisk_cache_entry_extended,len)
 
@@ -316,7 +316,6 @@ struct index_state {
        struct string_list *resolve_undo;
        struct cache_tree *cache_tree;
        struct cache_time timestamp;
-       void *alloc;
        unsigned name_hash_initialized : 1,
                 initialized : 1;
        struct hash_table name_hash;
@@ -875,7 +874,7 @@ extern int get_sha1_mb(const char *str, unsigned char *sha1);
 
 extern int refname_match(const char *abbrev_name, const char *full_name, const char **rules);
 extern const char *ref_rev_parse_rules[];
-extern const char *ref_fetch_rules[];
+#define ref_fetch_rules ref_rev_parse_rules
 
 extern int create_symref(const char *ref, const char *refs_heads_master, const char *logmsg);
 extern int validate_headref(const char *ref);
index 73b7e00292ba2de33fa43b5f028fd807a460af34..b78127403be65f5c26e35e53a59b91860396194a 100644 (file)
--- a/commit.c
+++ b/commit.c
@@ -840,14 +840,160 @@ struct commit_list *reduce_heads(struct commit_list *heads)
        return result;
 }
 
+static void handle_signed_tag(struct commit *parent, struct commit_extra_header ***tail)
+{
+       struct merge_remote_desc *desc;
+       struct commit_extra_header *mergetag;
+       char *buf;
+       unsigned long size, len;
+       enum object_type type;
+
+       desc = merge_remote_util(parent);
+       if (!desc || !desc->obj)
+               return;
+       buf = read_sha1_file(desc->obj->sha1, &type, &size);
+       if (!buf || type != OBJ_TAG)
+               goto free_return;
+       len = parse_signature(buf, size);
+       if (size == len)
+               goto free_return;
+       /*
+        * We could verify this signature and either omit the tag when
+        * it does not validate, but the integrator may not have the
+        * public key of the signer of the tag he is merging, while a
+        * later auditor may have it while auditing, so let's not run
+        * verify-signed-buffer here for now...
+        *
+        * if (verify_signed_buffer(buf, len, buf + len, size - len, ...))
+        *      warn("warning: signed tag unverified.");
+        */
+       mergetag = xcalloc(1, sizeof(*mergetag));
+       mergetag->key = xstrdup("mergetag");
+       mergetag->value = buf;
+       mergetag->len = size;
+
+       **tail = mergetag;
+       *tail = &mergetag->next;
+       return;
+
+free_return:
+       free(buf);
+}
+
+void append_merge_tag_headers(struct commit_list *parents,
+                             struct commit_extra_header ***tail)
+{
+       while (parents) {
+               struct commit *parent = parents->item;
+               handle_signed_tag(parent, tail);
+               parents = parents->next;
+       }
+}
+
+static void add_extra_header(struct strbuf *buffer,
+                            struct commit_extra_header *extra)
+{
+       strbuf_addstr(buffer, extra->key);
+       if (extra->len)
+               strbuf_add_lines(buffer, " ", extra->value, extra->len);
+       else
+               strbuf_addch(buffer, '\n');
+}
+
+struct commit_extra_header *read_commit_extra_headers(struct commit *commit)
+{
+       struct commit_extra_header *extra = NULL;
+       unsigned long size;
+       enum object_type type;
+       char *buffer = read_sha1_file(commit->object.sha1, &type, &size);
+       if (buffer && type == OBJ_COMMIT)
+               extra = read_commit_extra_header_lines(buffer, size);
+       free(buffer);
+       return extra;
+}
+
+static inline int standard_header_field(const char *field, size_t len)
+{
+       return ((len == 4 && !memcmp(field, "tree ", 5)) ||
+               (len == 6 && !memcmp(field, "parent ", 7)) ||
+               (len == 6 && !memcmp(field, "author ", 7)) ||
+               (len == 9 && !memcmp(field, "committer ", 10)) ||
+               (len == 8 && !memcmp(field, "encoding ", 9)));
+}
+
+struct commit_extra_header *read_commit_extra_header_lines(const char *buffer, size_t size)
+{
+       struct commit_extra_header *extra = NULL, **tail = &extra, *it = NULL;
+       const char *line, *next, *eof, *eob;
+       struct strbuf buf = STRBUF_INIT;
+
+       for (line = buffer, eob = line + size;
+            line < eob && *line != '\n';
+            line = next) {
+               next = memchr(line, '\n', eob - line);
+               next = next ? next + 1 : eob;
+               if (*line == ' ') {
+                       /* continuation */
+                       if (it)
+                               strbuf_add(&buf, line + 1, next - (line + 1));
+                       continue;
+               }
+               if (it)
+                       it->value = strbuf_detach(&buf, &it->len);
+               strbuf_reset(&buf);
+               it = NULL;
+
+               eof = strchr(line, ' ');
+               if (next <= eof)
+                       eof = next;
+
+               if (standard_header_field(line, eof - line))
+                       continue;
+
+               it = xcalloc(1, sizeof(*it));
+               it->key = xmemdupz(line, eof-line);
+               *tail = it;
+               tail = &it->next;
+               if (eof + 1 < next)
+                       strbuf_add(&buf, eof + 1, next - (eof + 1));
+       }
+       if (it)
+               it->value = strbuf_detach(&buf, &it->len);
+       return extra;
+}
+
+void free_commit_extra_headers(struct commit_extra_header *extra)
+{
+       while (extra) {
+               struct commit_extra_header *next = extra->next;
+               free(extra->key);
+               free(extra->value);
+               free(extra);
+               extra = next;
+       }
+}
+
+int commit_tree(const char *msg, unsigned char *tree,
+               struct commit_list *parents, unsigned char *ret,
+               const char *author)
+{
+       struct commit_extra_header *extra = NULL, **tail = &extra;
+       int result;
+
+       append_merge_tag_headers(parents, &tail);
+       result = commit_tree_extended(msg, tree, parents, ret, author, extra);
+       free_commit_extra_headers(extra);
+       return result;
+}
+
 static const char commit_utf8_warn[] =
 "Warning: commit message does not conform to UTF-8.\n"
 "You may want to amend it after fixing the message, or set the config\n"
 "variable i18n.commitencoding to the encoding your project uses.\n";
 
-int commit_tree(const char *msg, unsigned char *tree,
-               struct commit_list *parents, unsigned char *ret,
-               const char *author)
+int commit_tree_extended(const char *msg, unsigned char *tree,
+                        struct commit_list *parents, unsigned char *ret,
+                        const char *author, struct commit_extra_header *extra)
 {
        int result;
        int encoding_is_utf8;
@@ -868,8 +1014,10 @@ int commit_tree(const char *msg, unsigned char *tree,
         */
        while (parents) {
                struct commit_list *next = parents->next;
+               struct commit *parent = parents->item;
+
                strbuf_addf(&buffer, "parent %s\n",
-                       sha1_to_hex(parents->item->object.sha1));
+                           sha1_to_hex(parent->object.sha1));
                free(parents);
                parents = next;
        }
@@ -881,6 +1029,11 @@ int commit_tree(const char *msg, unsigned char *tree,
        strbuf_addf(&buffer, "committer %s\n", git_committer_info(IDENT_ERROR_ON_NO_NAME));
        if (!encoding_is_utf8)
                strbuf_addf(&buffer, "encoding %s\n", git_commit_encoding);
+
+       while (extra) {
+               add_extra_header(&buffer, extra);
+               extra = extra->next;
+       }
        strbuf_addch(&buffer, '\n');
 
        /* And add the comment */
@@ -894,3 +1047,22 @@ int commit_tree(const char *msg, unsigned char *tree,
        strbuf_release(&buffer);
        return result;
 }
+
+struct commit *get_merge_parent(const char *name)
+{
+       struct object *obj;
+       struct commit *commit;
+       unsigned char sha1[20];
+       if (get_sha1(name, sha1))
+               return NULL;
+       obj = parse_object(sha1);
+       commit = (struct commit *)peel_to_type(name, 0, obj, OBJ_COMMIT);
+       if (commit && !commit->util) {
+               struct merge_remote_desc *desc;
+               desc = xmalloc(sizeof(*desc));
+               desc->obj = obj;
+               desc->name = strdup(name);
+               commit->util = desc;
+       }
+       return commit;
+}
index 009b113e5bb5d04bdfb116897cc17dc5f5a2fa9c..3745f120994cb6876e1ccc1bfc5e07c6cc3fc5c9 100644 (file)
--- a/commit.h
+++ b/commit.h
@@ -181,8 +181,41 @@ static inline int single_parent(struct commit *commit)
 
 struct commit_list *reduce_heads(struct commit_list *heads);
 
+struct commit_extra_header {
+       struct commit_extra_header *next;
+       char *key;
+       char *value;
+       size_t len;
+};
+
+extern void append_merge_tag_headers(struct commit_list *parents,
+                                    struct commit_extra_header ***tail);
+
 extern int commit_tree(const char *msg, unsigned char *tree,
-               struct commit_list *parents, unsigned char *ret,
-               const char *author);
+                      struct commit_list *parents, unsigned char *ret,
+                      const char *author);
+
+extern int commit_tree_extended(const char *msg, unsigned char *tree,
+                               struct commit_list *parents, unsigned char *ret,
+                               const char *author,
+                               struct commit_extra_header *);
+
+extern struct commit_extra_header *read_commit_extra_headers(struct commit *);
+extern struct commit_extra_header *read_commit_extra_header_lines(const char *buf, size_t len);
+
+extern void free_commit_extra_headers(struct commit_extra_header *extra);
+
+struct merge_remote_desc {
+       struct object *obj; /* the named object, could be a tag */
+       const char *name;
+};
+#define merge_remote_util(commit) ((struct merge_remote_desc *)((commit)->util))
+
+/*
+ * Given "name" from the command line to merge, find the commit object
+ * and return it, while storing merge_remote_desc in its ->util field,
+ * to allow callers to tell if we are told to merge a tag.
+ */
+struct commit *get_merge_parent(const char *name);
 
 #endif /* COMMIT_H */
index efdc703257c9589018e59dc5bc93e9980e0f30b6..a0ac487c0c12ea0e7c81485b5784e28f2115a2ea 100644 (file)
@@ -1712,7 +1712,7 @@ char *getpass(const char *prompt)
        return strbuf_detach(&buf, NULL);
 }
 
-pid_t waitpid(pid_t pid, int *status, unsigned options)
+pid_t waitpid(pid_t pid, int *status, int options)
 {
        HANDLE h = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION,
            FALSE, pid);
index dfb0e87263a37bdee347c0a762aeea42fc57cee9..0ff1e04812ef2491f15b1d40bb8e1c2977b26d98 100644 (file)
@@ -85,6 +85,8 @@ static inline int symlink(const char *oldpath, const char *newpath)
 { errno = ENOSYS; return -1; }
 static inline int fchmod(int fildes, mode_t mode)
 { errno = ENOSYS; return -1; }
+static inline pid_t fork(void)
+{ errno = ENOSYS; return -1; }
 static inline unsigned int alarm(unsigned int seconds)
 { return 0; }
 static inline int fsync(int fd)
@@ -118,7 +120,7 @@ static inline int mingw_mkdir(const char *path, int mode)
 #define mkdir mingw_mkdir
 
 #define WNOHANG 1
-pid_t waitpid(pid_t pid, int *status, unsigned options);
+pid_t waitpid(pid_t pid, int *status, int options);
 
 #define kill mingw_kill
 int mingw_kill(pid_t pid, int sig);
index a33b01c032b1ab948d87b29447ad0787c86f14f1..aa4b56315ae2488ea656d695f0f660e4dbd745ef 100644 (file)
@@ -4,6 +4,7 @@
 #include <direct.h>
 #include <process.h>
 #include <malloc.h>
+#include <io.h>
 
 /* porting function */
 #define inline __inline
diff --git a/compat/strtoimax.c b/compat/strtoimax.c
new file mode 100644 (file)
index 0000000..ac09ed8
--- /dev/null
@@ -0,0 +1,10 @@
+#include "../git-compat-util.h"
+
+intmax_t gitstrtoimax (const char *nptr, char **endptr, int base)
+{
+#if defined(NO_STRTOULL)
+       return strtol(nptr, endptr, base);
+#else
+       return strtoll(nptr, endptr, base);
+#endif
+}
diff --git a/compat/vcbuild/include/arpa/inet.h b/compat/vcbuild/include/arpa/inet.h
deleted file mode 100644 (file)
index 0d8552a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/* Intentionally empty file to support building git with MSVC */
diff --git a/compat/vcbuild/include/grp.h b/compat/vcbuild/include/grp.h
deleted file mode 100644 (file)
index 0d8552a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/* Intentionally empty file to support building git with MSVC */
diff --git a/compat/vcbuild/include/inttypes.h b/compat/vcbuild/include/inttypes.h
deleted file mode 100644 (file)
index 0d8552a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/* Intentionally empty file to support building git with MSVC */
diff --git a/compat/vcbuild/include/netdb.h b/compat/vcbuild/include/netdb.h
deleted file mode 100644 (file)
index 0d8552a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/* Intentionally empty file to support building git with MSVC */
diff --git a/compat/vcbuild/include/netinet/in.h b/compat/vcbuild/include/netinet/in.h
deleted file mode 100644 (file)
index 0d8552a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/* Intentionally empty file to support building git with MSVC */
diff --git a/compat/vcbuild/include/netinet/tcp.h b/compat/vcbuild/include/netinet/tcp.h
deleted file mode 100644 (file)
index 0d8552a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/* Intentionally empty file to support building git with MSVC */
diff --git a/compat/vcbuild/include/pwd.h b/compat/vcbuild/include/pwd.h
deleted file mode 100644 (file)
index 0d8552a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/* Intentionally empty file to support building git with MSVC */
diff --git a/compat/vcbuild/include/sys/ioctl.h b/compat/vcbuild/include/sys/ioctl.h
deleted file mode 100644 (file)
index 0d8552a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/* Intentionally empty file to support building git with MSVC */
diff --git a/compat/vcbuild/include/sys/select.h b/compat/vcbuild/include/sys/select.h
deleted file mode 100644 (file)
index 0d8552a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/* Intentionally empty file to support building git with MSVC */
diff --git a/compat/vcbuild/include/sys/socket.h b/compat/vcbuild/include/sys/socket.h
deleted file mode 100644 (file)
index 0d8552a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/* Intentionally empty file to support building git with MSVC */
diff --git a/compat/vcbuild/include/sys/wait.h b/compat/vcbuild/include/sys/wait.h
deleted file mode 100644 (file)
index 0d8552a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/* Intentionally empty file to support building git with MSVC */
diff --git a/compat/vcbuild/include/termios.h b/compat/vcbuild/include/termios.h
deleted file mode 100644 (file)
index 0d8552a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/* Intentionally empty file to support building git with MSVC */
index edf9914df6a1a789780c98d53b7b779908bb9141..5ea101fb251d27eadac20c665a7f01fb210c20d1 100644 (file)
--- a/config.c
+++ b/config.c
@@ -333,7 +333,7 @@ static int git_parse_file(config_fn_t fn, void *data)
        die("bad config file line %d in %s", cf->linenr, cf->name);
 }
 
-static int parse_unit_factor(const char *end, unsigned long *val)
+static int parse_unit_factor(const char *end, uintmax_t *val)
 {
        if (!*end)
                return 1;
@@ -356,11 +356,23 @@ static int git_parse_long(const char *value, long *ret)
 {
        if (value && *value) {
                char *end;
-               long val = strtol(value, &end, 0);
-               unsigned long factor = 1;
+               intmax_t val;
+               uintmax_t uval;
+               uintmax_t factor = 1;
+
+               errno = 0;
+               val = strtoimax(value, &end, 0);
+               if (errno == ERANGE)
+                       return 0;
                if (!parse_unit_factor(end, &factor))
                        return 0;
-               *ret = val * factor;
+               uval = abs(val);
+               uval *= factor;
+               if ((uval > maximum_signed_value_of_type(long)) ||
+                   (abs(val) > uval))
+                       return 0;
+               val *= factor;
+               *ret = val;
                return 1;
        }
        return 0;
@@ -370,9 +382,19 @@ int git_parse_ulong(const char *value, unsigned long *ret)
 {
        if (value && *value) {
                char *end;
-               unsigned long val = strtoul(value, &end, 0);
+               uintmax_t val;
+               uintmax_t oldval;
+
+               errno = 0;
+               val = strtoumax(value, &end, 0);
+               if (errno == ERANGE)
+                       return 0;
+               oldval = val;
                if (!parse_unit_factor(end, &val))
                        return 0;
+               if ((val > maximum_unsigned_value_of_type(long)) ||
+                   (oldval > val))
+                       return 0;
                *ret = val;
                return 1;
        }
@@ -553,7 +575,7 @@ static int git_default_core_config(const char *var, const char *value)
 
        if (!strcmp(var, "core.packedgitwindowsize")) {
                int pgsz_x2 = getpagesize() * 2;
-               packed_git_window_size = git_config_int(var, value);
+               packed_git_window_size = git_config_ulong(var, value);
 
                /* This value must be multiple of (pagesize * 2) */
                packed_git_window_size /= pgsz_x2;
@@ -564,18 +586,17 @@ static int git_default_core_config(const char *var, const char *value)
        }
 
        if (!strcmp(var, "core.bigfilethreshold")) {
-               long n = git_config_int(var, value);
-               big_file_threshold = 0 < n ? n : 0;
+               big_file_threshold = git_config_ulong(var, value);
                return 0;
        }
 
        if (!strcmp(var, "core.packedgitlimit")) {
-               packed_git_limit = git_config_int(var, value);
+               packed_git_limit = git_config_ulong(var, value);
                return 0;
        }
 
        if (!strcmp(var, "core.deltabasecachelimit")) {
-               delta_base_cache_limit = git_config_int(var, value);
+               delta_base_cache_limit = git_config_ulong(var, value);
                return 0;
        }
 
@@ -865,12 +886,12 @@ int git_config_early(config_fn_t fn, void *data, const char *repo_config)
 
        home = getenv("HOME");
        if (home) {
-               char *user_config = xstrdup(mkpath("%s/.gitconfig", home));
+               char buf[PATH_MAX];
+               char *user_config = mksnpath(buf, sizeof(buf), "%s/.gitconfig", home);
                if (!access(user_config, R_OK)) {
                        ret += git_config_from_file(fn, user_config, data);
                        found += 1;
                }
-               free(user_config);
        }
 
        if (repo_config && !access(repo_config, R_OK)) {
index b975d67fca530a35c590cb677a6f11eabb7900bb..7fd8bf031e1eb10f6dda2342f32c86454ef7efb3 100755 (executable)
@@ -847,6 +847,38 @@ class P4Submit(Command, P4UserMap):
 
         return template
 
+    def edit_template(self, template_file):
+        """Invoke the editor to let the user change the submission
+           message.  Return true if okay to continue with the submit."""
+
+        # if configured to skip the editing part, just submit
+        if gitConfig("git-p4.skipSubmitEdit") == "true":
+            return True
+
+        # look at the modification time, to check later if the user saved
+        # the file
+        mtime = os.stat(template_file).st_mtime
+
+        # invoke the editor
+        if os.environ.has_key("P4EDITOR"):
+            editor = os.environ.get("P4EDITOR")
+        else:
+            editor = read_pipe("git var GIT_EDITOR").strip()
+        system(editor + " " + template_file)
+
+        # If the file was not saved, prompt to see if this patch should
+        # be skipped.  But skip this verification step if configured so.
+        if gitConfig("git-p4.skipSubmitEditCheck") == "true":
+            return True
+
+        if os.stat(template_file).st_mtime <= mtime:
+            while True:
+                response = raw_input("Submit template unchanged. Submit anyway? [y]es, [n]o (skip this patch) ")
+                if response == 'y':
+                    return True
+                if response == 'n':
+                    return False
+
     def applyCommit(self, id):
         print "Applying %s" % (read_pipe("git log --max-count=1 --pretty=oneline %s" % id))
 
@@ -1001,7 +1033,7 @@ class P4Submit(Command, P4UserMap):
 
             separatorLine = "######## everything below this line is just the diff #######\n"
 
-            [handle, fileName] = tempfile.mkstemp()
+            (handle, fileName) = tempfile.mkstemp()
             tmpFile = os.fdopen(handle, "w+")
             if self.isWindows:
                 submitTemplate = submitTemplate.replace("\n", "\r\n")
@@ -1009,25 +1041,9 @@ class P4Submit(Command, P4UserMap):
                 newdiff = newdiff.replace("\n", "\r\n")
             tmpFile.write(submitTemplate + separatorLine + diff + newdiff)
             tmpFile.close()
-            mtime = os.stat(fileName).st_mtime
-            if os.environ.has_key("P4EDITOR"):
-                editor = os.environ.get("P4EDITOR")
-            else:
-                editor = read_pipe("git var GIT_EDITOR").strip()
-            system(editor + " " + fileName)
 
-            if gitConfig("git-p4.skipSubmitEditCheck") == "true":
-                checkModTime = False
-            else:
-                checkModTime = True
-
-            response = "y"
-            if checkModTime and (os.stat(fileName).st_mtime <= mtime):
-                response = "x"
-                while response != "y" and response != "n":
-                    response = raw_input("Submit template unchanged. Submit anyway? [y]es, [n]o (skip this patch) ")
-
-            if response == "y":
+            if self.edit_template(fileName):
+                # read the edited message and submit
                 tmpFile = open(fileName, "rb")
                 message = tmpFile.read()
                 tmpFile.close()
@@ -1039,11 +1055,12 @@ class P4Submit(Command, P4UserMap):
                 if self.preserveUser:
                     if p4User:
                         # Get last changelist number. Cannot easily get it from
-                        # the submit command output as the output is unmarshalled.
+                        # the submit command output as the output is
+                        # unmarshalled.
                         changelist = self.lastP4Changelist()
                         self.modifyChangelistUser(changelist, p4User)
-
             else:
+                # skip this patch
                 for f in editedFiles:
                     p4_revert(f)
                 for f in filesToAdd:
index 52003ae9045626077009811cd8e10c1135d69cd0..5044a121e01668d941fdc09124b9db354213c460 100644 (file)
@@ -202,11 +202,24 @@ able to find the relevant client.  This client spec will be used to
 both filter the files cloned by git and set the directory layout as
 specified in the client (this implies --keep-path style semantics).
 
-git-p4.skipSubmitModTimeCheck
+git-p4.skipSubmitEdit
 
-  git config [--global] git-p4.skipSubmitModTimeCheck false
+  git config [--global] git-p4.skipSubmitEdit false
 
-If true, submit will not check if the p4 change template has been modified.
+Normally, git-p4 invokes an editor after each commit is applied so
+that you can make changes to the submit message.  Setting this
+variable to true will skip the editing step, submitting the change as is.
+
+git-p4.skipSubmitEditCheck
+
+  git config [--global] git-p4.skipSubmitEditCheck false
+
+After the editor is invoked, git-p4 normally makes sure you saved the
+change description, as an indication that you did indeed read it over
+and edit it.  You can quit without saving to abort the submit (or skip
+this change and continue).  Setting this variable to true will cause
+git-p4 not to check if you saved the change description.  This variable
+only matters if git-p4.skipSubmitEdit has not been set to true.
 
 git-p4.preserveUser
 
index 3bb5a4dd57c669bc59be0e2317ef33b64b024992..86e9c29ec05139844ff46868e2b52dfbc274cc39 100644 (file)
--- a/convert.c
+++ b/convert.c
@@ -641,7 +641,7 @@ static int ident_to_worktree(const char *path, const char *src, size_t len,
        return 1;
 }
 
-static int git_path_check_crlf(const char *path, struct git_attr_check *check)
+static enum crlf_action git_path_check_crlf(const char *path, struct git_attr_check *check)
 {
        const char *value = check->value;
 
@@ -658,7 +658,7 @@ static int git_path_check_crlf(const char *path, struct git_attr_check *check)
        return CRLF_GUESS;
 }
 
-static int git_path_check_eol(const char *path, struct git_attr_check *check)
+static enum eol git_path_check_eol(const char *path, struct git_attr_check *check)
 {
        const char *value = check->value;
 
@@ -811,7 +811,7 @@ int renormalize_buffer(const char *path, const char *src, size_t len, struct str
                src = dst->buf;
                len = dst->len;
        }
-       return ret | convert_to_git(path, src, len, dst, 0);
+       return ret | convert_to_git(path, src, len, dst, SAFE_CRLF_FALSE);
 }
 
 /*****************************************************************
diff --git a/dir.c b/dir.c
index 6c0d7825799f6c35a2c1f1830767ab6203e2da92..0a78d00b545ac4f302ea89b6393773669907599e 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -968,34 +968,34 @@ static int read_directory_recursive(struct dir_struct *dir,
 {
        DIR *fdir = opendir(*base ? base : ".");
        int contents = 0;
+       struct dirent *de;
+       char path[PATH_MAX + 1];
 
-       if (fdir) {
-               struct dirent *de;
-               char path[PATH_MAX + 1];
-               memcpy(path, base, baselen);
-
-               while ((de = readdir(fdir)) != NULL) {
-                       int len;
-                       switch (treat_path(dir, de, path, sizeof(path),
-                                          baselen, simplify, &len)) {
-                       case path_recurse:
-                               contents += read_directory_recursive
-                                       (dir, path, len, 0, simplify);
-                               continue;
-                       case path_ignored:
-                               continue;
-                       case path_handled:
-                               break;
-                       }
-                       contents++;
-                       if (check_only)
-                               goto exit_early;
-                       else
-                               dir_add_name(dir, path, len);
+       if (!fdir)
+               return 0;
+
+       memcpy(path, base, baselen);
+
+       while ((de = readdir(fdir)) != NULL) {
+               int len;
+               switch (treat_path(dir, de, path, sizeof(path),
+                                  baselen, simplify, &len)) {
+               case path_recurse:
+                       contents += read_directory_recursive(dir, path, len, 0, simplify);
+                       continue;
+               case path_ignored:
+                       continue;
+               case path_handled:
+                       break;
                }
-exit_early:
-               closedir(fdir);
+               contents++;
+               if (check_only)
+                       goto exit_early;
+               else
+                       dir_add_name(dir, path, len);
        }
+exit_early:
+       closedir(fdir);
 
        return contents;
 }
index 0bee6a7a88299f8c89eedeee25cece1d3cdafef0..2c41d7d6cb66832197d69d49065a3d5b3bb2e5da 100644 (file)
@@ -9,6 +9,7 @@
  */
 #include "cache.h"
 #include "refs.h"
+#include "fmt-merge-msg.h"
 
 char git_default_email[MAX_GITNAME];
 char git_default_name[MAX_GITNAME];
@@ -59,6 +60,7 @@ enum object_creation_mode object_creation_mode = OBJECT_CREATION_MODE;
 char *notes_ref_name;
 int grafts_replace_parents = 1;
 int core_apply_sparse_checkout;
+int merge_log_config = -1;
 struct startup_info *startup_info;
 
 /* Parallel index stat data preload? */
diff --git a/fmt-merge-msg.h b/fmt-merge-msg.h
new file mode 100644 (file)
index 0000000..b28d3a6
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef FMT_MERGE_MSG_H
+#define FMT_MERGE_MSG_H
+
+extern int merge_log_config;
+extern int fmt_merge_msg_config(const char *key, const char *value, void *cb);
+
+#endif /* FMT_MERGE_MSG_H */
index 9042432e23d7e43edafce28b6822a041028b57b7..1c13b1399185506dd11750fe7e8c1b989a0f3d0c 100755 (executable)
--- a/git-am.sh
+++ b/git-am.sh
@@ -530,7 +530,6 @@ else
        echo "$sign" >"$dotest/sign"
        echo "$utf8" >"$dotest/utf8"
        echo "$keep" >"$dotest/keep"
-       echo "$keepcr" >"$dotest/keepcr"
        echo "$scissors" >"$dotest/scissors"
        echo "$no_inbody_headers" >"$dotest/no_inbody_headers"
        echo "$GIT_QUIET" >"$dotest/quiet"
@@ -576,12 +575,6 @@ if test "$(cat "$dotest/keep")" = t
 then
        keep=-k
 fi
-case "$(cat "$dotest/keepcr")" in
-t)
-       keepcr=--keep-cr ;;
-f)
-       keepcr=--no-keep-cr ;;
-esac
 case "$(cat "$dotest/scissors")" in
 t)
        scissors=--scissors ;;
index 5ef8ff76f6fd262c3109d25d706ebd3db35c73fa..77062ed2a66e1efda60ead8ce99abedc8d04ce71 100644 (file)
 #else
 #include <poll.h>
 #endif
-#ifndef __MINGW32__
+#if defined(__MINGW32__)
+/* pull in Windows compatibility stuff */
+#include "compat/mingw.h"
+#elif defined(_MSC_VER)
+#include "compat/msvc.h"
+#else
 #include <sys/wait.h>
 #include <sys/resource.h>
 #include <sys/socket.h>
 #include <grp.h>
 #define _ALL_SOURCE 1
 #endif
-#else  /* __MINGW32__ */
-/* pull in Windows compatibility stuff */
-#include "compat/mingw.h"
-#endif /* __MINGW32__ */
-#ifdef _MSC_VER
-#include "compat/msvc.h"
 #endif
 
 #ifndef NO_LIBGEN_H
@@ -219,7 +218,7 @@ extern char *gitbasename(char *);
 #define find_last_dir_sep(path) strrchr(path, '/')
 #endif
 
-#if __HP_cc >= 61000
+#if defined(__HP_cc) && (__HP_cc >= 61000)
 #define NORETURN __attribute__((noreturn))
 #define NORETURN_PTR
 #elif defined(__GNUC__) && !defined(NO_NORETURN)
@@ -351,6 +350,8 @@ extern size_t gitstrlcpy(char *, const char *, size_t);
 #ifdef NO_STRTOUMAX
 #define strtoumax gitstrtoumax
 extern uintmax_t gitstrtoumax(const char *, char **, int);
+#define strtoimax gitstrtoimax
+extern intmax_t gitstrtoimax(const char *, char **, int);
 #endif
 
 #ifdef NO_STRTOK_R
index 9868a0bfb478707b361f664a252870b3d1939138..d8b64d7a67a19f1821a26c3ec82c0953db717be6 100755 (executable)
@@ -44,6 +44,10 @@ merge_args=
 curr_branch=$(git symbolic-ref -q HEAD)
 curr_branch_short="${curr_branch#refs/heads/}"
 rebase=$(git config --bool branch.$curr_branch_short.rebase)
+if test -z "$rebase"
+then
+       rebase=$(git config --bool pull.rebase)
+fi
 dry_run=
 while :
 do
index fc080cc5e45d02e618e7224c052de1be676f4360..c6a5b7a6b38adaafdebb4b0991cc5ee8c14c3796 100755 (executable)
@@ -35,44 +35,77 @@ do
        shift
 done
 
-base=$1
-url=$2
-head=${3-HEAD}
+base=$1 url=$2 head=${3-HEAD} status=0 branch_name=
 
-[ "$base" ] || usage
-[ "$url" ] || usage
+headref=$(git symbolic-ref -q "$head")
+if git show-ref -q --verify "$headref"
+then
+       branch_name=${headref#refs/heads/}
+       if test "z$branch_name" = "z$headref" ||
+               ! git config "branch.$branch_name.description" >/dev/null
+       then
+               branch_name=
+       fi
+fi
+
+tag_name=$(git describe --exact "$head^0" 2>/dev/null)
 
-baserev=`git rev-parse --verify "$base"^0` &&
-headrev=`git rev-parse --verify "$head"^0` || exit
+test -n "$base" && test -n "$url" || usage
+baserev=$(git rev-parse --verify "$base"^0) &&
+headrev=$(git rev-parse --verify "$head"^0) || exit
 
-merge_base=`git merge-base $baserev $headrev` ||
+merge_base=$(git merge-base $baserev $headrev) ||
 die "fatal: No commits in common between $base and $head"
 
-branch=$(git ls-remote "$url" \
-       | sed -n -e "/^$headrev refs.heads./{
-               s/^.*   refs.heads.//
-               p
-               q
-       }")
+find_matching_branch="/^$headrev       "'refs\/heads\//{
+       s/^.*   refs\/heads\///
+       p
+       q
+}'
+branch=$(git ls-remote "$url" | sed -n -e "$find_matching_branch")
 url=$(git ls-remote --get-url "$url")
-if [ -z "$branch" ]; then
-       echo "warn: No branch of $url is at:" >&2
-       git log --max-count=1 --pretty='tformat:warn:   %h: %s' $headrev >&2
-       echo "warn: Are you sure you pushed $head there?" >&2
-       echo >&2
-       echo >&2
-       branch=..BRANCH.NOT.VERIFIED..
-       status=1
-fi
 
 git show -s --format='The following changes since commit %H:
 
   %s (%ci)
 
-are available in the git repository at:' $baserev &&
-echo "  $url $branch" &&
-echo &&
+are available in the git repository at:
+' $baserev &&
+echo "  $url${branch+ $branch}" &&
+git show -s --format='
+for you to fetch changes up to %H:
+
+  %s (%ci)
+
+----------------------------------------------------------------' $headrev &&
+
+if test -n "$branch_name"
+then
+       echo "(from the branch description for $branch local branch)"
+       echo
+       git config "branch.$branch_name.description"
+fi &&
+
+if test -n "$tag_name"
+then
+       git cat-file tag "$tag_name" |
+       sed -n -e '1,/^$/d' -e '/^-----BEGIN PGP /q' -e p
+       echo
+fi &&
+
+if test -n "$branch_name" || test -n "$tag_name"
+then
+       echo "----------------------------------------------------------------"
+fi &&
 
 git shortlog ^$baserev $headrev &&
-git diff -M --stat --summary $patch $merge_base..$headrev || exit
+git diff -M --stat --summary $patch $merge_base..$headrev || status=1
+
+if test -z "$branch"
+then
+       echo "warn: No branch of $url is at:" >&2
+       git show -s --format='warn:   %h: %s' $headrev >&2
+       echo "warn: Are you sure you pushed '$head' there?" >&2
+       status=1
+fi
 exit $status
index e30df22d89d97642f0b99c3a35ee0b2c5c062bb3..eeb83d375931df81bd87ca285c8d0741c14f33a2 100755 (executable)
@@ -5389,7 +5389,7 @@ sub apply_diff {
                                       $self->{mergeinfo});
        }
        $self->rmdirs if $_rmdir;
-       if (@$mods == 0) {
+       if (@$mods == 0 && !defined($self->{mergeinfo})) {
                $self->abort_edit;
        } else {
                $self->close_edit;
diff --git a/gpg-interface.c b/gpg-interface.c
new file mode 100644 (file)
index 0000000..ff232c8
--- /dev/null
@@ -0,0 +1,138 @@
+#include "cache.h"
+#include "run-command.h"
+#include "strbuf.h"
+#include "gpg-interface.h"
+#include "sigchain.h"
+
+static char *configured_signing_key;
+
+void set_signing_key(const char *key)
+{
+       free(configured_signing_key);
+       configured_signing_key = xstrdup(key);
+}
+
+int git_gpg_config(const char *var, const char *value, void *cb)
+{
+       if (!strcmp(var, "user.signingkey")) {
+               if (!value)
+                       return config_error_nonbool(var);
+               set_signing_key(value);
+       }
+       return 0;
+}
+
+const char *get_signing_key(void)
+{
+       if (configured_signing_key)
+               return configured_signing_key;
+       return git_committer_info(IDENT_ERROR_ON_NO_NAME|IDENT_NO_DATE);
+}
+
+/*
+ * Create a detached signature for the contents of "buffer" and append
+ * it after "signature"; "buffer" and "signature" can be the same
+ * strbuf instance, which would cause the detached signature appended
+ * at the end.
+ */
+int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *signing_key)
+{
+       struct child_process gpg;
+       const char *args[4];
+       ssize_t len;
+       size_t i, j, bottom;
+
+       memset(&gpg, 0, sizeof(gpg));
+       gpg.argv = args;
+       gpg.in = -1;
+       gpg.out = -1;
+       args[0] = "gpg";
+       args[1] = "-bsau";
+       args[2] = signing_key;
+       args[3] = NULL;
+
+       if (start_command(&gpg))
+               return error(_("could not run gpg."));
+
+       /*
+        * When the username signingkey is bad, program could be terminated
+        * because gpg exits without reading and then write gets SIGPIPE.
+        */
+       sigchain_push(SIGPIPE, SIG_IGN);
+
+       if (write_in_full(gpg.in, buffer->buf, buffer->len) != buffer->len) {
+               close(gpg.in);
+               close(gpg.out);
+               finish_command(&gpg);
+               return error(_("gpg did not accept the data"));
+       }
+       close(gpg.in);
+
+       bottom = signature->len;
+       len = strbuf_read(signature, gpg.out, 1024);
+       close(gpg.out);
+
+       sigchain_pop(SIGPIPE);
+
+       if (finish_command(&gpg) || !len || len < 0)
+               return error(_("gpg failed to sign the data"));
+
+       /* Strip CR from the line endings, in case we are on Windows. */
+       for (i = j = bottom; i < signature->len; i++)
+               if (signature->buf[i] != '\r') {
+                       if (i != j)
+                               signature->buf[j] = signature->buf[i];
+                       j++;
+               }
+       strbuf_setlen(signature, j);
+
+       return 0;
+}
+
+/*
+ * Run "gpg" to see if the payload matches the detached signature.
+ * gpg_output_to tells where the output from "gpg" should go:
+ *   < 0: /dev/null
+ *   = 0: standard error of the calling process
+ *   > 0: the specified file descriptor
+ */
+int verify_signed_buffer(const char *payload, size_t payload_size,
+                        const char *signature, size_t signature_size,
+                        struct strbuf *gpg_output)
+{
+       struct child_process gpg;
+       const char *args_gpg[] = {"gpg", "--verify", "FILE", "-", NULL};
+       char path[PATH_MAX];
+       int fd, ret;
+
+       fd = git_mkstemp(path, PATH_MAX, ".git_vtag_tmpXXXXXX");
+       if (fd < 0)
+               return error("could not create temporary file '%s': %s",
+                            path, strerror(errno));
+       if (write_in_full(fd, signature, signature_size) < 0)
+               return error("failed writing detached signature to '%s': %s",
+                            path, strerror(errno));
+       close(fd);
+
+       memset(&gpg, 0, sizeof(gpg));
+       gpg.argv = args_gpg;
+       gpg.in = -1;
+       if (gpg_output)
+               gpg.err = -1;
+       args_gpg[2] = path;
+       if (start_command(&gpg)) {
+               unlink(path);
+               return error("could not run gpg.");
+       }
+
+       write_in_full(gpg.in, payload, payload_size);
+       close(gpg.in);
+
+       if (gpg_output)
+               strbuf_read(gpg_output, gpg.err, 0);
+       ret = finish_command(&gpg);
+
+       unlink_or_warn(path);
+
+       return ret;
+}
diff --git a/gpg-interface.h b/gpg-interface.h
new file mode 100644 (file)
index 0000000..b9c3608
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef GPG_INTERFACE_H
+#define GPG_INTERFACE_H
+
+extern int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *signing_key);
+extern int verify_signed_buffer(const char *payload, size_t payload_size, const char *signature, size_t signature_size, struct strbuf *gpg_output);
+extern int git_gpg_config(const char *, const char *, void *);
+extern void set_signing_key(const char *);
+extern const char *get_signing_key(void);
+
+#endif
diff --git a/http.c b/http.c
index 008ad72ae599b1b937e2956e2621d40c325ff632..44fcc4d178fcedaa87f1917608dd32a65c24c98a 100644 (file)
--- a/http.c
+++ b/http.c
@@ -4,7 +4,6 @@
 #include "run-command.h"
 #include "url.h"
 
-int data_received;
 int active_requests;
 int http_is_verbose;
 size_t http_post_buffer = 16 * LARGE_PACKET_MAX;
@@ -99,13 +98,11 @@ size_t fwrite_buffer(char *ptr, size_t eltsize, size_t nmemb, void *buffer_)
        struct strbuf *buffer = buffer_;
 
        strbuf_add(buffer, ptr, size);
-       data_received++;
        return size;
 }
 
 size_t fwrite_null(char *ptr, size_t eltsize, size_t nmemb, void *strbuf)
 {
-       data_received++;
        return eltsize * nmemb;
 }
 
@@ -536,7 +533,6 @@ struct active_request_slot *get_active_slot(void)
 
        active_requests++;
        slot->in_use = 1;
-       slot->local = NULL;
        slot->results = NULL;
        slot->finished = NULL;
        slot->callback_data = NULL;
@@ -640,8 +636,6 @@ void step_active_slots(void)
 void run_active_slot(struct active_request_slot *slot)
 {
 #ifdef USE_CURL_MULTI
-       long last_pos = 0;
-       long current_pos;
        fd_set readfds;
        fd_set writefds;
        fd_set excfds;
@@ -651,25 +645,33 @@ void run_active_slot(struct active_request_slot *slot)
 
        slot->finished = &finished;
        while (!finished) {
-               data_received = 0;
                step_active_slots();
 
-               if (!data_received && slot->local != NULL) {
-                       current_pos = ftell(slot->local);
-                       if (current_pos > last_pos)
-                               data_received++;
-                       last_pos = current_pos;
-               }
+               if (slot->in_use) {
+#if LIBCURL_VERSION_NUM >= 0x070f04
+                       long curl_timeout;
+                       curl_multi_timeout(curlm, &curl_timeout);
+                       if (curl_timeout == 0) {
+                               continue;
+                       } else if (curl_timeout == -1) {
+                               select_timeout.tv_sec  = 0;
+                               select_timeout.tv_usec = 50000;
+                       } else {
+                               select_timeout.tv_sec  =  curl_timeout / 1000;
+                               select_timeout.tv_usec = (curl_timeout % 1000) * 1000;
+                       }
+#else
+                       select_timeout.tv_sec  = 0;
+                       select_timeout.tv_usec = 50000;
+#endif
 
-               if (slot->in_use && !data_received) {
-                       max_fd = 0;
+                       max_fd = -1;
                        FD_ZERO(&readfds);
                        FD_ZERO(&writefds);
                        FD_ZERO(&excfds);
-                       select_timeout.tv_sec = 0;
-                       select_timeout.tv_usec = 50000;
-                       select(max_fd, &readfds, &writefds,
-                              &excfds, &select_timeout);
+                       curl_multi_fdset(curlm, &readfds, &writefds, &excfds, &max_fd);
+
+                       select(max_fd+1, &readfds, &writefds, &excfds, &select_timeout);
                }
        }
 #else
@@ -747,14 +749,6 @@ static inline int needs_quote(int ch)
        return 1;
 }
 
-static inline int hex(int v)
-{
-       if (v < 10)
-               return '0' + v;
-       else
-               return 'A' + v - 10;
-}
-
 static char *quote_ref_url(const char *base, const char *ref)
 {
        struct strbuf buf = STRBUF_INIT;
@@ -822,7 +816,6 @@ static int http_request(const char *url, void *result, int target, int options)
                                headers = curl_slist_append(headers, buf.buf);
                                strbuf_reset(&buf);
                        }
-                       slot->local = result;
                } else
                        curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION,
                                         fwrite_buffer);
@@ -870,7 +863,6 @@ static int http_request(const char *url, void *result, int target, int options)
                ret = HTTP_START_FAILED;
        }
 
-       slot->local = NULL;
        curl_slist_free_all(headers);
        strbuf_release(&buf);
 
@@ -1065,7 +1057,6 @@ void release_http_pack_request(struct http_pack_request *preq)
        if (preq->packfile != NULL) {
                fclose(preq->packfile);
                preq->packfile = NULL;
-               preq->slot->local = NULL;
        }
        if (preq->range_header != NULL) {
                curl_slist_free_all(preq->range_header);
@@ -1087,7 +1078,6 @@ int finish_http_pack_request(struct http_pack_request *preq)
 
        fclose(preq->packfile);
        preq->packfile = NULL;
-       preq->slot->local = NULL;
 
        lst = preq->lst;
        while (*lst != p)
@@ -1156,7 +1146,6 @@ struct http_pack_request *new_http_pack_request(
        }
 
        preq->slot = get_active_slot();
-       preq->slot->local = preq->packfile;
        curl_easy_setopt(preq->slot->curl, CURLOPT_FILE, preq->packfile);
        curl_easy_setopt(preq->slot->curl, CURLOPT_WRITEFUNCTION, fwrite);
        curl_easy_setopt(preq->slot->curl, CURLOPT_URL, preq->url);
@@ -1213,7 +1202,6 @@ static size_t fwrite_sha1_file(char *ptr, size_t eltsize, size_t nmemb,
                git_SHA1_Update(&freq->c, expn,
                                sizeof(expn) - freq->stream.avail_out);
        } while (freq->stream.avail_in && freq->zret == Z_OK);
-       data_received++;
        return size;
 }
 
diff --git a/http.h b/http.h
index 3c332a98e9358a296b937453351018ac1042120e..ee1606942a9716b45da937873949220ab7f8092b 100644 (file)
--- a/http.h
+++ b/http.h
@@ -49,7 +49,6 @@ struct slot_results {
 
 struct active_request_slot {
        CURL *curl;
-       FILE *local;
        int in_use;
        CURLcode curl_result;
        long http_code;
@@ -89,7 +88,6 @@ extern void step_active_slots(void);
 extern void http_init(struct remote *remote, const char *url);
 extern void http_cleanup(void);
 
-extern int data_received;
 extern int active_requests;
 extern int http_is_verbose;
 extern size_t http_post_buffer;
index 39d80c01753527e45716ec762beeb891dfc7d28d..3dd4a960190a1b0016b26dec9187692111b73e3f 100644 (file)
@@ -71,7 +71,8 @@ static void process_tree(struct rev_info *revs,
        struct tree_desc desc;
        struct name_entry entry;
        struct name_path me;
-       int match = revs->diffopt.pathspec.nr == 0 ? 2 : 0;
+       enum interesting match = revs->diffopt.pathspec.nr == 0 ?
+               all_entries_interesting: entry_not_interesting;
        int baselen = base->len;
 
        if (!revs->tree_objects)
@@ -97,12 +98,12 @@ static void process_tree(struct rev_info *revs,
        init_tree_desc(&desc, tree->buffer, tree->size);
 
        while (tree_entry(&desc, &entry)) {
-               if (match != 2) {
+               if (match != all_entries_interesting) {
                        match = tree_entry_interesting(&entry, base, 0,
                                                       &revs->diffopt.pathspec);
-                       if (match < 0)
+                       if (match == all_entries_not_interesting)
                                break;
-                       if (match == 0)
+                       if (match == entry_not_interesting)
                                continue;
                }
 
index 02fcfde0b0b786af5229559586cf8ff5758429bc..8c3196c7d76ff90e90a9fb4ff569aff6a429861a 100644 (file)
--- a/mailmap.c
+++ b/mailmap.c
@@ -70,8 +70,7 @@ static void add_mapping(struct string_list *map,
        } else {
                /* create mailmap entry */
                struct string_list_item *item = string_list_insert_at_index(map, index, old_email);
-               item->util = xmalloc(sizeof(struct mailmap_entry));
-               memset(item->util, 0, sizeof(struct mailmap_entry));
+               item->util = xcalloc(1, sizeof(struct mailmap_entry));
                ((struct mailmap_entry *)item->util)->namemap.strdup_strings = 1;
        }
        me = (struct mailmap_entry *)map->items[index].util;
@@ -88,7 +87,7 @@ static void add_mapping(struct string_list *map,
                        me->email = xstrdup(new_email);
                }
        } else {
-               struct mailmap_info *mi = xmalloc(sizeof(struct mailmap_info));
+               struct mailmap_info *mi = xcalloc(1, sizeof(struct mailmap_info));
                debug_mm("mailmap: adding (complex) entry for %s at index %d\n", old_email, index);
                if (new_name)
                        mi->name = xstrdup(new_name);
index cc664c39b66b0bb499dec13a22880a6096423fa6..5a2db296b83d1ab23bfce23913c036a71dc81398 100644 (file)
@@ -38,16 +38,15 @@ static struct tree *shift_tree_object(struct tree *one, struct tree *two,
        return lookup_tree(shifted);
 }
 
-/*
- * A virtual commit has (const char *)commit->util set to the name.
- */
-
 static struct commit *make_virtual_commit(struct tree *tree, const char *comment)
 {
        struct commit *commit = xcalloc(1, sizeof(struct commit));
+       struct merge_remote_desc *desc = xmalloc(sizeof(*desc));
+
+       desc->name = comment;
+       desc->obj = (struct object *)commit;
        commit->tree = tree;
-       commit->util = (void*)comment;
-       /* avoid warnings */
+       commit->util = desc;
        commit->object.parsed = 1;
        return commit;
 }
@@ -184,7 +183,7 @@ static void output_commit_title(struct merge_options *o, struct commit *commit)
        for (i = o->call_depth; i--;)
                fputs("  ", stdout);
        if (commit->util)
-               printf("virtual %s\n", (char *)commit->util);
+               printf("virtual %s\n", merge_remote_util(commit)->name);
        else {
                printf("%s ", find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV));
                if (parse_commit(commit) != 0)
index e33c2c9f165ea3ae883860066aca8f91018d2a75..2de27af751476a62dc9b0afe48eb360f83a0702b 100644 (file)
@@ -21,14 +21,6 @@ void init_notes_merge_options(struct notes_merge_options *o)
        o->verbosity = NOTES_MERGE_VERBOSITY_DEFAULT;
 }
 
-#define OUTPUT(o, v, ...) \
-       do { \
-               if ((o)->verbosity >= (v)) { \
-                       printf(__VA_ARGS__); \
-                       puts(""); \
-               } \
-       } while (0)
-
 static int path_to_sha1(const char *path, unsigned char *sha1)
 {
        char hex_sha1[40];
@@ -392,21 +384,26 @@ static int merge_one_change_manual(struct notes_merge_options *o,
 
        strbuf_addf(&(o->commit_msg), "\t%s\n", sha1_to_hex(p->obj));
 
-       OUTPUT(o, 2, "Auto-merging notes for %s", sha1_to_hex(p->obj));
+       if (o->verbosity >= 2)
+               printf("Auto-merging notes for %s\n", sha1_to_hex(p->obj));
        check_notes_merge_worktree(o);
        if (is_null_sha1(p->local)) {
                /* D/F conflict, checkout p->remote */
                assert(!is_null_sha1(p->remote));
-               OUTPUT(o, 1, "CONFLICT (delete/modify): Notes for object %s "
-                      "deleted in %s and modified in %s. Version from %s "
-                      "left in tree.", sha1_to_hex(p->obj), lref, rref, rref);
+               if (o->verbosity >= 1)
+                       printf("CONFLICT (delete/modify): Notes for object %s "
+                               "deleted in %s and modified in %s. Version from %s "
+                               "left in tree.\n",
+                               sha1_to_hex(p->obj), lref, rref, rref);
                write_note_to_worktree(p->obj, p->remote);
        } else if (is_null_sha1(p->remote)) {
                /* D/F conflict, checkout p->local */
                assert(!is_null_sha1(p->local));
-               OUTPUT(o, 1, "CONFLICT (delete/modify): Notes for object %s "
-                      "deleted in %s and modified in %s. Version from %s "
-                      "left in tree.", sha1_to_hex(p->obj), rref, lref, lref);
+               if (o->verbosity >= 1)
+                       printf("CONFLICT (delete/modify): Notes for object %s "
+                               "deleted in %s and modified in %s. Version from %s "
+                               "left in tree.\n",
+                               sha1_to_hex(p->obj), rref, lref, lref);
                write_note_to_worktree(p->obj, p->local);
        } else {
                /* "regular" conflict, checkout result of ll_merge() */
@@ -415,8 +412,9 @@ static int merge_one_change_manual(struct notes_merge_options *o,
                        reason = "add/add";
                assert(!is_null_sha1(p->local));
                assert(!is_null_sha1(p->remote));
-               OUTPUT(o, 1, "CONFLICT (%s): Merge conflict in notes for "
-                      "object %s", reason, sha1_to_hex(p->obj));
+               if (o->verbosity >= 1)
+                       printf("CONFLICT (%s): Merge conflict in notes for "
+                               "object %s\n", reason, sha1_to_hex(p->obj));
                ll_merge_in_worktree(o, p);
        }
 
@@ -438,24 +436,30 @@ static int merge_one_change(struct notes_merge_options *o,
        case NOTES_MERGE_RESOLVE_MANUAL:
                return merge_one_change_manual(o, p, t);
        case NOTES_MERGE_RESOLVE_OURS:
-               OUTPUT(o, 2, "Using local notes for %s", sha1_to_hex(p->obj));
+               if (o->verbosity >= 2)
+                       printf("Using local notes for %s\n",
+                                               sha1_to_hex(p->obj));
                /* nothing to do */
                return 0;
        case NOTES_MERGE_RESOLVE_THEIRS:
-               OUTPUT(o, 2, "Using remote notes for %s", sha1_to_hex(p->obj));
+               if (o->verbosity >= 2)
+                       printf("Using remote notes for %s\n",
+                                               sha1_to_hex(p->obj));
                if (add_note(t, p->obj, p->remote, combine_notes_overwrite))
                        die("BUG: combine_notes_overwrite failed");
                return 0;
        case NOTES_MERGE_RESOLVE_UNION:
-               OUTPUT(o, 2, "Concatenating local and remote notes for %s",
-                      sha1_to_hex(p->obj));
+               if (o->verbosity >= 2)
+                       printf("Concatenating local and remote notes for %s\n",
+                                                       sha1_to_hex(p->obj));
                if (add_note(t, p->obj, p->remote, combine_notes_concatenate))
                        die("failed to concatenate notes "
                            "(combine_notes_concatenate)");
                return 0;
        case NOTES_MERGE_RESOLVE_CAT_SORT_UNIQ:
-               OUTPUT(o, 2, "Concatenating unique lines in local and remote "
-                      "notes for %s", sha1_to_hex(p->obj));
+               if (o->verbosity >= 2)
+                       printf("Concatenating unique lines in local and remote "
+                               "notes for %s\n", sha1_to_hex(p->obj));
                if (add_note(t, p->obj, p->remote, combine_notes_cat_sort_uniq))
                        die("failed to concatenate notes "
                            "(combine_notes_cat_sort_uniq)");
@@ -518,8 +522,9 @@ static int merge_from_diffs(struct notes_merge_options *o,
        conflicts = merge_changes(o, changes, &num_changes, t);
        free(changes);
 
-       OUTPUT(o, 4, "Merge result: %i unmerged notes and a %s notes tree",
-              conflicts, t->dirty ? "dirty" : "clean");
+       if (o->verbosity >= 4)
+               printf("Merge result: %i unmerged notes and a %s notes tree\n",
+                       conflicts, t->dirty ? "dirty" : "clean");
 
        return conflicts ? -1 : 1;
 }
@@ -617,33 +622,40 @@ int notes_merge(struct notes_merge_options *o,
        if (!bases) {
                base_sha1 = null_sha1;
                base_tree_sha1 = EMPTY_TREE_SHA1_BIN;
-               OUTPUT(o, 4, "No merge base found; doing history-less merge");
+               if (o->verbosity >= 4)
+                       printf("No merge base found; doing history-less merge\n");
        } else if (!bases->next) {
                base_sha1 = bases->item->object.sha1;
                base_tree_sha1 = bases->item->tree->object.sha1;
-               OUTPUT(o, 4, "One merge base found (%.7s)",
-                      sha1_to_hex(base_sha1));
+               if (o->verbosity >= 4)
+                       printf("One merge base found (%.7s)\n",
+                               sha1_to_hex(base_sha1));
        } else {
                /* TODO: How to handle multiple merge-bases? */
                base_sha1 = bases->item->object.sha1;
                base_tree_sha1 = bases->item->tree->object.sha1;
-               OUTPUT(o, 3, "Multiple merge bases found. Using the first "
-                      "(%.7s)", sha1_to_hex(base_sha1));
+               if (o->verbosity >= 3)
+                       printf("Multiple merge bases found. Using the first "
+                               "(%.7s)\n", sha1_to_hex(base_sha1));
        }
 
-       OUTPUT(o, 4, "Merging remote commit %.7s into local commit %.7s with "
-              "merge-base %.7s", sha1_to_hex(remote->object.sha1),
-              sha1_to_hex(local->object.sha1), sha1_to_hex(base_sha1));
+       if (o->verbosity >= 4)
+               printf("Merging remote commit %.7s into local commit %.7s with "
+                       "merge-base %.7s\n", sha1_to_hex(remote->object.sha1),
+                       sha1_to_hex(local->object.sha1),
+                       sha1_to_hex(base_sha1));
 
        if (!hashcmp(remote->object.sha1, base_sha1)) {
                /* Already merged; result == local commit */
-               OUTPUT(o, 2, "Already up-to-date!");
+               if (o->verbosity >= 2)
+                       printf("Already up-to-date!\n");
                hashcpy(result_sha1, local->object.sha1);
                goto found_result;
        }
        if (!hashcmp(local->object.sha1, base_sha1)) {
                /* Fast-forward; result == remote commit */
-               OUTPUT(o, 2, "Fast-forward");
+               if (o->verbosity >= 2)
+                       printf("Fast-forward\n");
                hashcpy(result_sha1, remote->object.sha1);
                goto found_result;
        }
@@ -685,8 +697,9 @@ int notes_merge_commit(struct notes_merge_options *o,
        int path_len = strlen(path), i;
        const char *msg = strstr(partial_commit->buffer, "\n\n");
 
-       OUTPUT(o, 3, "Committing notes in notes merge worktree at %.*s",
-              path_len - 1, path);
+       if (o->verbosity >= 3)
+               printf("Committing notes in notes merge worktree at %.*s\n",
+                       path_len - 1, path);
 
        if (!msg || msg[2] == '\0')
                die("partial notes commit has empty message");
@@ -701,7 +714,9 @@ int notes_merge_commit(struct notes_merge_options *o,
                unsigned char obj_sha1[20], blob_sha1[20];
 
                if (ent->len - path_len != 40 || get_sha1_hex(relpath, obj_sha1)) {
-                       OUTPUT(o, 3, "Skipping non-SHA1 entry '%s'", ent->name);
+                       if (o->verbosity >= 3)
+                               printf("Skipping non-SHA1 entry '%s'\n",
+                                                               ent->name);
                        continue;
                }
 
@@ -713,14 +728,16 @@ int notes_merge_commit(struct notes_merge_options *o,
                if (add_note(partial_tree, obj_sha1, blob_sha1, NULL))
                        die("Failed to add resolved note '%s' to notes tree",
                            ent->name);
-               OUTPUT(o, 4, "Added resolved note for object %s: %s",
-                      sha1_to_hex(obj_sha1), sha1_to_hex(blob_sha1));
+               if (o->verbosity >= 4)
+                       printf("Added resolved note for object %s: %s\n",
+                               sha1_to_hex(obj_sha1), sha1_to_hex(blob_sha1));
        }
 
        create_notes_commit(partial_tree, partial_commit->parents, msg,
                            result_sha1);
-       OUTPUT(o, 4, "Finalized notes merge commit: %s",
-              sha1_to_hex(result_sha1));
+       if (o->verbosity >= 4)
+               printf("Finalized notes merge commit: %s\n",
+                       sha1_to_hex(result_sha1));
        free(path);
        return 0;
 }
@@ -732,7 +749,8 @@ int notes_merge_abort(struct notes_merge_options *o)
        int ret;
 
        strbuf_addstr(&buf, git_path(NOTES_MERGE_WORKTREE));
-       OUTPUT(o, 3, "Removing notes merge worktree at %s", buf.buf);
+       if (o->verbosity >= 3)
+               printf("Removing notes merge worktree at %s\n", buf.buf);
        ret = remove_dir_recursively(&buf, 0);
        strbuf_release(&buf);
        return ret;
index 31976b5d70b6310552b04ce79c7ea0b07bc536d7..d8d09f92aacd114e23378af2cfbeb78a3dd785a0 100644 (file)
--- a/object.c
+++ b/object.c
@@ -149,6 +149,8 @@ struct object *parse_object_buffer(const unsigned char *sha1, enum object_type t
                struct tree *tree = lookup_tree(sha1);
                if (tree) {
                        obj = &tree->object;
+                       if (!tree->buffer)
+                               tree->object.parsed = 0;
                        if (!tree->object.parsed) {
                                if (parse_tree_buffer(tree, buffer, size))
                                        return NULL;
index 0c19b6e5a5677bd14989175abddc119381fac4ef..63a595c45c961fce54cca95ab6e09e3336f0bb8e 100644 (file)
@@ -1,6 +1,7 @@
 #include "cache.h"
 #include "pack.h"
 #include "pack-revindex.h"
+#include "progress.h"
 
 struct idx_entry {
        off_t                offset;
@@ -42,7 +43,10 @@ int check_pack_crc(struct packed_git *p, struct pack_window **w_curs,
 }
 
 static int verify_packfile(struct packed_git *p,
-               struct pack_window **w_curs)
+                          struct pack_window **w_curs,
+                          verify_fn fn,
+                          struct progress *progress, uint32_t base_count)
+
 {
        off_t index_size = p->index_size;
        const unsigned char *index_base = p->index_data;
@@ -113,20 +117,25 @@ static int verify_packfile(struct packed_git *p,
                                            p->pack_name, (uintmax_t)offset);
                }
                data = unpack_entry(p, entries[i].offset, &type, &size);
-               if (!data) {
+               if (!data)
                        err = error("cannot unpack %s from %s at offset %"PRIuMAX"",
                                    sha1_to_hex(entries[i].sha1), p->pack_name,
                                    (uintmax_t)entries[i].offset);
-                       break;
-               }
-               if (check_sha1_signature(entries[i].sha1, data, size, typename(type))) {
+               else if (check_sha1_signature(entries[i].sha1, data, size, typename(type)))
                        err = error("packed %s from %s is corrupt",
                                    sha1_to_hex(entries[i].sha1), p->pack_name);
-                       free(data);
-                       break;
+               else if (fn) {
+                       int eaten = 0;
+                       fn(entries[i].sha1, type, size, data, &eaten);
+                       if (eaten)
+                               data = NULL;
                }
+               if (((base_count + i) & 1023) == 0)
+                       display_progress(progress, base_count + i);
                free(data);
+
        }
+       display_progress(progress, base_count + i);
        free(entries);
 
        return err;
@@ -155,7 +164,8 @@ int verify_pack_index(struct packed_git *p)
        return err;
 }
 
-int verify_pack(struct packed_git *p)
+int verify_pack(struct packed_git *p, verify_fn fn,
+               struct progress *progress, uint32_t base_count)
 {
        int err = 0;
        struct pack_window *w_curs = NULL;
@@ -164,7 +174,7 @@ int verify_pack(struct packed_git *p)
        if (!p->index_data)
                return -1;
 
-       err |= verify_packfile(p, &w_curs);
+       err |= verify_packfile(p, &w_curs, fn, progress, base_count);
        unuse_pack(&w_curs);
 
        return err;
index 9cd3bfbb4b3859cbbdc1b9375ea95f511fffc94e..f84adde3eb3bb6f6d3f4a871167d6a07ef73ebd8 100644 (file)
@@ -129,6 +129,10 @@ const char *write_idx_file(const char *index_name, struct pack_idx_entry **objec
                }
                sha1write(f, obj->sha1, 20);
                git_SHA1_Update(&ctx, obj->sha1, 20);
+               if ((opts->flags & WRITE_IDX_STRICT) &&
+                   (i && !hashcmp(list[-2]->sha1, obj->sha1)))
+                       die("The same object %s appears twice in the pack",
+                           sha1_to_hex(obj->sha1));
        }
 
        if (index_version >= 2) {
diff --git a/pack.h b/pack.h
index 722a54e00a2cb7d9514c12f799fb1ec15930cf5d..a8d9b9f2fcc41bf56007cd48dcfcb94a7e00d3ca 100644 (file)
--- a/pack.h
+++ b/pack.h
@@ -37,7 +37,8 @@ struct pack_header {
 struct pack_idx_option {
        unsigned flags;
        /* flag bits */
-#define WRITE_IDX_VERIFY 01
+#define WRITE_IDX_VERIFY 01 /* verify only, do not write the idx file */
+#define WRITE_IDX_STRICT 02
 
        uint32_t version;
        uint32_t off32_limit;
@@ -70,10 +71,14 @@ struct pack_idx_entry {
        off_t offset;
 };
 
+
+struct progress;
+typedef int (*verify_fn)(const unsigned char*, enum object_type, unsigned long, void*, int*);
+
 extern const char *write_idx_file(const char *index_name, struct pack_idx_entry **objects, int nr_objects, const struct pack_idx_option *, unsigned char *sha1);
 extern int check_pack_crc(struct packed_git *p, struct pack_window **w_curs, off_t offset, off_t len, unsigned int nr);
 extern int verify_pack_index(struct packed_git *);
-extern int verify_pack(struct packed_git *);
+extern int verify_pack(struct packed_git *, verify_fn fn, struct progress *, uint32_t);
 extern void fixup_pack_header_footer(int, unsigned char *, const char *, uint32_t, unsigned char *, off_t);
 extern char *index_pack_lockfile(int fd);
 extern int encode_in_pack_object_header(enum object_type, uintmax_t, unsigned char *);
index 98b24772c7ebe838d513d8e24f3c8acff7839cb9..9235e73163204593379cdf6367133b5b503423c2 100644 (file)
@@ -1,5 +1,6 @@
 perl.mak
 perl.mak.old
+MYMETA.yml
 blib
 blibdirs
 pm_to_blib
index 3fc6b1d320faad3a528db016a0d800ff1bdde4f0..bf7970661f26664e461ed5d6fd7a1982f7e8fadd 100644 (file)
@@ -7,11 +7,25 @@
 #include "revision.h"
 #include "reachable.h"
 #include "cache-tree.h"
+#include "progress.h"
+
+struct connectivity_progress {
+       struct progress *progress;
+       unsigned long count;
+};
+
+static void update_progress(struct connectivity_progress *cp)
+{
+       cp->count++;
+       if ((cp->count & 1023) == 0)
+               display_progress(cp->progress, cp->count);
+}
 
 static void process_blob(struct blob *blob,
                         struct object_array *p,
                         struct name_path *path,
-                        const char *name)
+                        const char *name,
+                        struct connectivity_progress *cp)
 {
        struct object *obj = &blob->object;
 
@@ -20,6 +34,7 @@ static void process_blob(struct blob *blob,
        if (obj->flags & SEEN)
                return;
        obj->flags |= SEEN;
+       update_progress(cp);
        /* Nothing to do, really .. The blob lookup was the important part */
 }
 
@@ -34,7 +49,8 @@ static void process_gitlink(const unsigned char *sha1,
 static void process_tree(struct tree *tree,
                         struct object_array *p,
                         struct name_path *path,
-                        const char *name)
+                        const char *name,
+                        struct connectivity_progress *cp)
 {
        struct object *obj = &tree->object;
        struct tree_desc desc;
@@ -46,6 +62,7 @@ static void process_tree(struct tree *tree,
        if (obj->flags & SEEN)
                return;
        obj->flags |= SEEN;
+       update_progress(cp);
        if (parse_tree(tree) < 0)
                die("bad tree object %s", sha1_to_hex(obj->sha1));
        add_object(obj, p, path, name);
@@ -57,23 +74,25 @@ static void process_tree(struct tree *tree,
 
        while (tree_entry(&desc, &entry)) {
                if (S_ISDIR(entry.mode))
-                       process_tree(lookup_tree(entry.sha1), p, &me, entry.path);
+                       process_tree(lookup_tree(entry.sha1), p, &me, entry.path, cp);
                else if (S_ISGITLINK(entry.mode))
                        process_gitlink(entry.sha1, p, &me, entry.path);
                else
-                       process_blob(lookup_blob(entry.sha1), p, &me, entry.path);
+                       process_blob(lookup_blob(entry.sha1), p, &me, entry.path, cp);
        }
        free(tree->buffer);
        tree->buffer = NULL;
 }
 
-static void process_tag(struct tag *tag, struct object_array *p, const char *name)
+static void process_tag(struct tag *tag, struct object_array *p,
+                       const char *name, struct connectivity_progress *cp)
 {
        struct object *obj = &tag->object;
 
        if (obj->flags & SEEN)
                return;
        obj->flags |= SEEN;
+       update_progress(cp);
 
        if (parse_tag(tag) < 0)
                die("bad tag object %s", sha1_to_hex(obj->sha1));
@@ -81,15 +100,18 @@ static void process_tag(struct tag *tag, struct object_array *p, const char *nam
                add_object(tag->tagged, p, NULL, name);
 }
 
-static void walk_commit_list(struct rev_info *revs)
+static void walk_commit_list(struct rev_info *revs,
+                            struct connectivity_progress *cp)
 {
        int i;
        struct commit *commit;
        struct object_array objects = OBJECT_ARRAY_INIT;
 
        /* Walk all commits, process their trees */
-       while ((commit = get_revision(revs)) != NULL)
-               process_tree(commit->tree, &objects, NULL, "");
+       while ((commit = get_revision(revs)) != NULL) {
+               process_tree(commit->tree, &objects, NULL, "", cp);
+               update_progress(cp);
+       }
 
        /* Then walk all the pending objects, recursively processing them too */
        for (i = 0; i < revs->pending.nr; i++) {
@@ -97,15 +119,15 @@ static void walk_commit_list(struct rev_info *revs)
                struct object *obj = pending->item;
                const char *name = pending->name;
                if (obj->type == OBJ_TAG) {
-                       process_tag((struct tag *) obj, &objects, name);
+                       process_tag((struct tag *) obj, &objects, name, cp);
                        continue;
                }
                if (obj->type == OBJ_TREE) {
-                       process_tree((struct tree *)obj, &objects, NULL, name);
+                       process_tree((struct tree *)obj, &objects, NULL, name, cp);
                        continue;
                }
                if (obj->type == OBJ_BLOB) {
-                       process_blob((struct blob *)obj, &objects, NULL, name);
+                       process_blob((struct blob *)obj, &objects, NULL, name, cp);
                        continue;
                }
                die("unknown pending object %s (%s)", sha1_to_hex(obj->sha1), name);
@@ -191,8 +213,11 @@ static void add_cache_refs(struct rev_info *revs)
                add_cache_tree(active_cache_tree, revs);
 }
 
-void mark_reachable_objects(struct rev_info *revs, int mark_reflog)
+void mark_reachable_objects(struct rev_info *revs, int mark_reflog,
+                           struct progress *progress)
 {
+       struct connectivity_progress cp;
+
        /*
         * Set up revision parsing, and mark us as being interested
         * in all object types, not just commits.
@@ -211,11 +236,15 @@ void mark_reachable_objects(struct rev_info *revs, int mark_reflog)
        if (mark_reflog)
                for_each_reflog(add_one_reflog, revs);
 
+       cp.progress = progress;
+       cp.count = 0;
+
        /*
         * Set up the revision walk - this will move all commits
         * from the pending list to the commit walking list.
         */
        if (prepare_revision_walk(revs))
                die("revision walk setup failed");
-       walk_commit_list(revs);
+       walk_commit_list(revs, &cp);
+       display_progress(cp.progress, cp.count);
 }
index 40751810b64f8bbf9c0a633472a0ef27d23ed1a5..5d082adfecc47c40074212df2ddedc00d8a5ecb1 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef REACHEABLE_H
 #define REACHEABLE_H
 
-extern void mark_reachable_objects(struct rev_info *revs, int mark_reflog);
+struct progress;
+extern void mark_reachable_objects(struct rev_info *revs, int mark_reflog, struct progress *);
 
 #endif
index 5790a91044e4fdf5b2eec515051a66c110e0daa4..a51bba1b9569d64c348f3affc90ed8640e0e0189 100644 (file)
@@ -1001,7 +1001,8 @@ int add_index_entry(struct index_state *istate, struct cache_entry *ce, int opti
  */
 static struct cache_entry *refresh_cache_ent(struct index_state *istate,
                                             struct cache_entry *ce,
-                                            unsigned int options, int *err)
+                                            unsigned int options, int *err,
+                                            int *changed_ret)
 {
        struct stat st;
        struct cache_entry *updated;
@@ -1033,6 +1034,8 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,
        }
 
        changed = ie_match_stat(istate, ce, &st, options);
+       if (changed_ret)
+               *changed_ret = changed;
        if (!changed) {
                /*
                 * The path is unchanged.  If we were told to ignore
@@ -1102,14 +1105,21 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
        int first = 1;
        int in_porcelain = (flags & REFRESH_IN_PORCELAIN);
        unsigned int options = really ? CE_MATCH_IGNORE_VALID : 0;
-       const char *needs_update_fmt;
-       const char *needs_merge_fmt;
-
-       needs_update_fmt = (in_porcelain ? "M\t%s\n" : "%s: needs update\n");
-       needs_merge_fmt = (in_porcelain ? "U\t%s\n" : "%s: needs merge\n");
+       const char *modified_fmt;
+       const char *deleted_fmt;
+       const char *typechange_fmt;
+       const char *added_fmt;
+       const char *unmerged_fmt;
+
+       modified_fmt = (in_porcelain ? "M\t%s\n" : "%s: needs update\n");
+       deleted_fmt = (in_porcelain ? "D\t%s\n" : "%s: needs update\n");
+       typechange_fmt = (in_porcelain ? "T\t%s\n" : "%s needs update\n");
+       added_fmt = (in_porcelain ? "A\t%s\n" : "%s needs update\n");
+       unmerged_fmt = (in_porcelain ? "U\t%s\n" : "%s: needs merge\n");
        for (i = 0; i < istate->cache_nr; i++) {
                struct cache_entry *ce, *new;
                int cache_errno = 0;
+               int changed = 0;
 
                ce = istate->cache[i];
                if (ignore_submodules && S_ISGITLINK(ce->ce_mode))
@@ -1122,7 +1132,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
                        i--;
                        if (allow_unmerged)
                                continue;
-                       show_file(needs_merge_fmt, ce->name, in_porcelain, &first, header_msg);
+                       show_file(unmerged_fmt, ce->name, in_porcelain, &first, header_msg);
                        has_errors = 1;
                        continue;
                }
@@ -1130,10 +1140,12 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
                if (pathspec && !match_pathspec(pathspec, ce->name, strlen(ce->name), 0, seen))
                        continue;
 
-               new = refresh_cache_ent(istate, ce, options, &cache_errno);
+               new = refresh_cache_ent(istate, ce, options, &cache_errno, &changed);
                if (new == ce)
                        continue;
                if (!new) {
+                       const char *fmt;
+
                        if (not_new && cache_errno == ENOENT)
                                continue;
                        if (really && cache_errno == EINVAL) {
@@ -1145,7 +1157,17 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
                        }
                        if (quiet)
                                continue;
-                       show_file(needs_update_fmt, ce->name, in_porcelain, &first, header_msg);
+
+                       if (cache_errno == ENOENT)
+                               fmt = deleted_fmt;
+                       else if (ce->ce_flags & CE_INTENT_TO_ADD)
+                               fmt = added_fmt; /* must be before other checks */
+                       else if (changed & TYPE_CHANGED)
+                               fmt = typechange_fmt;
+                       else
+                               fmt = modified_fmt;
+                       show_file(fmt,
+                                 ce->name, in_porcelain, &first, header_msg);
                        has_errors = 1;
                        continue;
                }
@@ -1157,7 +1179,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
 
 static struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int really)
 {
-       return refresh_cache_ent(&the_index, ce, really, NULL);
+       return refresh_cache_ent(&the_index, ce, really, NULL, NULL);
 }
 
 static int verify_hdr(struct cache_header *hdr, unsigned long size)
@@ -1202,29 +1224,18 @@ int read_index(struct index_state *istate)
        return read_index_from(istate, get_index_file());
 }
 
-static void convert_from_disk(struct ondisk_cache_entry *ondisk, struct cache_entry *ce)
+static struct cache_entry *create_from_disk(struct ondisk_cache_entry *ondisk)
 {
+       struct cache_entry *ce;
        size_t len;
        const char *name;
+       unsigned int flags;
 
-       ce->ce_ctime.sec = ntohl(ondisk->ctime.sec);
-       ce->ce_mtime.sec = ntohl(ondisk->mtime.sec);
-       ce->ce_ctime.nsec = ntohl(ondisk->ctime.nsec);
-       ce->ce_mtime.nsec = ntohl(ondisk->mtime.nsec);
-       ce->ce_dev   = ntohl(ondisk->dev);
-       ce->ce_ino   = ntohl(ondisk->ino);
-       ce->ce_mode  = ntohl(ondisk->mode);
-       ce->ce_uid   = ntohl(ondisk->uid);
-       ce->ce_gid   = ntohl(ondisk->gid);
-       ce->ce_size  = ntohl(ondisk->size);
        /* On-disk flags are just 16 bits */
-       ce->ce_flags = ntohs(ondisk->flags);
-
-       hashcpy(ce->sha1, ondisk->sha1);
-
-       len = ce->ce_flags & CE_NAMEMASK;
+       flags = ntohs(ondisk->flags);
+       len = flags & CE_NAMEMASK;
 
-       if (ce->ce_flags & CE_EXTENDED) {
+       if (flags & CE_EXTENDED) {
                struct ondisk_cache_entry_extended *ondisk2;
                int extended_flags;
                ondisk2 = (struct ondisk_cache_entry_extended *)ondisk;
@@ -1232,7 +1243,7 @@ static void convert_from_disk(struct ondisk_cache_entry *ondisk, struct cache_en
                /* We do not yet understand any bit out of CE_EXTENDED_FLAGS */
                if (extended_flags & ~CE_EXTENDED_FLAGS)
                        die("Unknown index entry format %08x", extended_flags);
-               ce->ce_flags |= extended_flags;
+               flags |= extended_flags;
                name = ondisk2->name;
        }
        else
@@ -1240,25 +1251,26 @@ static void convert_from_disk(struct ondisk_cache_entry *ondisk, struct cache_en
 
        if (len == CE_NAMEMASK)
                len = strlen(name);
-       /*
-        * NEEDSWORK: If the original index is crafted, this copy could
-        * go unchecked.
-        */
-       memcpy(ce->name, name, len + 1);
-}
 
-static inline size_t estimate_cache_size(size_t ondisk_size, unsigned int entries)
-{
-       size_t fix_size_mem = offsetof(struct cache_entry, name);
-       size_t fix_size_dsk = offsetof(struct ondisk_cache_entry, name);
-       long per_entry = (fix_size_mem - fix_size_dsk + 7) & ~7;
+       ce = xmalloc(cache_entry_size(len));
 
-       /*
-        * Alignment can cause differences. This should be "alignof", but
-        * since that's a gcc'ism, just use the size of a pointer.
-        */
-       per_entry += sizeof(void *);
-       return ondisk_size + entries*per_entry;
+       ce->ce_ctime.sec = ntohl(ondisk->ctime.sec);
+       ce->ce_mtime.sec = ntohl(ondisk->mtime.sec);
+       ce->ce_ctime.nsec = ntohl(ondisk->ctime.nsec);
+       ce->ce_mtime.nsec = ntohl(ondisk->mtime.nsec);
+       ce->ce_dev   = ntohl(ondisk->dev);
+       ce->ce_ino   = ntohl(ondisk->ino);
+       ce->ce_mode  = ntohl(ondisk->mode);
+       ce->ce_uid   = ntohl(ondisk->uid);
+       ce->ce_gid   = ntohl(ondisk->gid);
+       ce->ce_size  = ntohl(ondisk->size);
+       ce->ce_flags = flags;
+
+       hashcpy(ce->sha1, ondisk->sha1);
+
+       memcpy(ce->name, name, len);
+       ce->name[len] = '\0';
+       return ce;
 }
 
 /* remember to discard_cache() before reading a different cache! */
@@ -1266,7 +1278,7 @@ int read_index_from(struct index_state *istate, const char *path)
 {
        int fd, i;
        struct stat st;
-       unsigned long src_offset, dst_offset;
+       unsigned long src_offset;
        struct cache_header *hdr;
        void *mmap;
        size_t mmap_size;
@@ -1305,29 +1317,18 @@ int read_index_from(struct index_state *istate, const char *path)
        istate->cache_nr = ntohl(hdr->hdr_entries);
        istate->cache_alloc = alloc_nr(istate->cache_nr);
        istate->cache = xcalloc(istate->cache_alloc, sizeof(struct cache_entry *));
-
-       /*
-        * The disk format is actually larger than the in-memory format,
-        * due to space for nsec etc, so even though the in-memory one
-        * has room for a few  more flags, we can allocate using the same
-        * index size
-        */
-       istate->alloc = xmalloc(estimate_cache_size(mmap_size, istate->cache_nr));
        istate->initialized = 1;
 
        src_offset = sizeof(*hdr);
-       dst_offset = 0;
        for (i = 0; i < istate->cache_nr; i++) {
                struct ondisk_cache_entry *disk_ce;
                struct cache_entry *ce;
 
                disk_ce = (struct ondisk_cache_entry *)((char *)mmap + src_offset);
-               ce = (struct cache_entry *)((char *)istate->alloc + dst_offset);
-               convert_from_disk(disk_ce, ce);
+               ce = create_from_disk(disk_ce);
                set_index_entry(istate, i, ce);
 
                src_offset += ondisk_ce_size(ce);
-               dst_offset += ce_size(ce);
        }
        istate->timestamp.sec = st.st_mtime;
        istate->timestamp.nsec = ST_MTIME_NSEC(st);
@@ -1361,11 +1362,15 @@ int read_index_from(struct index_state *istate, const char *path)
 
 int is_index_unborn(struct index_state *istate)
 {
-       return (!istate->cache_nr && !istate->alloc && !istate->timestamp.sec);
+       return (!istate->cache_nr && !istate->timestamp.sec);
 }
 
 int discard_index(struct index_state *istate)
 {
+       int i;
+
+       for (i = 0; i < istate->cache_nr; i++)
+               free(istate->cache[i]);
        resolve_undo_clear_index(istate);
        istate->cache_nr = 0;
        istate->cache_changed = 0;
@@ -1374,8 +1379,6 @@ int discard_index(struct index_state *istate)
        istate->name_hash_initialized = 0;
        free_hash(&istate->name_hash);
        cache_tree_free(&(istate->cache_tree));
-       free(istate->alloc);
-       istate->alloc = NULL;
        istate->initialized = 0;
 
        /* no need to throw away allocated active_cache */
diff --git a/refs.c b/refs.c
index 44c1c86e187568f8cf1224f2f540cb6b73db3469..f5cb297292f5ae577e3d2719f5f78512aae8cf28 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -48,7 +48,7 @@ static const char *parse_ref_line(char *line, unsigned char *sha1)
 }
 
 static void add_ref(const char *name, const unsigned char *sha1,
-                   int flag, struct ref_array *refs,
+                   int flag, int check_name, struct ref_array *refs,
                    struct ref_entry **new_entry)
 {
        int len;
@@ -59,7 +59,8 @@ static void add_ref(const char *name, const unsigned char *sha1,
        entry = xmalloc(sizeof(struct ref_entry) + len);
        hashcpy(entry->sha1, sha1);
        hashclr(entry->peeled);
-       if (check_refname_format(name, REFNAME_ALLOW_ONELEVEL|REFNAME_DOT_COMPONENT))
+       if (check_name &&
+           check_refname_format(name, REFNAME_ALLOW_ONELEVEL|REFNAME_DOT_COMPONENT))
                die("Reference has invalid format: '%s'", name);
        memcpy(entry->name, name, len);
        entry->flag = flag;
@@ -234,7 +235,7 @@ static void read_packed_refs(FILE *f, struct ref_array *array)
 
                name = parse_ref_line(refline, sha1);
                if (name) {
-                       add_ref(name, sha1, flag, array, &last);
+                       add_ref(name, sha1, flag, 1, array, &last);
                        continue;
                }
                if (last &&
@@ -249,7 +250,7 @@ static void read_packed_refs(FILE *f, struct ref_array *array)
 
 void add_extra_ref(const char *name, const unsigned char *sha1, int flag)
 {
-       add_ref(name, sha1, flag, &extra_refs, NULL);
+       add_ref(name, sha1, flag, 0, &extra_refs, NULL);
 }
 
 void clear_extra_refs(void)
@@ -333,12 +334,11 @@ static void get_ref_dir(const char *submodule, const char *base,
                                        hashclr(sha1);
                                        flag |= REF_ISBROKEN;
                                }
-                       } else
-                               if (read_ref_full(ref, sha1, 1, &flag)) {
-                                       hashclr(sha1);
-                                       flag |= REF_ISBROKEN;
-                               }
-                       add_ref(ref, sha1, flag, array, NULL);
+                       } else if (read_ref_full(ref, sha1, 1, &flag)) {
+                               hashclr(sha1);
+                               flag |= REF_ISBROKEN;
+                       }
+                       add_ref(ref, sha1, flag, 1, array, NULL);
                }
                free(ref);
                closedir(dir);
@@ -1003,13 +1003,6 @@ const char *ref_rev_parse_rules[] = {
        NULL
 };
 
-const char *ref_fetch_rules[] = {
-       "%.*s",
-       "refs/%.*s",
-       "refs/heads/%.*s",
-       NULL
-};
-
 int refname_match(const char *abbrev_name, const char *full_name, const char **rules)
 {
        const char **p;
index 905d29501213f058f0d8cc88e7ba57527d506483..f435fdb4b147d2e2ce5480ddb4832228af1cb73b 100644 (file)
@@ -13,7 +13,7 @@
  *
  * With the aggressive flag, it additionally removes SEQ_OLD_DIR,
  * ignoring any errors.  Inteded to be used by the sequencer's
- * '--reset' subcommand.
+ * '--quit' subcommand.
  */
 void remove_sequencer_state(int aggressive);
 
index 27f3b9b278a97f66f92ca61a2bc39e30f0a70317..956422ba4a5df5f46caaf85f10e4c85321439272 100644 (file)
@@ -1267,7 +1267,8 @@ unsigned long unpack_object_header_buffer(const unsigned char *buf,
        while (c & 0x80) {
                if (len <= used || bitsizeof(long) <= shift) {
                        error("bad object header");
-                       return 0;
+                       size = used = 0;
+                       break;
                }
                c = buf[used++];
                size += (c & 0x7f) << shift;
@@ -2616,7 +2617,7 @@ static int index_mem(unsigned char *sha1, void *buf, size_t size,
        if ((type == OBJ_BLOB) && path) {
                struct strbuf nbuf = STRBUF_INIT;
                if (convert_to_git(path, buf, size, &nbuf,
-                                  write_object ? safe_crlf : 0)) {
+                                  write_object ? safe_crlf : SAFE_CRLF_FALSE)) {
                        buf = strbuf_detach(&nbuf, &size);
                        re_allocated = 1;
                }
index 3ad2cc00160fbf24e1e4904bb37ce44e8c414ce5..a849705197a6ad3d0d2ab9de22b269de6b4fc2b1 100644 (file)
--- a/strbuf.c
+++ b/strbuf.c
@@ -397,3 +397,17 @@ int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint)
 
        return len;
 }
+
+void strbuf_add_lines(struct strbuf *out, const char *prefix,
+                     const char *buf, size_t size)
+{
+       while (size) {
+               const char *next = memchr(buf, '\n', size);
+               next = next ? (next + 1) : (buf + size);
+               strbuf_addstr(out, prefix);
+               strbuf_add(out, buf, next - buf);
+               size -= next - buf;
+               buf = next;
+       }
+       strbuf_complete_line(out);
+}
index 46a33f8c46985c4377071011d6ea48d6d3fe5331..08fc13d386b410ee9163c8408557e06ab4df7833 100644 (file)
--- a/strbuf.h
+++ b/strbuf.h
@@ -100,6 +100,14 @@ extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...);
 __attribute__((format (printf,2,0)))
 extern void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap);
 
+extern void strbuf_add_lines(struct strbuf *sb, const char *prefix, const char *buf, size_t size);
+
+static inline void strbuf_complete_line(struct strbuf *sb)
+{
+       if (sb->len && sb->buf[sb->len - 1] != '\n')
+               strbuf_addch(sb, '\n');
+}
+
 extern size_t strbuf_fread(struct strbuf *, size_t, FILE *);
 /* XXX: if read fails, any partial read is undone */
 extern ssize_t strbuf_read(struct strbuf *, int fd, size_t hint);
index 0fd10a0fdbf5d1af10819dea808b43f6b13b98a8..52cdcc6a6347a786deafad34efdb9dc4dc3670ff 100644 (file)
@@ -391,7 +391,7 @@ static void commit_need_pushing(struct commit *commit, struct commit_list *paren
        rev.diffopt.format_callback_data = needs_pushing;
        diff_tree_combined(commit->object.sha1, parents, n, 1, &rev);
 
-       free(parents);
+       free((void *)parents);
 }
 
 int check_submodule_needs_pushing(unsigned char new_sha1[20], const char *remotes_name)
index cb45574a7b5cbdf6da58f609befc4a0bb396db2f..ee1659c17810d2c9ce7836582a80fd3d0d89ca24 100755 (executable)
@@ -253,6 +253,60 @@ test_expect_success 'revert also handles conflicts sanely' '
        test_cmp expected actual
 '
 
+test_expect_success 'failed revert sets REVERT_HEAD' '
+       pristine_detach initial &&
+       test_must_fail git revert picked &&
+       test_cmp_rev picked REVERT_HEAD
+'
+
+test_expect_success 'successful revert does not set REVERT_HEAD' '
+       pristine_detach base &&
+       git revert base &&
+       test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
+       test_must_fail git rev-parse --verify REVERT_HEAD
+'
+
+test_expect_success 'revert --no-commit sets REVERT_HEAD' '
+       pristine_detach base &&
+       git revert --no-commit base &&
+       test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
+       test_cmp_rev base REVERT_HEAD
+'
+
+test_expect_success 'revert w/dirty tree does not set REVERT_HEAD' '
+       pristine_detach base &&
+       echo foo > foo &&
+       test_must_fail git revert base &&
+       test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
+       test_must_fail git rev-parse --verify REVERT_HEAD
+'
+
+test_expect_success 'GIT_CHERRY_PICK_HELP does not suppress REVERT_HEAD' '
+       pristine_detach initial &&
+       (
+               GIT_CHERRY_PICK_HELP="and then do something else" &&
+               GIT_REVERT_HELP="and then do something else, again" &&
+               export GIT_CHERRY_PICK_HELP GIT_REVERT_HELP &&
+               test_must_fail git revert picked
+       ) &&
+       test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
+       test_cmp_rev picked REVERT_HEAD
+'
+
+test_expect_success 'git reset clears REVERT_HEAD' '
+       pristine_detach initial &&
+       test_must_fail git revert picked &&
+       git reset &&
+       test_must_fail git rev-parse --verify REVERT_HEAD
+'
+
+test_expect_success 'failed commit does not clear REVERT_HEAD' '
+       pristine_detach initial &&
+       test_must_fail git revert picked &&
+       test_must_fail git commit &&
+       test_cmp_rev picked REVERT_HEAD
+'
+
 test_expect_success 'revert conflict, diff3 -m style' '
        pristine_detach initial &&
        git config merge.conflictstyle diff3 &&
index 3bca2b3dd5cc252cad615b83f84891f6dc2bacfe..2c4c1c851dcbb1cd38edc2a2620e2b04e36f7192 100755 (executable)
@@ -2,6 +2,7 @@
 
 test_description='Test cherry-pick continuation features
 
+  + yetanotherpick: rewrites foo to e
   + anotherpick: rewrites foo to d
   + picked: rewrites foo to c
   + unrelatedpick: rewrites unrelated to reallyunrelated
@@ -13,12 +14,18 @@ test_description='Test cherry-pick continuation features
 . ./test-lib.sh
 
 pristine_detach () {
-       git cherry-pick --reset &&
+       git cherry-pick --quit &&
        git checkout -f "$1^0" &&
        git read-tree -u --reset HEAD &&
        git clean -d -f -f -q -x
 }
 
+test_cmp_rev () {
+       git rev-parse --verify "$1" >expect.rev &&
+       git rev-parse --verify "$2" >actual.rev &&
+       test_cmp expect.rev actual.rev
+}
+
 test_expect_success setup '
        echo unrelated >unrelated &&
        git add unrelated &&
@@ -27,6 +34,7 @@ test_expect_success setup '
        test_commit unrelatedpick unrelated reallyunrelated &&
        test_commit picked foo c &&
        test_commit anotherpick foo d &&
+       test_commit yetanotherpick foo e &&
        git config advice.detachedhead false
 
 '
@@ -70,18 +78,117 @@ test_expect_success 'cherry-pick cleans up sequencer state upon success' '
        test_path_is_missing .git/sequencer
 '
 
-test_expect_success '--reset does not complain when no cherry-pick is in progress' '
+test_expect_success '--quit does not complain when no cherry-pick is in progress' '
        pristine_detach initial &&
-       git cherry-pick --reset
+       git cherry-pick --quit
 '
 
-test_expect_success '--reset cleans up sequencer state' '
+test_expect_success '--abort requires cherry-pick in progress' '
+       pristine_detach initial &&
+       test_must_fail git cherry-pick --abort
+'
+
+test_expect_success '--quit cleans up sequencer state' '
        pristine_detach initial &&
        test_must_fail git cherry-pick base..picked &&
-       git cherry-pick --reset &&
+       git cherry-pick --quit &&
        test_path_is_missing .git/sequencer
 '
 
+test_expect_success '--quit keeps HEAD and conflicted index intact' '
+       pristine_detach initial &&
+       cat >expect <<-\EOF &&
+       OBJID
+       :100644 100644 OBJID OBJID M    unrelated
+       OBJID
+       :000000 100644 OBJID OBJID A    foo
+       :000000 100644 OBJID OBJID A    unrelated
+       EOF
+       test_must_fail git cherry-pick base..picked &&
+       git cherry-pick --quit &&
+       test_path_is_missing .git/sequencer &&
+       test_must_fail git update-index --refresh &&
+       {
+               git rev-list HEAD |
+               git diff-tree --root --stdin |
+               sed "s/$_x40/OBJID/g"
+       } >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success '--abort to cancel multiple cherry-pick' '
+       pristine_detach initial &&
+       test_must_fail git cherry-pick base..anotherpick &&
+       git cherry-pick --abort &&
+       test_path_is_missing .git/sequencer &&
+       test_cmp_rev initial HEAD &&
+       git update-index --refresh &&
+       git diff-index --exit-code HEAD
+'
+
+test_expect_success '--abort to cancel single cherry-pick' '
+       pristine_detach initial &&
+       test_must_fail git cherry-pick picked &&
+       git cherry-pick --abort &&
+       test_path_is_missing .git/sequencer &&
+       test_cmp_rev initial HEAD &&
+       git update-index --refresh &&
+       git diff-index --exit-code HEAD
+'
+
+test_expect_success 'cherry-pick --abort to cancel multiple revert' '
+       pristine_detach anotherpick &&
+       test_must_fail git revert base..picked &&
+       git cherry-pick --abort &&
+       test_path_is_missing .git/sequencer &&
+       test_cmp_rev anotherpick HEAD &&
+       git update-index --refresh &&
+       git diff-index --exit-code HEAD
+'
+
+test_expect_success 'revert --abort works, too' '
+       pristine_detach anotherpick &&
+       test_must_fail git revert base..picked &&
+       git revert --abort &&
+       test_path_is_missing .git/sequencer &&
+       test_cmp_rev anotherpick HEAD
+'
+
+test_expect_success '--abort to cancel single revert' '
+       pristine_detach anotherpick &&
+       test_must_fail git revert picked &&
+       git revert --abort &&
+       test_path_is_missing .git/sequencer &&
+       test_cmp_rev anotherpick HEAD &&
+       git update-index --refresh &&
+       git diff-index --exit-code HEAD
+'
+
+test_expect_success '--abort keeps unrelated change, easy case' '
+       pristine_detach unrelatedpick &&
+       echo changed >expect &&
+       test_must_fail git cherry-pick picked..yetanotherpick &&
+       echo changed >unrelated &&
+       git cherry-pick --abort &&
+       test_cmp expect unrelated
+'
+
+test_expect_success '--abort refuses to clobber unrelated change, harder case' '
+       pristine_detach initial &&
+       echo changed >expect &&
+       test_must_fail git cherry-pick base..anotherpick &&
+       echo changed >unrelated &&
+       test_must_fail git cherry-pick --abort &&
+       test_cmp expect unrelated &&
+       git rev-list HEAD >log &&
+       test_line_count = 2 log &&
+       test_must_fail git update-index --refresh &&
+
+       git checkout unrelated &&
+       git cherry-pick --abort &&
+       test_cmp_rev initial HEAD
+'
+
 test_expect_success 'cherry-pick cleans up sequencer state when one commit is left' '
        pristine_detach initial &&
        test_must_fail git cherry-pick base..picked &&
@@ -106,6 +213,16 @@ test_expect_success 'cherry-pick cleans up sequencer state when one commit is le
        test_cmp expect actual
 '
 
+test_expect_failure '--abort after last commit in sequence' '
+       pristine_detach initial &&
+       test_must_fail git cherry-pick base..picked &&
+       git cherry-pick --abort &&
+       test_path_is_missing .git/sequencer &&
+       test_cmp_rev initial HEAD &&
+       git update-index --refresh &&
+       git diff-index --exit-code HEAD
+'
+
 test_expect_success 'cherry-pick does not implicitly stomp an existing operation' '
        pristine_detach initial &&
        test_must_fail git cherry-pick base..anotherpick &&
index b68c56b68c0f80a0d96b513733bc5fb17db6fed4..4bd2a1c838e9a522c4376860e726455d3cdb92b0 100755 (executable)
@@ -105,7 +105,7 @@ test_expect_funcname () {
        grep "^@@.*@@ $1" diff
 }
 
-for p in bibtex cpp csharp fortran html java objc pascal perl php python ruby tex
+for p in bibtex cpp csharp fortran html java matlab objc pascal perl php python ruby tex
 do
        test_expect_success "builtin $p pattern compiles" '
                echo "*.java diff=$p" >.gitattributes &&
index c374aa4c1c60e9a12cf1ebf5587daf3656e4851a..6f1e5a2a15f0215e4ed7c19437f5d000edbbd255 100755 (executable)
@@ -299,6 +299,7 @@ test_language_driver csharp
 test_language_driver fortran
 test_language_driver html
 test_language_driver java
+test_language_driver matlab
 test_language_driver objc
 test_language_driver pascal
 test_language_driver perl
diff --git a/t/t4034/matlab/expect b/t/t4034/matlab/expect
new file mode 100644 (file)
index 0000000..72cf3e9
--- /dev/null
@@ -0,0 +1,14 @@
+<BOLD>diff --git a/pre b/post<RESET>
+<BOLD>index dc204db..70e05f0 100644<RESET>
+<BOLD>--- a/pre<RESET>
+<BOLD>+++ b/post<RESET>
+<CYAN>@@ -1,9 +1,9 @@<RESET>
+(<RED>1<RESET><GREEN>0<RESET>) (<RED>-1e10<RESET><GREEN>-0e10<RESET>) '<RED>b<RESET><GREEN>y<RESET>';
+[<RED>a<RESET><GREEN>x<RESET>] {<RED>a<RESET><GREEN>x<RESET>} <RED>a<RESET><GREEN>x<RESET>.<RED>b<RESET><GREEN>y<RESET>;
+~<RED>a<RESET><GREEN>x<RESET>;
+<RED>a<RESET><GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>.*<RED>b a<RESET><GREEN>y x<RESET>/<RED>b a<RESET><GREEN>y x<RESET>./<RED>b a<RESET><GREEN>y x<RESET>^<RED>b a<RESET><GREEN>y x<RESET>.^<RED>b a<RESET><GREEN>y x<RESET>.\<RED>b a<RESET><GREEN>y x<RESET>.';
+<RED>a<RESET><GREEN>x<RESET>+<RED>b a<RESET><GREEN>y x<RESET>-<RED>b<RESET><GREEN>y<RESET>;
+<RED>a<RESET><GREEN>x<RESET>&<RED>b a<RESET><GREEN>y x<RESET>&&<RED>b a<RESET><GREEN>y x<RESET>|<RED>b a<RESET><GREEN>y x<RESET>||<RED>b<RESET><GREEN>y<RESET>;
+<RED>a<RESET><GREEN>x<RESET><<RED>b a<RESET><GREEN>y x<RESET><=<RED>b a<RESET><GREEN>y x<RESET>><RED>b a<RESET><GREEN>y x<RESET>>=<RED>b<RESET><GREEN>y<RESET>;
+<RED>a<RESET><GREEN>x<RESET>==<RED>b a<RESET><GREEN>y x<RESET>~=<RED>b<RESET><GREEN>y<RESET>;
+<RED>a<RESET><GREEN>x<RESET>,<RED>b<RESET><GREEN>y<RESET>;
diff --git a/t/t4034/matlab/post b/t/t4034/matlab/post
new file mode 100644 (file)
index 0000000..70e05f0
--- /dev/null
@@ -0,0 +1,9 @@
+(0) (-0e10) 'y';
+[x] {x} x.y;
+~x;
+x*y x.*y x/y x./y x^y x.^y x.\y x.';
+x+y x-y;
+x&y x&&y x|y x||y;
+x<y x<=y x>y x>=y;
+x==y x~=y;
+x,y;
diff --git a/t/t4034/matlab/pre b/t/t4034/matlab/pre
new file mode 100644 (file)
index 0000000..dc204db
--- /dev/null
@@ -0,0 +1,9 @@
+(1) (-1e10) 'b';
+[a] {a} a.b;
+~a;
+a*b a.*b a/b a./b a^b a.^b a.\b a.';
+a+b a-b;
+a&b a&&b a|b a||b;
+a<b a<=b a>b a>=b;
+a==b a~=b;
+a,b;
index 983e34bec67a4cc4ba1182332e495377cc879ac9..222f7559e92caa2a0bbd128b0bb6bac14e2e113f 100755 (executable)
@@ -346,11 +346,11 @@ test_expect_success 'set up more tangled history' '
 '
 
 cat > expect <<\EOF
-*   Merge commit 'reach'
+*   Merge tag 'reach'
 |\
 | \
 |  \
-*-. \   Merge commit 'octopus-a'; commit 'octopus-b'
+*-. \   Merge tags 'octopus-a' and 'octopus-b'
 |\ \ \
 * | | | seventh
 | | * | octopus-b
index 889842e7fc0cf80f7e8b6016a508bffdb0399d32..d9068981f8475c37d30e584bc6b795075a2f3063 100755 (executable)
@@ -96,7 +96,7 @@ test_expect_success 'git archive with --output' \
     'git archive --output=b4.tar HEAD &&
     test_cmp b.tar b4.tar'
 
-test_expect_success 'git archive --remote' \
+test_expect_success NOT_MINGW 'git archive --remote' \
     'git archive --remote=. HEAD >b5.tar &&
     test_cmp b.tar b5.tar'
 
@@ -266,7 +266,7 @@ test_expect_success 'archive --list mentions user filter' '
        grep "^bar\$" output
 '
 
-test_expect_success 'archive --list shows only enabled remote filters' '
+test_expect_success NOT_MINGW 'archive --list shows only enabled remote filters' '
        git archive --list --remote=. >output &&
        ! grep "^tar\.foo\$" output &&
        grep "^bar\$" output
@@ -298,7 +298,7 @@ test_expect_success 'extension matching requires dot' '
        test_cmp b.tar config-implicittar.foo
 '
 
-test_expect_success 'only enabled filters are available remotely' '
+test_expect_success NOT_MINGW 'only enabled filters are available remotely' '
        test_must_fail git archive --remote=. --format=tar.foo HEAD \
                >remote.tar.foo &&
        git archive --remote=. --format=bar >remote.bar HEAD &&
@@ -341,12 +341,12 @@ test_expect_success GZIP,GUNZIP 'extract tgz file' '
        test_cmp b.tar j.tar
 '
 
-test_expect_success GZIP 'remote tar.gz is allowed by default' '
+test_expect_success GZIP,NOT_MINGW 'remote tar.gz is allowed by default' '
        git archive --remote=. --format=tar.gz HEAD >remote.tar.gz &&
        test_cmp j.tgz remote.tar.gz
 '
 
-test_expect_success GZIP 'remote tar.gz can be disabled' '
+test_expect_success GZIP,NOT_MINGW 'remote tar.gz can be disabled' '
        git config tar.tar.gz.remote false &&
        test_must_fail git archive --remote=. --format=tar.gz HEAD \
                >remote.tar.gz
index 9cc0a42ea977e184be7af02e05352da8155c4728..ea6f692bafa9f2c4f81985a50ed79a1c5016b493 100755 (executable)
@@ -86,6 +86,7 @@ test_expect_success 'setup: two scripts for reading pull requests' '
        s/$downstream_url_for_sed/URL/g
        s/for-upstream/BRANCH/g
        s/mnemonic.txt/FILENAME/g
+       s/^version [0-9]/VERSION/
        /^ FILENAME | *[0-9]* [-+]*\$/ b diffstat
        /^AUTHOR ([0-9]*):\$/ b shortlog
        p
@@ -193,8 +194,17 @@ test_expect_success 'pull request format' '
          SUBJECT (DATE)
 
        are available in the git repository at:
+
          URL BRANCH
 
+       for you to fetch changes up to OBJECT_NAME:
+
+         SUBJECT (DATE)
+
+       ----------------------------------------------------------------
+       VERSION
+
+       ----------------------------------------------------------------
        SHORTLOG
 
        DIFFSTAT
index b5ced8483a8fc663eb53b514bbb56df92f217deb..1bc57ac03f9df7e82fab5478b7234ab1435c60e3 100755 (executable)
@@ -28,7 +28,7 @@ test_expect_success setup '
                done
        ) &&
        (
-               git clone --reference=original "file:///$(pwd)/original" one &&
+               git clone --reference=original "file://$(pwd)/original" one &&
                cd one &&
                echo Z >count &&
                git add count &&
index e0af4c4e62c40a563f692361944cc58e2c8e38e2..e88dbd50f3368296a0e0487d7ed1675646ee9594 100755 (executable)
@@ -166,7 +166,7 @@ test_expect_success 'fetch must not resolve short tag name' '
 
 '
 
-test_expect_success 'fetch must not resolve short remote name' '
+test_expect_success 'fetch can now resolve short remote name' '
 
        cd "$D" &&
        git update-ref refs/remotes/six/HEAD HEAD &&
@@ -175,8 +175,7 @@ test_expect_success 'fetch must not resolve short remote name' '
        cd six &&
        git init &&
 
-       test_must_fail git fetch .. six:six
-
+       git fetch .. six:six
 '
 
 test_expect_success 'create bundle 1' '
index 2e0414f6c3d006ac6f06b884a13397c67f6b7df1..a1bc3d53a606bb67eb5b808834c57a53e1b32fbe 100644 (file)
@@ -1,8 +1,8 @@
 # br-branches-default
 754b754407bf032e9a2f9d5a9ad05ca79a6b228f               branch 'master' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index ca2cc1d1b44e3edc8cd42e2e77d0f85658a52195..e3a41ae811fb9957e8ac91b96a5d0c538c0515e1 100644 (file)
@@ -1,9 +1,9 @@
 # br-branches-default-merge
 754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   branch 'master' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b               branch 'three' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 7d947cd80f9cf656024206f1ea31da0d9f10f493..1f60561cb12b37d2c85662476d5e3a8d11c4f1f2 100644 (file)
@@ -1,9 +1,9 @@
 # br-branches-default-merge branches-default
 754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   branch 'master' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b               branch 'three' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index ec39c54b7e242ddbeec76f55b98f555d562aa271..f31e1b3080f3cc0344ba88674d9de1d968cd372f 100644 (file)
@@ -2,9 +2,9 @@
 754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   branch 'master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689               branch 'one' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8               branch 'two' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 6bf42e24b67b526bac49e3cdb287e32513f4a6c4..7060bd9ae59d02f7d4457e90aee06407c30da976 100644 (file)
@@ -2,9 +2,9 @@
 754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   branch 'master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689               branch 'one' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8               branch 'two' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 4a2bf3c95ca474417d1dd54d1ac0bcc02bb5f402..8cbd718936223fd7dec89638d5ad9a4933a37e9d 100644 (file)
@@ -1,8 +1,8 @@
 # br-branches-default branches-default
 754b754407bf032e9a2f9d5a9ad05ca79a6b228f               branch 'master' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 12ac8d20fba1c8a9402b92aa71e2e6797101a042..c98f67052638fd340b4c2069c85536b69e123b5c 100644 (file)
@@ -1,8 +1,8 @@
 # br-branches-one
 8e32a6d901327a23ef831511badce7bf3bf46689               branch 'one' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index b4b3b35ce0e2f46a16b015a74b771eb90ed3ebad..aa1c8a937ea1ab67e519adad0b5e3483c240411f 100644 (file)
@@ -1,9 +1,9 @@
 # br-branches-one-merge
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   branch 'one' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b               branch 'three' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 2ecef384eb7d823104581bfe2b4bd240b449e5df..c93310a730b0dca890d42525148196645a8ca869 100644 (file)
@@ -1,9 +1,9 @@
 # br-branches-one-merge branches-one
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   branch 'one' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b               branch 'three' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 96e3029416b46ab4192d3e4aaa285a02489e4054..97c4b544b8c2c4466ab62759533703896f31ca4c 100644 (file)
@@ -1,9 +1,9 @@
 # br-branches-one-octopus
 8e32a6d901327a23ef831511badce7bf3bf46689               branch 'one' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8               branch 'two' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 55e0bad621cde0c93e6a6fb92dc259c61986aba5..df705f74c7d6e24577ae48f1e783706d7ec939eb 100644 (file)
@@ -1,9 +1,9 @@
 # br-branches-one-octopus branches-one
 8e32a6d901327a23ef831511badce7bf3bf46689               branch 'one' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8               branch 'two' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 281fa09d481a2d04788d5c1b0a67b8f569203ebc..96890e5bd9920bfe3ea27a7e992f689b01badc2f 100644 (file)
@@ -1,8 +1,8 @@
 # br-branches-one branches-one
 8e32a6d901327a23ef831511badce7bf3bf46689               branch 'one' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index e2fa9c8654647e46baa89d24501b050209aefdc1..68fc927263ed582621fe3385770603900e7ce841 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   branch 'one' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   branch 'two' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   branch 'three' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index ec1a7231aa7875df2cebd32411bad4861c233dcd..f6475b717a0d42a8944ab1a9593fe226a519c7a5 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   branch 'one' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   branch 'two' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b               branch 'three' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 54f689151ff1006561309f6f7ca5e3523f8626c4..018bdd752a500295a5f1685ed53d1489fe780bf3 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   branch 'one' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   branch 'two' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b               branch 'three' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 7011dfc18140aade896592c853bec85567d4ccc8..36d0270502637ce0d54b29b3f3c3839c8ca8d50c 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689               branch 'one' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8               branch 'two' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   branch 'three' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index bdad51f87163b51c378aaa1ca9bed8fe4a461af1..6654ad0898dfa7573a0552ec40489fd5c212ca85 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689               branch 'one' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8               branch 'two' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   branch 'three' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 1b237dde6e03b9bb1f4b9ad0b5ab75ae31127b57..b19b0162e1f234965687acb5041c504258d5ab68 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   branch 'one' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   branch 'two' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   branch 'three' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index e75ec2f72b4420cf27bcb959ab83518d93e115b1..946d70ca0718e499d576772059060c5304d1e7f2 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   branch 'one' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   branch 'three' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   branch 'two' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index ce8f739a0d5f53d24d1408e0e39719c0411e3c0d..8bb5e8bc4e3ed113b59c19f08316ffc2785d5209 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   branch 'one' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b               branch 'three' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   branch 'two' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 5817bed8f88fcc11b9d5e67ce0863249339eeb2c..113c08dabe284a2d8a4de2b0a6f9dae7fde87103 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   branch 'one' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b               branch 'three' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   branch 'two' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 938e532db25e684599b39d1c862680a1caf8ea23..9bbd537579fe82441b6ae3cd93b97967b3f97763 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689               branch 'one' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   branch 'three' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8               branch 'two' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index c9225bf6ff060118ae85b5c666085b3a558db16e..4e510437d912057c7c61165cf13e610037d67274 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689               branch 'one' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   branch 'three' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8               branch 'two' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index a6c20f92ce6e708f915b285310a94b7080eab1e3..19daf0cb77e313f013fe89406cd989d0c12f7fd4 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   branch 'one' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   branch 'three' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   branch 'two' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 83534d2ec85e30dee5c32b8d385dd717cf4930a2..ab44bc551969d358c32c6b99e79c5748df2ec669 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   branch 'one' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   branch 'two' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   branch 'three' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index a9064dd65a0e569cc3e7ce5ae2368313f6bfa7ec..7421b2cb8617c8999491089bfd26bba8fec6f808 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   branch 'one' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   branch 'two' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b               branch 'three' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 732a37e4d358f0239687770b28c109051c438070..b6975d38906e721270af011cff37cf64b8ae2313 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   branch 'one' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   branch 'two' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b               branch 'three' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index ecf020d9298e7a031833e9986f2deb787712cb89..76812812eef26415ad84653016b62aa92664eafb 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689               branch 'one' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8               branch 'two' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   branch 'three' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index af7753101140d43e2a592ec37b88d57d53d45bde..4c896cfc1a0d66322ba08bb2c2581625d9fa9019 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689               branch 'one' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8               branch 'two' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   branch 'three' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 51fae567c8765fc6f447d7ee93a9796e022663a5..01e014e6a0219073abdd000bd46915acfa45559b 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   branch 'one' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   branch 'two' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   branch 'three' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 94e6ad31e301a87b52160f2287b54051e27b4e18..09bfcee00f9cae28660fc6be3fcddf5272c4a5b3 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   branch 'one' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   branch 'three' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   branch 'two' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 09362e25af564342ccb5ed9507caa103676aedf6..4b62b01de4b38c37f3c34736851308dd239761b1 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   branch 'one' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b               branch 'three' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   branch 'two' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index e2eabec62e12b29be2b8cd0c8e6d0cc9ad042f4d..7478f1f158877452db84848c987184804758741c 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   branch 'one' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b               branch 'three' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   branch 'two' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index b08e0461954dcedc90df43c03302e3d4257c6f4b..254342058192f04b34c67d763afb4614a952fe0f 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689               branch 'one' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   branch 'three' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8               branch 'two' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index d4d547c84733f0faacc85c88c7b7fa138933e4a6..5ffde9c03c782e95c34f3624ddcbfac581327d4f 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689               branch 'one' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   branch 'three' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8               branch 'two' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 646dbc877008edae3644ceef92fd5bed990eb784..20ba5cb1725d4b97a3bc9ac2c2f5a9abf207d063 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   branch 'one' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   branch 'three' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   branch 'two' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 65ce6d99e2631fd777de10e11b3a58db5859c29a..887ccfc41f57fcf85f10a44deafa08fbd2c4d041 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   branch 'one' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   branch 'three' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   branch 'two' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 8258c808689d883b97867b3d07ca89e08146de12..1669cc4af0e8b3d179bcff9dd850f2f363278005 100644 (file)
@@ -1,7 +1,7 @@
 # br-unconfig --tags ../.git
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index f02bab2fb4a1e07c6128fb899bf42183d1f0965e..74115361ba00984ca2fd174ea2dd686e7ec2d7ae 100644 (file)
@@ -2,7 +2,7 @@
 8e32a6d901327a23ef831511badce7bf3bf46689               branch 'one' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689               tag 'tag-one' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 85de41109ecfb6fd4ac3a1b3b15489b83506a63c..7726983818f81aa230a91d5512b079f2b6b733a5 100644 (file)
@@ -1,7 +1,7 @@
 # br-unconfig ../.git tag tag-one-tree tag tag-three-file
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 0da2337f1b95b2011524b3d047a291747bd80305..7b3750ce5c0136030fd8b50ad87c6b0231f1cffe 100644 (file)
@@ -1,7 +1,7 @@
 # br-unconfig ../.git tag tag-one tag tag-three
 8e32a6d901327a23ef831511badce7bf3bf46689               tag 'tag-one' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b               tag 'tag-three' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899               tag 'tag-three' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index fc7041eefc2150417abc504e25f9d82049b3102e..da30e3c62c269b8a94b29f9edcb4a24d26185463 100644 (file)
@@ -1,8 +1,8 @@
 # br-unconfig branches-default
 754b754407bf032e9a2f9d5a9ad05ca79a6b228f               branch 'master' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index e94cde745b58aeb360e2db064466260f2362cf87..e4614314c54e10b6abc285ad35b385de889b6cf4 100644 (file)
@@ -1,8 +1,8 @@
 # br-unconfig branches-one
 8e32a6d901327a23ef831511badce7bf3bf46689               branch 'one' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 01a283e70d9d10373c363d1fe15b39949bba8d89..ed323c98713c55658906f053517b9543eac7c5e6 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   branch 'one' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   branch 'two' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   branch 'three' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 3a556c5e964785046cc43e9c13351818f436b857..2372ed03c5c506300b233dc983475905c20d2499 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   branch 'one' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   branch 'three' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   branch 'two' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index db216dfa562e894999c565d44d43abb6c6dd562e..6318dd11b4c2d62e89b3be7b32bafaccc18da301 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   branch 'one' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   branch 'two' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   branch 'three' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index aee65c204d1b1468adaee9d41dc5c0a47a3ae999..1d9afad7d841a7d300c7653b19334c35a33bcdf0 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   branch 'one' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   branch 'three' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   branch 'two' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 950fd078db7ccbe27825183cb0236a0dcc45139a..9b29d6720002a3cd7fa19157762d26e908173d52 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   branch 'one' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   branch 'three' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   branch 'two' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 0e59950c7b5e18521b59a17d3aaddc3a314a6f9c..8a7493537b99ac9592fd548300d5332e4163ab77 100644 (file)
@@ -1,7 +1,7 @@
 # master --tags ../.git
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 82868524ca40041b243e146064f4451d6899f3c4..0672d1292f5fab7043842ac142fcdc5474a0cdcb 100644 (file)
@@ -2,7 +2,7 @@
 8e32a6d901327a23ef831511badce7bf3bf46689               branch 'one' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689               tag 'tag-one' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 2e133eff296d291045e86fe6a8cba958106b9aae..0fd737cf81fd852d31346022c7e2b24545079fd2 100644 (file)
@@ -1,7 +1,7 @@
 # master ../.git tag tag-one-tree tag tag-three-file
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 92b18b40ccc883bede4d2067aa4bf7a529d2f059..e488986653714b1af47a2ed11f18eb05283d1d81 100644 (file)
@@ -1,7 +1,7 @@
 # master ../.git tag tag-one tag tag-three
 8e32a6d901327a23ef831511badce7bf3bf46689               tag 'tag-one' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b               tag 'tag-three' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899               tag 'tag-three' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 603d6d23312b6a58d95a685803d8b19f0e0ac4e2..2eedd3bfa4a5f4a14c911cd37e00d40e9b0d1171 100644 (file)
@@ -1,8 +1,8 @@
 # master branches-default
 754b754407bf032e9a2f9d5a9ad05ca79a6b228f               branch 'master' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index fe9bb0b7982951ccf85934e42ff7c9620e2312b4..901ce21d333c8c5a37bcc8953f81f93faf415563 100644 (file)
@@ -1,8 +1,8 @@
 # master branches-one
 8e32a6d901327a23ef831511badce7bf3bf46689               branch 'one' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 4be97c75752571d46aef0283f164abea025a1be8..251c826aa9dea34ce01bdee293b7c35b02bf6228 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   branch 'one' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   branch 'two' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   branch 'three' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index cb0726ff8d7ea9e801497b564b680710c2a273af..27c158e332f291dcde9aa345807c3b077c28dfd7 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   branch 'one' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   branch 'three' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   branch 'two' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 44a1ca84296079356eabc3fd37d04529a3492409..b3cfe6b98b24f9ffb241d8cea37c70123c6f3273 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   branch 'one' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   branch 'two' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   branch 'three' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 724e8db0a533248cab6784696c90db02ca1435f3..118befd1e483cb91eb8a28b6bba362565dcd59d5 100644 (file)
@@ -3,9 +3,9 @@
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   branch 'one' of ../
 0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   branch 'three' of ../
 6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   branch 'two' of ../
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f       not-for-merge   tag 'tag-master' of ../
+6c9dec2b923228c9ff994c6cfe4ae16c12408dc5       not-for-merge   tag 'tag-master' of ../
 8e32a6d901327a23ef831511badce7bf3bf46689       not-for-merge   tag 'tag-one' of ../
 22feea448b023a2d864ef94b013735af34d238ba       not-for-merge   tag 'tag-one-tree' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b       not-for-merge   tag 'tag-three' of ../
+c61a82b60967180544e3c19f819ddbd0c9f89899       not-for-merge   tag 'tag-three' of ../
 0e3b14047d3ee365f4f2a1b673db059c3972589c       not-for-merge   tag 'tag-three-file' of ../
-6134ee8f857693b96ff1cc98d3e2fd62b199e5a8       not-for-merge   tag 'tag-two' of ../
+525b7fb068d59950d185a8779dc957c77eed73ba       not-for-merge   tag 'tag-two' of ../
index 0e5eb678ce6b2f4fad79c39947455e5284313ba4..35304b41e9ce6222f7d713e3d310e47241d8e6e0 100755 (executable)
@@ -94,16 +94,35 @@ test_expect_success '--rebase' '
        test $(git rev-parse HEAD^) = $(git rev-parse copy) &&
        test new = $(git show HEAD:file2)
 '
+test_expect_success 'pull.rebase' '
+       git reset --hard before-rebase &&
+       git config --bool pull.rebase true &&
+       test_when_finished "git config --unset pull.rebase" &&
+       git pull . copy &&
+       test $(git rev-parse HEAD^) = $(git rev-parse copy) &&
+       test new = $(git show HEAD:file2)
+'
 
 test_expect_success 'branch.to-rebase.rebase' '
        git reset --hard before-rebase &&
-       git config branch.to-rebase.rebase 1 &&
+       git config --bool branch.to-rebase.rebase true &&
+       test_when_finished "git config --unset branch.to-rebase.rebase" &&
        git pull . copy &&
-       git config branch.to-rebase.rebase 0 &&
        test $(git rev-parse HEAD^) = $(git rev-parse copy) &&
        test new = $(git show HEAD:file2)
 '
 
+test_expect_success 'branch.to-rebase.rebase should override pull.rebase' '
+       git reset --hard before-rebase &&
+       git config --bool pull.rebase true &&
+       test_when_finished "git config --unset pull.rebase" &&
+       git config --bool branch.to-rebase.rebase false &&
+       test_when_finished "git config --unset branch.to-rebase.rebase" &&
+       git pull . copy &&
+       test $(git rev-parse HEAD^) != $(git rev-parse copy) &&
+       test new = $(git show HEAD:file2)
+'
+
 test_expect_success '--rebase with rebased upstream' '
 
        git remote add -f me . &&
index 895f5595aee9341276e79497b9c4a8736c78e5e7..c4c375ac042bbb7f58998c87d8c9277d2f5004a6 100755 (executable)
@@ -146,4 +146,11 @@ test_expect_success 'cloning with reference being subset of source (-l -s)' \
 
 cd "$base_dir"
 
+test_expect_success 'clone with reference from a tagged repository' '
+       (
+               cd A && git tag -a -m 'tagged' HEAD
+       ) &&
+       git clone --reference=A A I
+'
+
 test_done
index 4956caaf82be8c42ef01a9adae55387e87adaa04..83f7ea59c9b4e05aa200bc4ebd77f0c16bd8ef33 100755 (executable)
@@ -12,7 +12,7 @@ test_description='Test interaction of reset --hard with sequencer
 . ./test-lib.sh
 
 pristine_detach () {
-       git cherry-pick --reset &&
+       git cherry-pick --quit &&
        git checkout -f "$1^0" &&
        git read-tree -u --reset HEAD &&
        git clean -d -f -f -q -x
@@ -41,4 +41,12 @@ test_expect_success 'reset --hard cleans up sequencer state, providing one-level
        test_path_is_missing .git/sequencer-old
 '
 
+test_expect_success 'cherry-pick --abort does not leave sequencer-old dir' '
+       pristine_detach initial &&
+       test_must_fail git cherry-pick base..anotherpick &&
+       git cherry-pick --abort &&
+       test_path_is_missing .git/sequencer &&
+       test_path_is_missing .git/sequencer-old
+'
+
 test_done
index 3008e4e1210900be3bdc2e28dddd681ce8ec3551..5d8c428543bd61a27489af72045b4e1816d240e9 100755 (executable)
@@ -38,8 +38,8 @@ printf '%s\n' '1 X' 2 3 4 '5 X' 6 7 8 '9 X' >result.1-5-9
 >empty
 
 create_merge_msgs () {
-       echo "Merge commit 'c2'" >msg.1-5 &&
-       echo "Merge commit 'c2'; commit 'c3'" >msg.1-5-9 &&
+       echo "Merge tag 'c2'" >msg.1-5 &&
+       echo "Merge tags 'c2' and 'c3'" >msg.1-5-9 &&
        {
                echo "Squashed commit of the following:" &&
                echo &&
@@ -57,7 +57,7 @@ create_merge_msgs () {
        } >squash.1-5-9 &&
        echo >msg.nolog &&
        {
-               echo "* commit 'c3':" &&
+               echo "* tag 'c3':" &&
                echo "  commit 3" &&
                echo
        } >msg.log
@@ -96,7 +96,11 @@ verify_parents () {
 
 verify_mergeheads () {
        printf '%s\n' "$@" >mergehead.expected &&
-       test_cmp mergehead.expected .git/MERGE_HEAD
+       while read sha1 rest
+       do
+               git rev-parse $sha1
+       done <.git/MERGE_HEAD >mergehead.actual &&
+       test_cmp mergehead.expected mergehead.actual
 }
 
 verify_no_mergehead () {
index 9114785ef7c850ae2d393bed3565e13f11339ba0..89619cf44608282efa6d75c2ed93cd3bdc4096fc 100755 (executable)
@@ -11,7 +11,7 @@ create_merge_msgs() {
 
        cp exp.subject exp.log &&
        echo >>exp.log "" &&
-       echo >>exp.log "* commit 'c2':" &&
+       echo >>exp.log "* tag 'c2':" &&
        echo >>exp.log "  c2"
 }
 
index 9225fa6f025cd9586b46f30464a69ccb57ca6b2a..8e7e0a5865d762c1cb859154c2d4735b9bf8722b 100755 (executable)
@@ -35,7 +35,7 @@ test_expect_success 'merge tag' '
        git checkout master &&
        test_commit master-3 &&
        git merge tag-1 &&
-       check_oneline "Merge commit Qtag-1Q"
+       check_oneline "Merge tag Qtag-1Q"
 '
 
 test_expect_success 'ambiguous tag' '
@@ -44,7 +44,7 @@ test_expect_success 'ambiguous tag' '
        git checkout master &&
        test_commit master-4 &&
        git merge ambiguous &&
-       check_oneline "Merge commit QambiguousQ"
+       check_oneline "Merge tag QambiguousQ"
 '
 
 test_expect_success 'remote-tracking branch' '
diff --git a/t/t9805-skip-submit-edit.sh b/t/t9805-skip-submit-edit.sh
new file mode 100755 (executable)
index 0000000..734ccf2
--- /dev/null
@@ -0,0 +1,82 @@
+#!/bin/sh
+
+test_description='git-p4 skipSubmitEdit config variables'
+
+. ./lib-git-p4.sh
+
+test_expect_success 'start p4d' '
+       start_p4d
+'
+
+test_expect_success 'init depot' '
+       (
+               cd "$cli" &&
+               echo file1 >file1 &&
+               p4 add file1 &&
+               p4 submit -d "change 1"
+       )
+'
+
+# this works because EDITOR is set to :
+test_expect_success 'no config, unedited, say yes' '
+       "$GITP4" clone --dest="$git" //depot &&
+       test_when_finished cleanup_git &&
+       (
+               cd "$git" &&
+               echo line >>file1 &&
+               git commit -a -m "change 2" &&
+               echo y | "$GITP4" submit &&
+               p4 changes //depot/... >wc &&
+               test_line_count = 2 wc
+       )
+'
+
+test_expect_success 'no config, unedited, say no' '
+       "$GITP4" clone --dest="$git" //depot &&
+       test_when_finished cleanup_git &&
+       (
+               cd "$git" &&
+               echo line >>file1 &&
+               git commit -a -m "change 3 (not really)" &&
+               printf "bad response\nn\n" | "$GITP4" submit
+               p4 changes //depot/... >wc &&
+               test_line_count = 2 wc
+       )
+'
+
+test_expect_success 'skipSubmitEdit' '
+       "$GITP4" clone --dest="$git" //depot &&
+       test_when_finished cleanup_git &&
+       (
+               cd "$git" &&
+               git config git-p4.skipSubmitEdit true &&
+               # will fail if editor is even invoked
+               git config core.editor /bin/false &&
+               echo line >>file1 &&
+               git commit -a -m "change 3" &&
+               "$GITP4" submit &&
+               p4 changes //depot/... >wc &&
+               test_line_count = 3 wc
+       )
+'
+
+test_expect_success 'skipSubmitEditCheck' '
+       "$GITP4" clone --dest="$git" //depot &&
+       test_when_finished cleanup_git &&
+       (
+               cd "$git" &&
+               git config git-p4.skipSubmitEditCheck true &&
+               echo line >>file1 &&
+               git commit -a -m "change 4" &&
+               "$GITP4" submit &&
+               p4 changes //depot/... >wc &&
+               test_line_count = 4 wc
+       )
+'
+
+
+test_expect_success 'kill p4d' '
+       kill_p4d
+'
+
+test_done
diff --git a/tag.c b/tag.c
index 7d38cc0f4de1c16b5b52725ba7a6a361650a6b41..3aa186df628331e74e8a84d3cc2d313f4518a626 100644 (file)
--- a/tag.c
+++ b/tag.c
@@ -139,6 +139,11 @@ int parse_tag(struct tag *item)
        return ret;
 }
 
+/*
+ * Look at a signed tag object, and return the offset where
+ * the embedded detached signature begins, or the end of the
+ * data when there is no such signature.
+ */
 size_t parse_signature(const char *buf, unsigned long size)
 {
        char *eol;
index b3cc2e4753447d4734ed08a70e3396771257dced..7a51d091b5a6babed91f60b9ff7079308afa4e6f 100644 (file)
@@ -21,8 +21,8 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2,
        sha1 = tree_entry_extract(t1, &path1, &mode1);
        sha2 = tree_entry_extract(t2, &path2, &mode2);
 
-       pathlen1 = tree_entry_len(path1, sha1);
-       pathlen2 = tree_entry_len(path2, sha2);
+       pathlen1 = tree_entry_len(&t1->entry);
+       pathlen2 = tree_entry_len(&t2->entry);
        cmp = base_name_compare(path1, pathlen1, mode1, path2, pathlen2, mode2);
        if (cmp < 0) {
                show_entry(opt, "-", t1, base);
@@ -64,14 +64,14 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2,
 static void show_tree(struct diff_options *opt, const char *prefix,
                      struct tree_desc *desc, struct strbuf *base)
 {
-       int match = 0;
+       enum interesting match = entry_not_interesting;
        for (; desc->size; update_tree_entry(desc)) {
-               if (match != 2) {
+               if (match != all_entries_interesting) {
                        match = tree_entry_interesting(&desc->entry, base, 0,
                                                       &opt->pathspec);
-                       if (match < 0)
+                       if (match == all_entries_not_interesting)
                                break;
-                       if (match == 0)
+                       if (match == entry_not_interesting)
                                continue;
                }
                show_entry(opt, prefix, desc, base);
@@ -85,7 +85,7 @@ static void show_entry(struct diff_options *opt, const char *prefix,
        unsigned mode;
        const char *path;
        const unsigned char *sha1 = tree_entry_extract(desc, &path, &mode);
-       int pathlen = tree_entry_len(path, sha1);
+       int pathlen = tree_entry_len(&desc->entry);
        int old_baselen = base->len;
 
        strbuf_add(base, path, pathlen);
@@ -114,12 +114,13 @@ static void show_entry(struct diff_options *opt, const char *prefix,
 }
 
 static void skip_uninteresting(struct tree_desc *t, struct strbuf *base,
-                              struct diff_options *opt, int *match)
+                              struct diff_options *opt,
+                              enum interesting *match)
 {
        while (t->size) {
                *match = tree_entry_interesting(&t->entry, base, 0, &opt->pathspec);
                if (*match) {
-                       if (*match < 0)
+                       if (*match == all_entries_not_interesting)
                                t->size = 0;
                        break;
                }
@@ -132,7 +133,8 @@ int diff_tree(struct tree_desc *t1, struct tree_desc *t2,
 {
        struct strbuf base;
        int baselen = strlen(base_str);
-       int t1_match = 0, t2_match = 0;
+       enum interesting t1_match = entry_not_interesting;
+       enum interesting t2_match = entry_not_interesting;
 
        /* Enable recursion indefinitely */
        opt->pathspec.recursive = DIFF_OPT_TST(opt, RECURSIVE);
index 418107ec83728473093b43dfe74ab709f312e8a8..f82dba6a1f43bf2a259952a4fd6db94d6335deb7 100644 (file)
@@ -116,7 +116,7 @@ void setup_traverse_info(struct traverse_info *info, const char *base)
 
 char *make_traverse_path(char *path, const struct traverse_info *info, const struct name_entry *n)
 {
-       int len = tree_entry_len(n->path, n->sha1);
+       int len = tree_entry_len(n);
        int pathlen = info->pathlen;
 
        path[pathlen + len] = 0;
@@ -126,7 +126,7 @@ char *make_traverse_path(char *path, const struct traverse_info *info, const str
                        break;
                path[--pathlen] = '/';
                n = &info->name;
-               len = tree_entry_len(n->path, n->sha1);
+               len = tree_entry_len(n);
                info = info->prev;
                pathlen -= len;
        }
@@ -253,7 +253,7 @@ static void extended_entry_extract(struct tree_desc_x *t,
         * The caller wants "first" from this tree, or nothing.
         */
        path = a->path;
-       len = tree_entry_len(a->path, a->sha1);
+       len = tree_entry_len(a);
        switch (check_entry_match(first, first_len, path, len)) {
        case -1:
                entry_clear(a);
@@ -271,7 +271,7 @@ static void extended_entry_extract(struct tree_desc_x *t,
        while (probe.size) {
                entry_extract(&probe, a);
                path = a->path;
-               len = tree_entry_len(a->path, a->sha1);
+               len = tree_entry_len(a);
                switch (check_entry_match(first, first_len, path, len)) {
                case -1:
                        entry_clear(a);
@@ -362,7 +362,7 @@ int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info)
                        e = entry + i;
                        if (!e->path)
                                continue;
-                       len = tree_entry_len(e->path, e->sha1);
+                       len = tree_entry_len(e);
                        if (!first) {
                                first = e->path;
                                first_len = len;
@@ -381,7 +381,7 @@ int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info)
                                /* Cull the ones that are not the earliest */
                                if (!e->path)
                                        continue;
-                               len = tree_entry_len(e->path, e->sha1);
+                               len = tree_entry_len(e);
                                if (name_compare(e->path, len, first, first_len))
                                        entry_clear(e);
                        }
@@ -434,8 +434,8 @@ static int find_tree_entry(struct tree_desc *t, const char *name, unsigned char
                int entrylen, cmp;
 
                sha1 = tree_entry_extract(t, &entry, mode);
+               entrylen = tree_entry_len(&t->entry);
                update_tree_entry(t);
-               entrylen = tree_entry_len(entry, sha1);
                if (entrylen > namelen)
                        continue;
                cmp = memcmp(name, entry, entrylen);
@@ -465,7 +465,6 @@ int get_tree_entry(const unsigned char *tree_sha1, const char *name, unsigned ch
        int retval;
        void *tree;
        unsigned long size;
-       struct tree_desc t;
        unsigned char root[20];
 
        tree = read_object_with_reference(tree_sha1, tree_type, &size, root);
@@ -478,8 +477,13 @@ int get_tree_entry(const unsigned char *tree_sha1, const char *name, unsigned ch
                return 0;
        }
 
-       init_tree_desc(&t, tree, size);
-       retval = find_tree_entry(&t, name, sha1, mode);
+       if (!size) {
+               retval = -1;
+       } else {
+               struct tree_desc t;
+               init_tree_desc(&t, tree, size);
+               retval = find_tree_entry(&t, name, sha1, mode);
+       }
        free(tree);
        return retval;
 }
@@ -573,30 +577,26 @@ static int match_dir_prefix(const char *base,
  *
  * Pre-condition: either baselen == base_offset (i.e. empty path)
  * or base[baselen-1] == '/' (i.e. with trailing slash).
- *
- * Return:
- *  - 2 for "yes, and all subsequent entries will be"
- *  - 1 for yes
- *  - zero for no
- *  - negative for "no, and no subsequent entries will be either"
  */
-int tree_entry_interesting(const struct name_entry *entry,
-                          struct strbuf *base, int base_offset,
-                          const struct pathspec *ps)
+enum interesting tree_entry_interesting(const struct name_entry *entry,
+                                       struct strbuf *base, int base_offset,
+                                       const struct pathspec *ps)
 {
        int i;
        int pathlen, baselen = base->len - base_offset;
-       int never_interesting = ps->has_wildcard ? 0 : -1;
+       int never_interesting = ps->has_wildcard ?
+               entry_not_interesting : all_entries_not_interesting;
 
        if (!ps->nr) {
                if (!ps->recursive || ps->max_depth == -1)
-                       return 2;
-               return !!within_depth(base->buf + base_offset, baselen,
-                                     !!S_ISDIR(entry->mode),
-                                     ps->max_depth);
+                       return all_entries_interesting;
+               return within_depth(base->buf + base_offset, baselen,
+                                   !!S_ISDIR(entry->mode),
+                                   ps->max_depth) ?
+                       entry_interesting : entry_not_interesting;
        }
 
-       pathlen = tree_entry_len(entry->path, entry->sha1);
+       pathlen = tree_entry_len(entry);
 
        for (i = ps->nr - 1; i >= 0; i--) {
                const struct pathspec_item *item = ps->items+i;
@@ -610,12 +610,13 @@ int tree_entry_interesting(const struct name_entry *entry,
                                goto match_wildcards;
 
                        if (!ps->recursive || ps->max_depth == -1)
-                               return 2;
+                               return all_entries_interesting;
 
-                       return !!within_depth(base_str + matchlen + 1,
-                                             baselen - matchlen - 1,
-                                             !!S_ISDIR(entry->mode),
-                                             ps->max_depth);
+                       return within_depth(base_str + matchlen + 1,
+                                           baselen - matchlen - 1,
+                                           !!S_ISDIR(entry->mode),
+                                           ps->max_depth) ?
+                               entry_interesting : entry_not_interesting;
                }
 
                /* Either there must be no base, or the base must match. */
@@ -623,25 +624,25 @@ int tree_entry_interesting(const struct name_entry *entry,
                        if (match_entry(entry, pathlen,
                                        match + baselen, matchlen - baselen,
                                        &never_interesting))
-                               return 1;
+                               return entry_interesting;
 
-                       if (ps->items[i].use_wildcard) {
+                       if (item->use_wildcard) {
                                if (!fnmatch(match + baselen, entry->path, 0))
-                                       return 1;
+                                       return entry_interesting;
 
                                /*
                                 * Match all directories. We'll try to
                                 * match files later on.
                                 */
                                if (ps->recursive && S_ISDIR(entry->mode))
-                                       return 1;
+                                       return entry_interesting;
                        }
 
                        continue;
                }
 
 match_wildcards:
-               if (!ps->items[i].use_wildcard)
+               if (!item->use_wildcard)
                        continue;
 
                /*
@@ -653,7 +654,7 @@ int tree_entry_interesting(const struct name_entry *entry,
 
                if (!fnmatch(match, base->buf + base_offset, 0)) {
                        strbuf_setlen(base, base_offset + baselen);
-                       return 1;
+                       return entry_interesting;
                }
                strbuf_setlen(base, base_offset + baselen);
 
@@ -662,7 +663,7 @@ int tree_entry_interesting(const struct name_entry *entry,
                 * later on.
                 */
                if (ps->recursive && S_ISDIR(entry->mode))
-                       return 1;
+                       return entry_interesting;
        }
        return never_interesting; /* No matches */
 }
index 0089581e1dd55800302799a7381d4a7ad01bd79d..2bf0db9814a5c9f77fe00c97fa4f723986a7aac1 100644 (file)
@@ -20,9 +20,9 @@ static inline const unsigned char *tree_entry_extract(struct tree_desc *desc, co
        return desc->entry.sha1;
 }
 
-static inline int tree_entry_len(const char *name, const unsigned char *sha1)
+static inline int tree_entry_len(const struct name_entry *ne)
 {
-       return (const char *)sha1 - name - 1;
+       return (const char *)ne->sha1 - ne->path - 1;
 }
 
 void update_tree_entry(struct tree_desc *);
@@ -58,9 +58,19 @@ extern void setup_traverse_info(struct traverse_info *info, const char *base);
 
 static inline int traverse_path_len(const struct traverse_info *info, const struct name_entry *n)
 {
-       return info->pathlen + tree_entry_len(n->path, n->sha1);
+       return info->pathlen + tree_entry_len(n);
 }
 
-extern int tree_entry_interesting(const struct name_entry *, struct strbuf *, int, const struct pathspec *ps);
+/* in general, positive means "kind of interesting" */
+enum interesting {
+       all_entries_not_interesting = -1, /* no, and no subsequent entries will be either */
+       entry_not_interesting = 0,
+       entry_interesting = 1,
+       all_entries_interesting = 2 /* yes, and all subsequent entries will be */
+};
+
+extern enum interesting tree_entry_interesting(const struct name_entry *,
+                                              struct strbuf *, int,
+                                              const struct pathspec *ps);
 
 #endif
diff --git a/tree.c b/tree.c
index 698ecf7af13871cf9639e969f368ba5d7b2e940a..676e9f710ca8d5a568e0c6ea2fa88132da81b48c 100644 (file)
--- a/tree.c
+++ b/tree.c
@@ -52,7 +52,8 @@ static int read_tree_1(struct tree *tree, struct strbuf *base,
        struct tree_desc desc;
        struct name_entry entry;
        unsigned char sha1[20];
-       int len, retval = 0, oldlen = base->len;
+       int len, oldlen = base->len;
+       enum interesting retval = entry_not_interesting;
 
        if (parse_tree(tree))
                return -1;
@@ -60,11 +61,11 @@ static int read_tree_1(struct tree *tree, struct strbuf *base,
        init_tree_desc(&desc, tree->buffer, tree->size);
 
        while (tree_entry(&desc, &entry)) {
-               if (retval != 2) {
+               if (retval != all_entries_interesting) {
                        retval = tree_entry_interesting(&entry, base, 0, pathspec);
-                       if (retval < 0)
+                       if (retval == all_entries_not_interesting)
                                break;
-                       if (retval == 0)
+                       if (retval == entry_not_interesting)
                                continue;
                }
 
@@ -99,7 +100,7 @@ static int read_tree_1(struct tree *tree, struct strbuf *base,
                else
                        continue;
 
-               len = tree_entry_len(entry.path, entry.sha1);
+               len = tree_entry_len(&entry);
                strbuf_add(base, entry.path, len);
                strbuf_addch(base, '/');
                retval = read_tree_1(lookup_tree(sha1),
index 8282f5e5f6c615460e1c340d66e395c2d57aef73..7c9ecf665d062d79e9208875d9bf2577e98f4fb2 100644 (file)
@@ -446,7 +446,7 @@ static int traverse_trees_recursive(int n, unsigned long dirmask,
        newinfo.prev = info;
        newinfo.pathspec = info->pathspec;
        newinfo.name = *p;
-       newinfo.pathlen += tree_entry_len(p->path, p->sha1) + 1;
+       newinfo.pathlen += tree_entry_len(p) + 1;
        newinfo.conflicts |= df_conflicts;
 
        for (i = 0; i < n; i++, dirmask >>= 1) {
@@ -495,7 +495,7 @@ static int do_compare_entry(const struct cache_entry *ce, const struct traverse_
        ce_len -= pathlen;
        ce_name = ce->name + pathlen;
 
-       len = tree_entry_len(n->path, n->sha1);
+       len = tree_entry_len(n);
        return df_name_compare(ce_name, ce_len, S_IFREG, n->path, len, n->mode);
 }
 
@@ -626,7 +626,7 @@ static int find_cache_pos(struct traverse_info *info,
        struct unpack_trees_options *o = info->data;
        struct index_state *index = o->src_index;
        int pfxlen = info->pathlen;
-       int p_len = tree_entry_len(p->path, p->sha1);
+       int p_len = tree_entry_len(p);
 
        for (pos = o->cache_bottom; pos < index->cache_nr; pos++) {
                struct cache_entry *ce = index->cache[pos];
index bf553ad91b55de8a762d56a6ffc6c86e959e878c..7c983c14ff2f4bc2aac6e632ccf982ea9589c6e3 100644 (file)
@@ -37,6 +37,9 @@ PATTERNS("java",
         "|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?"
         "|[-+*/<>%&^|=!]="
         "|--|\\+\\+|<<=?|>>>?=?|&&|\\|\\|"),
+PATTERNS("matlab",
+        "^[[:space:]]*((classdef|function)[[:space:]].*)$|^%%[[:space:]].*$",
+        "[a-zA-Z_][a-zA-Z0-9_]*|[-+0-9.e]+|[=~<>]=|\\.[*/\\^']|\\|\\||&&"),
 PATTERNS("objc",
         /* Negate C statements that can look like functions */
         "!^[ \t]*(do|for|if|else|return|switch|while)\n"