Merge branch 'jn/branch-move-to-self'
authorJunio C Hamano <gitster@pobox.com>
Wed, 14 Dec 2011 06:53:08 +0000 (22:53 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 14 Dec 2011 06:53:08 +0000 (22:53 -0800)
* jn/branch-move-to-self:
Allow checkout -B <current-branch> to update the current branch
branch: allow a no-op "branch -M <current-branch> HEAD"

207 files changed:
Documentation/RelNotes/1.7.6.5.txt [new file with mode: 0644]
Documentation/RelNotes/1.7.7.5.txt [new file with mode: 0644]
Documentation/RelNotes/1.7.8.1.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-commit-tree.txt
Documentation/git-fsck.txt
Documentation/git-pull.txt
Documentation/git-reset.txt
Documentation/git-symbolic-ref.txt
Documentation/git.txt
Documentation/gitattributes.txt
Documentation/merge-options.txt
GIT-VERSION-GEN
Makefile
RelNotes
archive.c
branch.c
branch.h
builtin.h
builtin/apply.c
builtin/blame.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/notes.c
builtin/pack-objects.c
builtin/prune.c
builtin/receive-pack.c
builtin/reflog.c
builtin/remote.c
builtin/replace.c
builtin/revert.c
builtin/show-ref.c
builtin/stripspace.c
builtin/tag.c
builtin/verify-tag.c
bundle.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/completion/git-completion.bash
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-gui/.gitattributes
git-gui/GIT-VERSION-GEN
git-gui/git-gui.sh
git-gui/lib/blame.tcl
git-gui/lib/browser.tcl
git-gui/lib/choose_rev.tcl
git-gui/lib/class.tcl
git-gui/lib/commit.tcl
git-gui/lib/diff.tcl
git-gui/lib/index.tcl
git-gui/lib/line.tcl
git-gui/lib/option.tcl
git-gui/lib/search.tcl
git-gui/lib/sshkey.tcl
git-gui/lib/themed.tcl
git-gui/lib/tools.tcl
git-gui/lib/transport.tcl
git-pull.sh
git-request-pull.sh
git-svn.perl
gitweb/gitweb.perl
gitweb/static/gitweb.css
gpg-interface.c [new file with mode: 0644]
gpg-interface.h [new file with mode: 0644]
http.c
http.h
imap-send.c
list-objects.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
reflog-walk.c
refs.c
remote.c
sha1_file.c
strbuf.c
strbuf.h
submodule.c
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/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/t7106-reset-sequence.sh
t/t7600-merge.sh
t/t7604-merge-custom-message.sh
t/t7608-merge-messages.sh
t/t9500-gitweb-standalone-no-errors.sh
t/t9805-skip-submit-edit.sh [new file with mode: 0755]
t/t9807-submit.sh [new file with mode: 0755]
t/t9808-chdir.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.6.5.txt b/Documentation/RelNotes/1.7.6.5.txt
new file mode 100644 (file)
index 0000000..6713132
--- /dev/null
@@ -0,0 +1,26 @@
+Git v1.7.6.5 Release Notes
+==========================
+
+Fixes since v1.7.6.4
+--------------------
+
+ * The date parser did not accept timezone designators that lack minutes
+   part and also has a colon between "hh:mm".
+
+ * After fetching from a remote that has very long refname, the reporting
+   output could have corrupted by overrunning a static buffer.
+
+ * "git mergetool" did not use its arguments as pathspec, but as a path to
+   the file that may not even have any conflict.
+
+ * "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.
+
+ * "git remote rename $a $b" were not careful to match the remote name
+   against $a (i.e. source side of the remote nickname).
+
+ * "gitweb" used to produce a non-working link while showing the contents
+   of a blob, when JavaScript actions are enabled.
+
+Also contains minor fixes and documentation updates.
diff --git a/Documentation/RelNotes/1.7.7.5.txt b/Documentation/RelNotes/1.7.7.5.txt
new file mode 100644 (file)
index 0000000..7b09319
--- /dev/null
@@ -0,0 +1,14 @@
+Git v1.7.7.5 Release Notes
+==========================
+
+Fixes since v1.7.7.4
+--------------------
+
+ * After fetching from a remote that has very long refname, the reporting
+   output could have corrupted by overrunning a static buffer.
+
+ * "git checkout" and "git merge" treated in-tree .gitignore and exclude
+   file in $GIT_DIR/info/ directory inconsistently when deciding which
+   untracked files are ignored and expendable.
+
+Also contains minor fixes and documentation updates.
diff --git a/Documentation/RelNotes/1.7.8.1.txt b/Documentation/RelNotes/1.7.8.1.txt
new file mode 100644 (file)
index 0000000..0e8bd9f
--- /dev/null
@@ -0,0 +1,17 @@
+Git v1.7.8.1 Release Notes
+==========================
+
+Fixes since v1.7.8.1
+--------------------
+
+ * In some codepaths (notably, checkout and merge), the ignore patterns
+   recorded in $GIT_DIR/info/exclude were not honored. They now are.
+
+ * After fetching from a remote that has very long refname, the reporting
+   output could have corrupted by overrunning a static buffer.
+
+ * "git checkout" and "git merge" treated in-tree .gitignore and exclude
+   file in $GIT_DIR/info/ directory inconsistently when deciding which
+   untracked files are ignored and expendable.
+
+Also contains minor fixes and documentation updates.
index d9da586972620cf10157bc55cc24d6c40434ff6f..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
 --------------------
@@ -159,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-rc3-16-g9e9ab40
-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..258ab7a
--- /dev/null
@@ -0,0 +1,62 @@
+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.
+
+ * "git pull" can be used to fetch and merge an annotated/signed tag,
+   instead of the tip of a topic branch. The GPG signature from the
+   signed tag is recorded in the resulting merge commit for later
+   auditing.
+
+ * "git branch --edit-description" can be used to add descriptive text
+   to explain what a topic branch is about.
+
+ * "git fmt-merge-msg" learned to take the branch description into
+   account when preparing a merge summary that "git merge" records
+   when merging a local branch.
+
+ * "git request-pull" has been updated to convey more information
+   useful for integrators to decide if a topic is worth merging and
+   what is pulled is indeed what the requestor asked to pull,
+   including:
+
+   - the tip of the branch being requested to be merged;
+   - the branch description describing what the topic is about;
+   - the contents of the annotated tag, when requesting to pull a tag.
+
+ * "git pull" learned to notice 'pull.rebase' configuration variable,
+   which serves as a global fallback for setting 'branch.<name>.rebase'
+   configuration variable per branch.
+
+
+Also contains minor 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).
+
+
+--
+exec >/var/tmp/1
+O=v1.7.8-162-gd2c7807
+echo O=$(git describe master)
+git log --first-parent --oneline --reverse ^$O master
+echo
+git shortlog --no-merges ^$O ^maint master
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 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 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 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..da7d48787e7a00e7e14f9d9a0bf236ffe088bd8b 100644 (file)
@@ -44,15 +44,25 @@ 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.7.1/git.html[documentation for release 1.7.7.1]
+* 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.5/git.html[documentation for release 1.7.7.5]
+
+* release notes for
+  link:RelNotes/1.7.7.5.txt[1.7.7.5],
+  link:RelNotes/1.7.7.4.txt[1.7.7.4],
+  link:RelNotes/1.7.7.3.txt[1.7.7.3],
+  link:RelNotes/1.7.7.2.txt[1.7.7.2],
   link:RelNotes/1.7.7.1.txt[1.7.7.1],
   link:RelNotes/1.7.7.txt[1.7.7].
 
-* link:v1.7.6.4/git.html[documentation for release 1.7.6.4]
+* link:v1.7.6.5/git.html[documentation for release 1.7.6.5]
 
 * release notes for
+  link:RelNotes/1.7.6.5.txt[1.7.6.5],
   link:RelNotes/1.7.6.4.txt[1.7.6.4],
   link:RelNotes/1.7.6.3.txt[1.7.6.3],
   link:RelNotes/1.7.6.2.txt[1.7.6.2],
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 6fbd7cd27761b3de5e8a3af0cafcae5acae98d51..e18a30a16a6bd671290ac466745c218fed669755 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v1.7.8-rc3
+DEF_VER=v1.7.8.GIT
 
 LF='
 '
index b1c80a678b5fdb80ec71f0a1ad567a384feba4e8..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.
@@ -532,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
@@ -628,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
@@ -1478,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
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 2ae740a71e6d43ee81afdeddcb53f983f10a8fff..164bbd014a82feac48886db6f27ba85d61a059ac 100644 (file)
--- a/archive.c
+++ b/archive.c
@@ -247,7 +247,8 @@ static void parse_pathspec_arg(const char **pathspec,
 }
 
 static void parse_treeish_arg(const char **argv,
-               struct archiver_args *ar_args, const char *prefix)
+               struct archiver_args *ar_args, const char *prefix,
+               int remote)
 {
        const char *name = argv[0];
        const unsigned char *commit_sha1;
@@ -256,8 +257,17 @@ static void parse_treeish_arg(const char **argv,
        const struct commit *commit;
        unsigned char sha1[20];
 
-       if (get_sha1(name, sha1))
-               die("Not a valid object name");
+       /* Remotes are only allowed to fetch actual refs */
+       if (remote) {
+               char *ref = NULL;
+               if (!dwim_ref(name, strlen(name), sha1, &ref))
+                       die("no such ref: %s", name);
+               free(ref);
+       }
+       else {
+               if (get_sha1(name, sha1))
+                       die("Not a valid object name");
+       }
 
        commit = lookup_commit_reference_gently(sha1, 1);
        if (commit) {
@@ -414,7 +424,7 @@ int write_archive(int argc, const char **argv, const char *prefix,
                setup_git_directory();
        }
 
-       parse_treeish_arg(argv, &args, prefix);
+       parse_treeish_arg(argv, &args, prefix, remote);
        parse_pathspec_arg(argv + 1, &args);
 
        return ar->write_archive(ar, &args);
index f85c438284d6b810617595971d7e3ec2e79e3120..a715a1174982970943ed2c4fc1c2ab4906699fdc 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)
 {
index e125ff4ca89a87fadb03b3d8272b44ab33640c72..b99c5a369e31a85d1fff822460e69a79d8c6102b 100644 (file)
--- a/branch.h
+++ b/branch.h
@@ -47,4 +47,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 80febbe420db1c75bbcf7eda6a733e7e66549790..5a67c202f06abeaa90a7547d78b536f7f2b9db24 100644 (file)
@@ -1598,7 +1598,7 @@ static const char *format_time(unsigned long time, const char *tz_str,
        int tz;
 
        if (show_raw_time) {
-               sprintf(time_buf, "%lu %s", time, tz_str);
+               snprintf(time_buf, sizeof(time_buf), "%lu %s", time, tz_str);
        }
        else {
                tz = atoi(tz_str);
index 823789fc95f609ca5a763be545f3963c2fa5a1ec..465ff6a513f3e314d4a526b6f8ee9f7a7c7b43f4 100644 (file)
@@ -115,8 +115,10 @@ static int branch_merged(int kind, const char *name,
                    branch->merge[0] &&
                    branch->merge[0]->dst &&
                    (reference_name =
-                    resolve_ref(branch->merge[0]->dst, sha1, 1, NULL)) != NULL)
+                    resolve_ref(branch->merge[0]->dst, sha1, 1, NULL)) != NULL) {
+                       reference_name = xstrdup(reference_name);
                        reference_rev = lookup_commit_reference(sha1);
+               }
        }
        if (!reference_rev)
                reference_rev = head_rev;
@@ -141,6 +143,7 @@ static int branch_merged(int kind, const char *name,
                                "         '%s', even though it is merged to HEAD."),
                                name, reference_name);
        }
+       free((char *)reference_name);
        return merged;
 }
 
@@ -186,7 +189,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds)
                free(name);
 
                name = xstrdup(mkpath(fmt, bname.buf));
-               if (!resolve_ref(name, sha1, 1, NULL)) {
+               if (read_ref(name, sha1)) {
                        error(_("%sbranch '%s' not found."),
                                        remote, bname.buf);
                        ret = 1;
@@ -565,7 +568,6 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru
 static void rename_branch(const char *oldname, const char *newname, int force)
 {
        struct strbuf oldref = STRBUF_INIT, newref = STRBUF_INIT, logmsg = STRBUF_INIT;
-       unsigned char sha1[20];
        struct strbuf oldsection = STRBUF_INIT, newsection = STRBUF_INIT;
        int recovery = 0;
        int clobber_head_ok;
@@ -578,7 +580,7 @@ static void rename_branch(const char *oldname, const char *newname, int force)
                 * Bad name --- this could be an attempt to rename a
                 * ref that we used to allow to be created by accident.
                 */
-               if (resolve_ref(oldref.buf, sha1, 1, NULL))
+               if (ref_exists(oldref.buf))
                        recovery = 1;
                else
                        die(_("Invalid branch name: '%s'"), oldname);
@@ -630,11 +632,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;
@@ -673,6 +713,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,
@@ -712,7 +754,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)
@@ -726,14 +768,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 ca00a8538ae2e49458046a41aa48f3285a9b6de9..3f5d9b629a515d1531ff801fabdb9a72246d5d5c 100644 (file)
@@ -288,7 +288,7 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec,
            commit_locked_index(lock_file))
                die(_("unable to write new index file"));
 
-       resolve_ref("HEAD", rev, 0, &flag);
+       read_ref_full("HEAD", rev, 0, &flag);
        head = lookup_commit_reference_gently(rev, 1);
 
        errs |= post_checkout_hook(head, head, 0);
@@ -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);
@@ -705,7 +705,9 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
        unsigned char rev[20];
        int flag;
        memset(&old, 0, sizeof(old));
-       old.path = xstrdup(resolve_ref("HEAD", rev, 0, &flag));
+       old.path = resolve_ref("HEAD", rev, 0, &flag);
+       if (old.path)
+               old.path = xstrdup(old.path);
        old.commit = lookup_commit_reference_gently(rev, 1);
        if (!(flag & REF_ISSYMREF)) {
                free((char *)old.path);
@@ -872,7 +874,7 @@ static int parse_branchname_arg(int argc, const char **argv,
        setup_branch_path(new);
 
        if (!check_refname_format(new->path, 0) &&
-           resolve_ref(new->path, branch_rev, 1, NULL))
+           !read_ref(new->path, branch_rev))
                hashcpy(rev, branch_rev);
        else
                new->path = NULL; /* not an existing branch */
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 8f2bebecf313a0e4b742f9327ec178c7e3547dd2..e36e9adf87d76002784eb26107c25e5d91683229 100644 (file)
@@ -1259,7 +1259,7 @@ static void print_summary(const char *prefix, const unsigned char *sha1,
        struct commit *commit;
        struct strbuf format = STRBUF_INIT;
        unsigned char junk_sha1[20];
-       const char *head = resolve_ref("HEAD", junk_sha1, 0, NULL);
+       const char *head;
        struct pretty_print_context pctx = {0};
        struct strbuf author_ident = STRBUF_INIT;
        struct strbuf committer_ident = STRBUF_INIT;
@@ -1304,6 +1304,7 @@ static void print_summary(const char *prefix, const unsigned char *sha1,
        rev.diffopt.break_opt = 0;
        diff_setup_done(&rev.diffopt);
 
+       head = resolve_ref("HEAD", junk_sha1, 0, NULL);
        printf("[%s%s ",
                !prefixcmp(head, "refs/heads/") ?
                        head + 11 :
@@ -1382,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);
@@ -1425,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)
@@ -1436,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);
@@ -1483,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
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..33ad3aad2c99116a237d7e7d11dab22fcf4295b1 100644 (file)
@@ -240,23 +240,23 @@ static int s_update_ref(const char *action,
 
 static int update_local_ref(struct ref *ref,
                            const char *remote,
-                           char *display)
+                           struct strbuf *display)
 {
        struct commit *current = NULL, *updated;
        enum object_type type;
        struct branch *current_branch = branch_get(NULL);
        const char *pretty_ref = prettify_refname(ref->name);
 
-       *display = 0;
        type = sha1_object_info(ref->new_sha1, NULL);
        if (type < 0)
                die(_("object %s not found"), sha1_to_hex(ref->new_sha1));
 
        if (!hashcmp(ref->old_sha1, ref->new_sha1)) {
                if (verbosity > 0)
-                       sprintf(display, "= %-*s %-*s -> %s", TRANSPORT_SUMMARY_WIDTH,
-                               _("[up to date]"), REFCOL_WIDTH, remote,
-                               pretty_ref);
+                       strbuf_addf(display, "= %-*s %-*s -> %s",
+                                   TRANSPORT_SUMMARY_WIDTH,
+                                   _("[up to date]"), REFCOL_WIDTH,
+                                   remote, pretty_ref);
                return 0;
        }
 
@@ -268,9 +268,10 @@ static int update_local_ref(struct ref *ref,
                 * If this is the head, and it's not okay to update
                 * the head, and the old value of the head isn't empty...
                 */
-               sprintf(display, _("! %-*s %-*s -> %s  (can't fetch in current branch)"),
-                       TRANSPORT_SUMMARY_WIDTH, _("[rejected]"), REFCOL_WIDTH, remote,
-                       pretty_ref);
+               strbuf_addf(display,
+                           _("! %-*s %-*s -> %s  (can't fetch in current branch)"),
+                           TRANSPORT_SUMMARY_WIDTH, _("[rejected]"),
+                           REFCOL_WIDTH, remote, pretty_ref);
                return 1;
        }
 
@@ -278,9 +279,11 @@ static int update_local_ref(struct ref *ref,
            !prefixcmp(ref->name, "refs/tags/")) {
                int r;
                r = s_update_ref("updating tag", ref, 0);
-               sprintf(display, "%c %-*s %-*s -> %s%s", r ? '!' : '-',
-                       TRANSPORT_SUMMARY_WIDTH, _("[tag update]"), REFCOL_WIDTH, remote,
-                       pretty_ref, r ? _("  (unable to update local ref)") : "");
+               strbuf_addf(display, "%c %-*s %-*s -> %s%s",
+                           r ? '!' : '-',
+                           TRANSPORT_SUMMARY_WIDTH, _("[tag update]"),
+                           REFCOL_WIDTH, remote, pretty_ref,
+                           r ? _("  (unable to update local ref)") : "");
                return r;
        }
 
@@ -303,9 +306,11 @@ static int update_local_ref(struct ref *ref,
                }
 
                r = s_update_ref(msg, ref, 0);
-               sprintf(display, "%c %-*s %-*s -> %s%s", r ? '!' : '*',
-                       TRANSPORT_SUMMARY_WIDTH, what, REFCOL_WIDTH, remote, pretty_ref,
-                       r ? _("  (unable to update local ref)") : "");
+               strbuf_addf(display, "%c %-*s %-*s -> %s%s",
+                           r ? '!' : '*',
+                           TRANSPORT_SUMMARY_WIDTH, what,
+                           REFCOL_WIDTH, remote, pretty_ref,
+                           r ? _("  (unable to update local ref)") : "");
                return r;
        }
 
@@ -319,9 +324,11 @@ static int update_local_ref(struct ref *ref,
                    (recurse_submodules != RECURSE_SUBMODULES_ON))
                        check_for_new_submodule_commits(ref->new_sha1);
                r = s_update_ref("fast-forward", ref, 1);
-               sprintf(display, "%c %-*s %-*s -> %s%s", r ? '!' : ' ',
-                       TRANSPORT_SUMMARY_WIDTH, quickref, REFCOL_WIDTH, remote,
-                       pretty_ref, r ? _("  (unable to update local ref)") : "");
+               strbuf_addf(display, "%c %-*s %-*s -> %s%s",
+                           r ? '!' : ' ',
+                           TRANSPORT_SUMMARY_WIDTH, quickref,
+                           REFCOL_WIDTH, remote, pretty_ref,
+                           r ? _("  (unable to update local ref)") : "");
                return r;
        } else if (force || ref->force) {
                char quickref[84];
@@ -333,15 +340,17 @@ static int update_local_ref(struct ref *ref,
                    (recurse_submodules != RECURSE_SUBMODULES_ON))
                        check_for_new_submodule_commits(ref->new_sha1);
                r = s_update_ref("forced-update", ref, 1);
-               sprintf(display, "%c %-*s %-*s -> %s  (%s)", r ? '!' : '+',
-                       TRANSPORT_SUMMARY_WIDTH, quickref, REFCOL_WIDTH, remote,
-                       pretty_ref,
-                       r ? _("unable to update local ref") : _("forced update"));
+               strbuf_addf(display, "%c %-*s %-*s -> %s  (%s)",
+                           r ? '!' : '+',
+                           TRANSPORT_SUMMARY_WIDTH, quickref,
+                           REFCOL_WIDTH, remote, pretty_ref,
+                           r ? _("unable to update local ref") : _("forced update"));
                return r;
        } else {
-               sprintf(display, "! %-*s %-*s -> %s  %s",
-                       TRANSPORT_SUMMARY_WIDTH, _("[rejected]"), REFCOL_WIDTH, remote,
-                       pretty_ref, _("(non-fast-forward)"));
+               strbuf_addf(display, "! %-*s %-*s -> %s  %s",
+                           TRANSPORT_SUMMARY_WIDTH, _("[rejected]"),
+                           REFCOL_WIDTH, remote, pretty_ref,
+                           _("(non-fast-forward)"));
                return 1;
        }
 }
@@ -363,8 +372,8 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
 {
        FILE *fp;
        struct commit *commit;
-       int url_len, i, note_len, shown_url = 0, rc = 0;
-       char note[1024];
+       int url_len, i, shown_url = 0, rc = 0;
+       struct strbuf note = STRBUF_INIT;
        const char *what, *kind;
        struct ref *rm;
        char *url, *filename = dry_run ? "/dev/null" : git_path("FETCH_HEAD");
@@ -427,19 +436,16 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
                if (4 < i && !strncmp(".git", url + i - 3, 4))
                        url_len = i - 3;
 
-               note_len = 0;
+               strbuf_reset(&note);
                if (*what) {
                        if (*kind)
-                               note_len += sprintf(note + note_len, "%s ",
-                                                   kind);
-                       note_len += sprintf(note + note_len, "'%s' of ", what);
+                               strbuf_addf(&note, "%s ", kind);
+                       strbuf_addf(&note, "'%s' of ", what);
                }
-               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);
+                       note.buf);
                for (i = 0; i < url_len; ++i)
                        if ('\n' == url[i])
                                fputs("\\n", fp);
@@ -447,21 +453,24 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
                                fputc(url[i], fp);
                fputc('\n', fp);
 
+               strbuf_reset(&note);
                if (ref) {
-                       rc |= update_local_ref(ref, what, note);
+                       rc |= update_local_ref(ref, what, &note);
                        free(ref);
                } else
-                       sprintf(note, "* %-*s %-*s -> FETCH_HEAD",
-                               TRANSPORT_SUMMARY_WIDTH, *kind ? kind : "branch",
-                                REFCOL_WIDTH, *what ? what : "HEAD");
-               if (*note) {
+                       strbuf_addf(&note, "* %-*s %-*s -> FETCH_HEAD",
+                                   TRANSPORT_SUMMARY_WIDTH,
+                                   *kind ? kind : "branch",
+                                   REFCOL_WIDTH,
+                                   *what ? what : "HEAD");
+               if (note.len) {
                        if (verbosity >= 0 && !shown_url) {
                                fprintf(stderr, _("From %.*s\n"),
                                                url_len, url);
                                shown_url = 1;
                        }
                        if (verbosity >= 0)
-                               fprintf(stderr, " %s\n", note);
+                               fprintf(stderr, " %s\n", note.buf);
                }
        }
 
@@ -471,6 +480,7 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
                      "branches"), remote_name);
 
  abort:
+       strbuf_release(&note);
        free(url);
        fclose(fp);
        return rc;
index 7e2f22589dcb14d5ba95ce1331ef816a458533d0..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;
@@ -268,6 +379,7 @@ static int do_fmt_merge_msg(int merge_title, struct strbuf *in,
                die("No current branch");
        if (!prefixcmp(current_branch, "refs/heads/"))
                current_branch += 11;
+       current_branch = xstrdup(current_branch);
 
        /* get a line */
        while (pos < in->len) {
@@ -283,13 +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)
-               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;
 
@@ -303,21 +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);
        }
-       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);
+       strbuf_complete_line(out);
+       free((char *)current_branch);
+       return 0;
 }
 
 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",
@@ -335,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");
@@ -361,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 2870a6af6fbc868455f2961483cfbfdb065a1a14..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;
@@ -408,21 +409,11 @@ 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;
-       unsigned char branch_head[20], buf_sha[20];
+       struct commit *remote_head;
+       unsigned char branch_head[20];
        struct strbuf buf = STRBUF_INIT;
        struct strbuf bname = STRBUF_INIT;
        const char *ptr;
@@ -433,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);
 
@@ -443,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);
@@ -481,10 +477,10 @@ static void merge_name(const char *remote, struct strbuf *msg)
                strbuf_addstr(&truname, "refs/heads/");
                strbuf_addstr(&truname, remote);
                strbuf_setlen(&truname, truname.len - len);
-               if (resolve_ref(truname.buf, buf_sha, 1, NULL)) {
+               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);
@@ -514,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);
@@ -542,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")) {
@@ -558,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;
@@ -579,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);
 }
 
@@ -718,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);
@@ -775,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;
@@ -1058,9 +1051,16 @@ static void write_merge_state(void)
        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));
+       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)
@@ -1091,7 +1091,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
        struct commit *head_commit;
        struct strbuf buf = STRBUF_INIT;
        const char *head_arg;
-       int flag, i;
+       int flag, i, ret = 0;
        int best_cnt = -1, merge_was_ok = 0, automerge_was_ok = 0;
        struct commit_list *common = NULL;
        const char *best_strategy = NULL, *wt_strategy = NULL;
@@ -1105,8 +1105,11 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
         * current branch.
         */
        branch = resolve_ref("HEAD", head_sha1, 0, &flag);
-       if (branch && !prefixcmp(branch, "refs/heads/"))
-               branch += 11;
+       if (branch) {
+               if (!prefixcmp(branch, "refs/heads/"))
+                       branch += 11;
+               branch = xstrdup(branch);
+       }
        if (!branch || is_null_sha1(head_sha1))
                head_commit = NULL;
        else
@@ -1118,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;
@@ -1130,7 +1135,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
                        die(_("There is no merge to abort (MERGE_HEAD missing)."));
 
                /* Invoke 'git reset --merge' */
-               return cmd_reset(nargc, nargv, prefix);
+               ret = cmd_reset(nargc, nargv, prefix);
+               goto done;
        }
 
        if (read_cache_unmerged())
@@ -1169,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)
@@ -1194,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.
@@ -1208,13 +1217,13 @@ 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);
-               return 0;
+               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;
 
@@ -1222,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);
                }
@@ -1251,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) {
@@ -1301,13 +1312,13 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
                 * but first the most common case of merging one remote.
                 */
                finish_up_to_date("Already up-to-date.");
-               return 0;
+               goto done;
        } else if (allow_fast_forward && !remoteheads->next &&
                        !common->next &&
                        !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));
@@ -1321,16 +1332,21 @@ 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)
-                       return 1;
+               commit = remoteheads->item;
+               if (!commit) {
+                       ret = 1;
+                       goto done;
+               }
 
-               if (checkout_fast_forward(head_commit->object.sha1, remoteheads->item->object.sha1))
-                       return 1;
+               if (checkout_fast_forward(head_commit->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();
-               return 0;
+               goto done;
        } else if (!remoteheads->next && common->next)
                ;
                /*
@@ -1348,8 +1364,11 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
                        git_committer_info(IDENT_ERROR_ON_NO_NAME);
                        printf(_("Trying really trivial in-index merge...\n"));
                        if (!read_tree_trivial(common->item->object.sha1,
-                                       head_commit->object.sha1, remoteheads->item->object.sha1))
-                               return merge_trivial(head_commit);
+                                              head_commit->object.sha1,
+                                              remoteheads->item->object.sha1)) {
+                               ret = merge_trivial(head_commit);
+                               goto done;
+                       }
                        printf(_("Nope.\n"));
                }
        } else {
@@ -1377,7 +1396,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
                }
                if (up_to_date) {
                        finish_up_to_date("Already up-to-date. Yeeah!");
-                       return 0;
+                       goto done;
                }
        }
 
@@ -1459,9 +1478,11 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
         * If we have a resulting tree, that means the strategy module
         * auto resolved the merge cleanly.
         */
-       if (automerge_was_ok)
-               return finish_automerge(head_commit, common, result_tree,
-                                       wt_strategy);
+       if (automerge_was_ok) {
+               ret = finish_automerge(head_commit, common, result_tree,
+                                      wt_strategy);
+               goto done;
+       }
 
        /*
         * Pick the result from the best strategy and have the user fix
@@ -1475,7 +1496,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
                else
                        fprintf(stderr, _("Merge with strategy %s failed.\n"),
                                use_strategies[0]->name);
-               return 2;
+               ret = 2;
+               goto done;
        } else if (best_strategy == wt_strategy)
                ; /* We already have its result in the working tree. */
        else {
@@ -1491,10 +1513,13 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
        else
                write_merge_state();
 
-       if (merge_was_ok) {
+       if (merge_was_ok)
                fprintf(stderr, _("Automatic merge went well; "
                        "stopped before committing as requested\n"));
-               return 0;
-       } else
-               return suggest_conflicts(option_renormalize);
+       else
+               ret = suggest_conflicts(option_renormalize);
+
+done:
+       free((char *)branch);
+       return ret;
 }
index f8e437db0156043f1586e66adf343e34ef6cf4dc..10b8bc7ad9c392d9dad9e06cf2d1b3ae3f7fd001 100644 (file)
@@ -804,6 +804,7 @@ static int merge_commit(struct notes_merge_options *o)
        struct notes_tree *t;
        struct commit *partial;
        struct pretty_print_context pretty_ctx;
+       int ret;
 
        /*
         * Read partial merge result from .git/NOTES_MERGE_PARTIAL,
@@ -828,6 +829,7 @@ static int merge_commit(struct notes_merge_options *o)
        o->local_ref = resolve_ref("NOTES_MERGE_REF", sha1, 0, NULL);
        if (!o->local_ref)
                die("Failed to resolve NOTES_MERGE_REF");
+       o->local_ref = xstrdup(o->local_ref);
 
        if (notes_merge_commit(o, t, partial, sha1))
                die("Failed to finalize notes merge");
@@ -843,7 +845,9 @@ static int merge_commit(struct notes_merge_options *o)
 
        free_notes(t);
        strbuf_release(&msg);
-       return merge_abort(o);
+       ret = merge_abort(o);
+       free((char *)o->local_ref);
+       return ret;
 }
 
 static int merge(int argc, const char **argv, const char *prefix)
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 7ec68a1e8089f74ce7c70fecd86d5c18264ce4bc..b6d957cb0d2659f2207287598b3566ed37a35ae0 100644 (file)
@@ -695,7 +695,10 @@ static void execute_commands(struct command *commands, const char *unpacker_erro
 
        check_aliased_updates(commands);
 
+       free((char *)head_name);
        head_name = resolve_ref("HEAD", sha1, 0, NULL);
+       if (head_name)
+               head_name = xstrdup(head_name);
 
        for (cmd = commands; cmd; cmd = cmd->next)
                if (!cmd->skip_update)
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 c810643815e38f4ada805e2af49973e4e0051801..407abfb0f7545374f1d4c0bcdef22effe5ca1bea 100644 (file)
@@ -343,8 +343,7 @@ static int get_ref_states(const struct ref *remote_refs, struct ref_states *stat
        states->tracked.strdup_strings = 1;
        states->stale.strdup_strings = 1;
        for (ref = fetch_map; ref; ref = ref->next) {
-               unsigned char sha1[20];
-               if (!ref->peer_ref || read_ref(ref->peer_ref->name, sha1))
+               if (!ref->peer_ref || !ref_exists(ref->peer_ref->name))
                        string_list_append(&states->new, abbrev_branch(ref->name));
                else
                        string_list_append(&states->tracked, abbrev_branch(ref->name));
@@ -710,7 +709,7 @@ static int mv(int argc, const char **argv)
                int flag = 0;
                unsigned char sha1[20];
 
-               resolve_ref(item->string, sha1, 1, &flag);
+               read_ref_full(item->string, sha1, 1, &flag);
                if (!(flag & REF_ISSYMREF))
                        continue;
                if (delete_ref(item->string, NULL, REF_NODEREF))
@@ -1220,10 +1219,9 @@ static int set_head(int argc, const char **argv)
                usage_with_options(builtin_remote_sethead_usage, options);
 
        if (head_name) {
-               unsigned char sha1[20];
                strbuf_addf(&buf2, "refs/remotes/%s/%s", argv[0], head_name);
                /* make sure it's valid */
-               if (!resolve_ref(buf2.buf, sha1, 1, NULL))
+               if (!ref_exists(buf2.buf))
                        result |= error("Not a valid ref: %s", buf2.buf);
                else if (create_symref(buf.buf, buf2.buf, "remote set-head"))
                        result |= error("Could not setup %s", buf.buf);
index 517fa1031a86f50c0d41ba567237aa701e9c2c05..4a8970e9c95c1e07c1ed919d40f33238dcd05588 100644 (file)
@@ -58,7 +58,7 @@ static int for_each_replace_name(const char **argv, each_replace_name_fn fn)
                        had_error = 1;
                        continue;
                }
-               if (!resolve_ref(ref, sha1, 1, NULL)) {
+               if (read_ref(ref, sha1)) {
                        error("replace ref '%s' not found.", *p);
                        had_error = 1;
                        continue;
@@ -97,7 +97,7 @@ static int replace_object(const char *object_ref, const char *replace_ref,
        if (check_refname_format(ref, 0))
                die("'%s' is not a valid ref name.", ref);
 
-       if (!resolve_ref(ref, prev, 1, NULL))
+       if (read_ref(ref, prev))
                hashclr(prev);
        else if (!force)
                die("replace ref '%s' already exists", ref);
index 0c61668b858671c4817e1445de01812fcc53f92d..1ea525c10e4c00b66006bf46465ebd490823f25f 100644 (file)
@@ -308,7 +308,7 @@ static void write_cherry_pick_head(struct commit *commit, const char *pseudoref)
 
        strbuf_addf(&buf, "%s\n", sha1_to_hex(commit->object.sha1));
 
-       filename = git_path(pseudoref);
+       filename = git_path("%s", pseudoref);
        fd = open(filename, O_WRONLY | O_CREAT, 0666);
        if (fd < 0)
                die_errno(_("Could not open '%s' for writing"), filename);
@@ -931,8 +931,10 @@ static int sequencer_rollback(struct replay_opts *opts)
        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);
@@ -940,12 +942,11 @@ static int sequencer_rollback(struct replay_opts *opts)
        }
        if (reset_for_rollback(sha1))
                goto fail;
+       remove_sequencer_state(1);
        strbuf_release(&buf);
-       fclose(f);
        return 0;
 fail:
        strbuf_release(&buf);
-       fclose(f);
        return -1;
 }
 
index fafb6dd50081b3af22bdbcde898d170ef47f679d..3911661900f79562133b4ebd6cbb513a06232b5b 100644 (file)
@@ -225,7 +225,7 @@ int cmd_show_ref(int argc, const char **argv, const char *prefix)
                        unsigned char sha1[20];
 
                        if (!prefixcmp(*pattern, "refs/") &&
-                           resolve_ref(*pattern, sha1, 1, NULL)) {
+                           !read_ref(*pattern, sha1)) {
                                if (!quiet)
                                        show_one(*pattern, sha1);
                        }
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 9b6fd95494fd80240f88d49224199b7e621717e4..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;
@@ -174,7 +173,7 @@ static int for_each_tag_name(const char **argv, each_tag_name_fn fn)
                        had_error = 1;
                        continue;
                }
-               if (!resolve_ref(ref, sha1, 1, NULL)) {
+               if (read_ref(ref, sha1)) {
                        error(_("tag '%s' not found."), *p);
                        had_error = 1;
                        continue;
@@ -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;
@@ -518,7 +454,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
        if (strbuf_check_tag_ref(&ref, tag))
                die(_("'%s' is not a valid tag name."), tag);
 
-       if (!resolve_ref(ref.buf, prev, 1, NULL))
+       if (read_ref(ref.buf, prev))
                hashclr(prev);
        else if (!force)
                die(_("tag '%s' already exists"), tag);
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)
index 08020bc3a258e055a8f5f6974217cf482edc3ee3..4742f2734eeb3dee117ab02a422056cfee4f71ea 100644 (file)
--- a/bundle.c
+++ b/bundle.c
@@ -320,7 +320,7 @@ int create_bundle(struct bundle_header *header, const char *path,
                        continue;
                if (dwim_ref(e->name, strlen(e->name), sha1, &ref) != 1)
                        continue;
-               if (!resolve_ref(e->name, sha1, 1, &flag))
+               if (read_ref_full(e->name, sha1, 1, &flag))
                        flag = 0;
                display_ref = (flag & REF_ISSYMREF) ? e->name : ref;
 
diff --git a/cache.h b/cache.h
index 2e6ad3604e4cc6efd60a69407159967a1940e680..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;
@@ -832,6 +831,8 @@ static inline int get_sha1_with_context(const char *str, unsigned char *sha1, st
 extern int get_sha1_hex(const char *hex, unsigned char *sha1);
 
 extern char *sha1_to_hex(const unsigned char *sha1);   /* static buffer result! */
+extern int read_ref_full(const char *filename, unsigned char *sha1,
+                        int reading, int *flags);
 extern int read_ref(const char *filename, unsigned char *sha1);
 
 /*
@@ -873,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 fecf0d07760d2211fac6db2e19ecbedaac81c57e..0ff1e04812ef2491f15b1d40bb8e1c2977b26d98 100644 (file)
@@ -120,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 b6d789a189713a0259e3f8eb0e29ef657cde66c7..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;
        }
 
index b7c1edf1cc763199d41a490b212a3b65ea581a86..cc1bdf960949cfeb977d8a188a2324b48bf5c6df 100755 (executable)
@@ -486,8 +486,13 @@ _get_comp_words_by_ref ()
 fi
 fi
 
-# __gitcomp accepts 1, 2, 3, or 4 arguments
-# generates completion reply with compgen
+# Generates completion reply with compgen, appending a space to possible
+# completion words, if necessary.
+# It accepts 1 to 4 arguments:
+# 1: List of possible completion words.
+# 2: A prefix to be added to each possible completion word (optional).
+# 3: Generate possible completion matches for this word (optional).
+# 4: A suffix to be appended to each possible completion word (optional).
 __gitcomp ()
 {
        local cur_="$cur"
@@ -508,42 +513,49 @@ __gitcomp ()
        esac
 }
 
-# __git_heads accepts 0 or 1 arguments (to pass to __gitdir)
+# Generates completion reply with compgen from newline-separated possible
+# completion words by appending a space to all of them.
+# It accepts 1 to 4 arguments:
+# 1: List of possible completion words, separated by a single newline.
+# 2: A prefix to be added to each possible completion word (optional).
+# 3: Generate possible completion matches for this word (optional).
+# 4: A suffix to be appended to each possible completion word instead of
+#    the default space (optional).  If specified but empty, nothing is
+#    appended.
+__gitcomp_nl ()
+{
+       local s=$'\n' IFS=' '$'\t'$'\n'
+       local cur_="$cur" suffix=" "
+
+       if [ $# -gt 2 ]; then
+               cur_="$3"
+               if [ $# -gt 3 ]; then
+                       suffix="$4"
+               fi
+       fi
+
+       IFS=$s
+       COMPREPLY=($(compgen -P "${2-}" -S "$suffix" -W "$1" -- "$cur_"))
+}
+
 __git_heads ()
 {
-       local cmd i is_hash=y dir="$(__gitdir "${1-}")"
+       local dir="$(__gitdir)"
        if [ -d "$dir" ]; then
                git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
                        refs/heads
                return
        fi
-       for i in $(git ls-remote "${1-}" 2>/dev/null); do
-               case "$is_hash,$i" in
-               y,*) is_hash=n ;;
-               n,*^{}) is_hash=y ;;
-               n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
-               n,*) is_hash=y; echo "$i" ;;
-               esac
-       done
 }
 
-# __git_tags accepts 0 or 1 arguments (to pass to __gitdir)
 __git_tags ()
 {
-       local cmd i is_hash=y dir="$(__gitdir "${1-}")"
+       local dir="$(__gitdir)"
        if [ -d "$dir" ]; then
                git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
                        refs/tags
                return
        fi
-       for i in $(git ls-remote "${1-}" 2>/dev/null); do
-               case "$is_hash,$i" in
-               y,*) is_hash=n ;;
-               n,*^{}) is_hash=y ;;
-               n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;;
-               n,*) is_hash=y; echo "$i" ;;
-               esac
-       done
 }
 
 # __git_refs accepts 0, 1 (to pass to __gitdir), or 2 arguments
@@ -551,7 +563,7 @@ __git_tags ()
 # by checkout for tracking branches
 __git_refs ()
 {
-       local i is_hash=y dir="$(__gitdir "${1-}")" track="${2-}"
+       local i hash dir="$(__gitdir "${1-}")" track="${2-}"
        local format refs
        if [ -d "$dir" ]; then
                case "$cur" in
@@ -587,16 +599,27 @@ __git_refs ()
                fi
                return
        fi
-       for i in $(git ls-remote "$dir" 2>/dev/null); do
-               case "$is_hash,$i" in
-               y,*) is_hash=n ;;
-               n,*^{}) is_hash=y ;;
-               n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;;
-               n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
-               n,refs/remotes/*) is_hash=y; echo "${i#refs/remotes/}" ;;
-               n,*) is_hash=y; echo "$i" ;;
-               esac
-       done
+       case "$cur" in
+       refs|refs/*)
+               git ls-remote "$dir" "$cur*" 2>/dev/null | \
+               while read hash i; do
+                       case "$i" in
+                       *^{}) ;;
+                       *) echo "$i" ;;
+                       esac
+               done
+               ;;
+       *)
+               git ls-remote "$dir" HEAD ORIG_HEAD 'refs/tags/*' 'refs/heads/*' 'refs/remotes/*' 2>/dev/null | \
+               while read hash i; do
+                       case "$i" in
+                       *^{}) ;;
+                       refs/*) echo "${i#refs/*/}" ;;
+                       *) echo "$i" ;;
+                       esac
+               done
+               ;;
+       esac
 }
 
 # __git_refs2 requires 1 argument (to pass to __git_refs)
@@ -611,18 +634,10 @@ __git_refs2 ()
 # __git_refs_remotes requires 1 argument (to pass to ls-remote)
 __git_refs_remotes ()
 {
-       local cmd i is_hash=y
-       for i in $(git ls-remote "$1" 2>/dev/null); do
-               case "$is_hash,$i" in
-               n,refs/heads/*)
-                       is_hash=y
-                       echo "$i:refs/remotes/$1/${i#refs/heads/}"
-                       ;;
-               y,*) is_hash=n ;;
-               n,*^{}) is_hash=y ;;
-               n,refs/tags/*) is_hash=y;;
-               n,*) is_hash=y; ;;
-               esac
+       local i hash
+       git ls-remote "$1" 'refs/heads/*' 2>/dev/null | \
+       while read hash i; do
+               echo "$i:refs/remotes/$1/${i#refs/heads/}"
        done
 }
 
@@ -712,15 +727,15 @@ __git_complete_revlist_file ()
        *...*)
                pfx="${cur_%...*}..."
                cur_="${cur_#*...}"
-               __gitcomp "$(__git_refs)" "$pfx" "$cur_"
+               __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
                ;;
        *..*)
                pfx="${cur_%..*}.."
                cur_="${cur_#*..}"
-               __gitcomp "$(__git_refs)" "$pfx" "$cur_"
+               __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
                ;;
        *)
-               __gitcomp "$(__git_refs)"
+               __gitcomp_nl "$(__git_refs)"
                ;;
        esac
 }
@@ -760,7 +775,7 @@ __git_complete_remote_or_refspec ()
                c=$((++c))
        done
        if [ -z "$remote" ]; then
-               __gitcomp "$(__git_remotes)"
+               __gitcomp_nl "$(__git_remotes)"
                return
        fi
        if [ $no_complete_refspec = 1 ]; then
@@ -785,23 +800,23 @@ __git_complete_remote_or_refspec ()
        case "$cmd" in
        fetch)
                if [ $lhs = 1 ]; then
-                       __gitcomp "$(__git_refs2 "$remote")" "$pfx" "$cur_"
+                       __gitcomp_nl "$(__git_refs2 "$remote")" "$pfx" "$cur_"
                else
-                       __gitcomp "$(__git_refs)" "$pfx" "$cur_"
+                       __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
                fi
                ;;
        pull)
                if [ $lhs = 1 ]; then
-                       __gitcomp "$(__git_refs "$remote")" "$pfx" "$cur_"
+                       __gitcomp_nl "$(__git_refs "$remote")" "$pfx" "$cur_"
                else
-                       __gitcomp "$(__git_refs)" "$pfx" "$cur_"
+                       __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
                fi
                ;;
        push)
                if [ $lhs = 1 ]; then
-                       __gitcomp "$(__git_refs)" "$pfx" "$cur_"
+                       __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
                else
-                       __gitcomp "$(__git_refs "$remote")" "$pfx" "$cur_"
+                       __gitcomp_nl "$(__git_refs "$remote")" "$pfx" "$cur_"
                fi
                ;;
        esac
@@ -1080,7 +1095,7 @@ _git_archive ()
                return
                ;;
        --remote=*)
-               __gitcomp "$(__git_remotes)" "" "${cur##--remote=}"
+               __gitcomp_nl "$(__git_remotes)" "" "${cur##--remote=}"
                return
                ;;
        --*)
@@ -1111,7 +1126,7 @@ _git_bisect ()
 
        case "$subcommand" in
        bad|good|reset|skip|start)
-               __gitcomp "$(__git_refs)"
+               __gitcomp_nl "$(__git_refs)"
                ;;
        *)
                COMPREPLY=()
@@ -1142,9 +1157,9 @@ _git_branch ()
                ;;
        *)
                if [ $only_local_ref = "y" -a $has_r = "n" ]; then
-                       __gitcomp "$(__git_heads)"
+                       __gitcomp_nl "$(__git_heads)"
                else
-                       __gitcomp "$(__git_refs)"
+                       __gitcomp_nl "$(__git_refs)"
                fi
                ;;
        esac
@@ -1191,7 +1206,7 @@ _git_checkout ()
                if [ -n "$(__git_find_on_cmdline "$flags")" ]; then
                        track=''
                fi
-               __gitcomp "$(__git_refs '' $track)"
+               __gitcomp_nl "$(__git_refs '' $track)"
                ;;
        esac
 }
@@ -1208,7 +1223,7 @@ _git_cherry_pick ()
                __gitcomp "--edit --no-commit"
                ;;
        *)
-               __gitcomp "$(__git_refs)"
+               __gitcomp_nl "$(__git_refs)"
                ;;
        esac
 }
@@ -1262,7 +1277,7 @@ _git_commit ()
                ;;
        --reuse-message=*|--reedit-message=*|\
        --fixup=*|--squash=*)
-               __gitcomp "$(__git_refs)" "" "${cur#*=}"
+               __gitcomp_nl "$(__git_refs)" "" "${cur#*=}"
                return
                ;;
        --untracked-files=*)
@@ -1293,7 +1308,7 @@ _git_describe ()
                        "
                return
        esac
-       __gitcomp "$(__git_refs)"
+       __gitcomp_nl "$(__git_refs)"
 }
 
 __git_diff_common_options="--stat --numstat --shortstat --summary
@@ -1459,13 +1474,13 @@ _git_grep ()
        case "$cword,$prev" in
        2,*|*,-*)
                if test -r tags; then
-                       __gitcomp "$(__git_match_ctag "$cur" tags)"
+                       __gitcomp_nl "$(__git_match_ctag "$cur" tags)"
                        return
                fi
                ;;
        esac
 
-       __gitcomp "$(__git_refs)"
+       __gitcomp_nl "$(__git_refs)"
 }
 
 _git_help ()
@@ -1523,7 +1538,7 @@ _git_ls_files ()
 
 _git_ls_remote ()
 {
-       __gitcomp "$(__git_remotes)"
+       __gitcomp_nl "$(__git_remotes)"
 }
 
 _git_ls_tree ()
@@ -1619,7 +1634,7 @@ _git_merge ()
                __gitcomp "$__git_merge_options"
                return
        esac
-       __gitcomp "$(__git_refs)"
+       __gitcomp_nl "$(__git_refs)"
 }
 
 _git_mergetool ()
@@ -1639,7 +1654,7 @@ _git_mergetool ()
 
 _git_merge_base ()
 {
-       __gitcomp "$(__git_refs)"
+       __gitcomp_nl "$(__git_refs)"
 }
 
 _git_mv ()
@@ -1670,7 +1685,7 @@ _git_notes ()
        ,*)
                case "${words[cword-1]}" in
                --ref)
-                       __gitcomp "$(__git_refs)"
+                       __gitcomp_nl "$(__git_refs)"
                        ;;
                *)
                        __gitcomp "$subcommands --ref"
@@ -1679,7 +1694,7 @@ _git_notes ()
                ;;
        add,--reuse-message=*|append,--reuse-message=*|\
        add,--reedit-message=*|append,--reedit-message=*)
-               __gitcomp "$(__git_refs)" "" "${cur#*=}"
+               __gitcomp_nl "$(__git_refs)" "" "${cur#*=}"
                ;;
        add,--*|append,--*)
                __gitcomp '--file= --message= --reedit-message=
@@ -1698,7 +1713,7 @@ _git_notes ()
                -m|-F)
                        ;;
                *)
-                       __gitcomp "$(__git_refs)"
+                       __gitcomp_nl "$(__git_refs)"
                        ;;
                esac
                ;;
@@ -1726,12 +1741,12 @@ _git_push ()
 {
        case "$prev" in
        --repo)
-               __gitcomp "$(__git_remotes)"
+               __gitcomp_nl "$(__git_remotes)"
                return
        esac
        case "$cur" in
        --repo=*)
-               __gitcomp "$(__git_remotes)" "" "${cur##--repo=}"
+               __gitcomp_nl "$(__git_remotes)" "" "${cur##--repo=}"
                return
                ;;
        --*)
@@ -1769,7 +1784,7 @@ _git_rebase ()
 
                return
        esac
-       __gitcomp "$(__git_refs)"
+       __gitcomp_nl "$(__git_refs)"
 }
 
 _git_reflog ()
@@ -1780,7 +1795,7 @@ _git_reflog ()
        if [ -z "$subcommand" ]; then
                __gitcomp "$subcommands"
        else
-               __gitcomp "$(__git_refs)"
+               __gitcomp_nl "$(__git_refs)"
        fi
 }
 
@@ -1862,23 +1877,27 @@ _git_config ()
 {
        case "$prev" in
        branch.*.remote)
-               __gitcomp "$(__git_remotes)"
+               __gitcomp_nl "$(__git_remotes)"
                return
                ;;
        branch.*.merge)
-               __gitcomp "$(__git_refs)"
+               __gitcomp_nl "$(__git_refs)"
                return
                ;;
        remote.*.fetch)
                local remote="${prev#remote.}"
                remote="${remote%.fetch}"
-               __gitcomp "$(__git_refs_remotes "$remote")"
+               if [ -z "$cur" ]; then
+                       COMPREPLY=("refs/heads/")
+                       return
+               fi
+               __gitcomp_nl "$(__git_refs_remotes "$remote")"
                return
                ;;
        remote.*.push)
                local remote="${prev#remote.}"
                remote="${remote%.push}"
-               __gitcomp "$(git --git-dir="$(__gitdir)" \
+               __gitcomp_nl "$(git --git-dir="$(__gitdir)" \
                        for-each-ref --format='%(refname):%(refname)' \
                        refs/heads)"
                return
@@ -1925,7 +1944,7 @@ _git_config ()
                return
                ;;
        --get|--get-all|--unset|--unset-all)
-               __gitcomp "$(__git_config_get_set_variables)"
+               __gitcomp_nl "$(__git_config_get_set_variables)"
                return
                ;;
        *.*)
@@ -1951,7 +1970,7 @@ _git_config ()
                ;;
        branch.*)
                local pfx="${cur%.*}." cur_="${cur#*.}"
-               __gitcomp "$(__git_heads)" "$pfx" "$cur_" "."
+               __gitcomp_nl "$(__git_heads)" "$pfx" "$cur_" "."
                return
                ;;
        guitool.*.*)
@@ -1980,7 +1999,7 @@ _git_config ()
        pager.*)
                local pfx="${cur%.*}." cur_="${cur#*.}"
                __git_compute_all_commands
-               __gitcomp "$__git_all_commands" "$pfx" "$cur_"
+               __gitcomp_nl "$__git_all_commands" "$pfx" "$cur_"
                return
                ;;
        remote.*.*)
@@ -1993,7 +2012,7 @@ _git_config ()
                ;;
        remote.*)
                local pfx="${cur%.*}." cur_="${cur#*.}"
-               __gitcomp "$(__git_remotes)" "$pfx" "$cur_" "."
+               __gitcomp_nl "$(__git_remotes)" "$pfx" "$cur_" "."
                return
                ;;
        url.*.*)
@@ -2294,7 +2313,7 @@ _git_remote ()
 
        case "$subcommand" in
        rename|rm|show|prune)
-               __gitcomp "$(__git_remotes)"
+               __gitcomp_nl "$(__git_remotes)"
                ;;
        update)
                local i c='' IFS=$'\n'
@@ -2312,7 +2331,7 @@ _git_remote ()
 
 _git_replace ()
 {
-       __gitcomp "$(__git_refs)"
+       __gitcomp_nl "$(__git_refs)"
 }
 
 _git_reset ()
@@ -2325,7 +2344,7 @@ _git_reset ()
                return
                ;;
        esac
-       __gitcomp "$(__git_refs)"
+       __gitcomp_nl "$(__git_refs)"
 }
 
 _git_revert ()
@@ -2336,7 +2355,7 @@ _git_revert ()
                return
                ;;
        esac
-       __gitcomp "$(__git_refs)"
+       __gitcomp_nl "$(__git_refs)"
 }
 
 _git_rm ()
@@ -2435,7 +2454,7 @@ _git_stash ()
                        COMPREPLY=()
                        ;;
                show,*|apply,*|drop,*|pop,*|branch,*)
-                       __gitcomp "$(git --git-dir="$(__gitdir)" stash list \
+                       __gitcomp_nl "$(git --git-dir="$(__gitdir)" stash list \
                                        | sed -n -e 's/:.*//p')"
                        ;;
                *)
@@ -2569,7 +2588,7 @@ _git_tag ()
                i="${words[c]}"
                case "$i" in
                -d|-v)
-                       __gitcomp "$(__git_tags)"
+                       __gitcomp_nl "$(__git_tags)"
                        return
                        ;;
                -f)
@@ -2585,13 +2604,13 @@ _git_tag ()
                ;;
        -*|tag)
                if [ $f = 1 ]; then
-                       __gitcomp "$(__git_tags)"
+                       __gitcomp_nl "$(__git_tags)"
                else
                        COMPREPLY=()
                fi
                ;;
        *)
-               __gitcomp "$(__git_refs)"
+               __gitcomp_nl "$(__git_refs)"
                ;;
        esac
 }
index b975d67fca530a35c590cb677a6f11eabb7900bb..7d8e74b6ddb3e17ce3d2fdfd7b4bcdf28a7e7a2f 100755 (executable)
@@ -53,9 +53,10 @@ def p4_build_cmd(cmd):
 
 def chdir(dir):
     # P4 uses the PWD environment variable rather than getcwd(). Since we're
-    # not using the shell, we have to set it ourselves.
-    os.environ['PWD']=dir
+    # not using the shell, we have to set it ourselves.  This path could
+    # be relative, so go there first, then figure out where we ended up.
     os.chdir(dir)
+    os.environ['PWD'] = os.getcwd()
 
 def die(msg):
     if verbose:
@@ -847,6 +848,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 +1034,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 +1042,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 +1056,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:
@@ -1099,6 +1117,10 @@ class P4Submit(Command, P4UserMap):
         print "Perforce checkout for depot path %s located at %s" % (self.depotPath, self.clientPath)
         self.oldWorkingDirectory = os.getcwd()
 
+        # ensure the clientPath exists
+        if not os.path.exists(self.clientPath):
+            os.makedirs(self.clientPath)
+
         chdir(self.clientPath)
         print "Synchronizing p4 checkout..."
         p4_sync("...")
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 86e9c29ec05139844ff46868e2b52dfbc274cc39..346f9d45e0f48048603d779f909e6c29bdd60b5b 100644 (file)
--- a/convert.c
+++ b/convert.c
@@ -876,24 +876,39 @@ int is_null_stream_filter(struct stream_filter *filter)
 /*
  * LF-to-CRLF filter
  */
+
+struct lf_to_crlf_filter {
+       struct stream_filter filter;
+       int want_lf;
+};
+
 static int lf_to_crlf_filter_fn(struct stream_filter *filter,
                                const char *input, size_t *isize_p,
                                char *output, size_t *osize_p)
 {
-       size_t count;
+       size_t count, o = 0;
+       struct lf_to_crlf_filter *lf_to_crlf = (struct lf_to_crlf_filter *)filter;
+
+       /* Output a pending LF if we need to */
+       if (lf_to_crlf->want_lf) {
+               output[o++] = '\n';
+               lf_to_crlf->want_lf = 0;
+       }
 
        if (!input)
-               return 0; /* we do not keep any states */
+               return 0; /* We've already dealt with the state */
+
        count = *isize_p;
        if (count) {
-               size_t i, o;
-               for (i = o = 0; o < *osize_p && i < count; i++) {
+               size_t i;
+               for (i = 0; o < *osize_p && i < count; i++) {
                        char ch = input[i];
                        if (ch == '\n') {
-                               if (o + 1 < *osize_p)
-                                       output[o++] = '\r';
-                               else
-                                       break;
+                               output[o++] = '\r';
+                               if (o >= *osize_p) {
+                                       lf_to_crlf->want_lf = 1;
+                                       continue; /* We need to increase i */
+                               }
                        }
                        output[o++] = ch;
                }
@@ -904,15 +919,24 @@ static int lf_to_crlf_filter_fn(struct stream_filter *filter,
        return 0;
 }
 
+static void lf_to_crlf_free_fn(struct stream_filter *filter)
+{
+       free(filter);
+}
+
 static struct stream_filter_vtbl lf_to_crlf_vtbl = {
        lf_to_crlf_filter_fn,
-       null_free_fn,
+       lf_to_crlf_free_fn,
 };
 
-static struct stream_filter lf_to_crlf_filter_singleton = {
-       &lf_to_crlf_vtbl,
-};
+static struct stream_filter *lf_to_crlf_filter(void)
+{
+       struct lf_to_crlf_filter *lf_to_crlf = xmalloc(sizeof(*lf_to_crlf));
 
+       lf_to_crlf->filter.vtbl = &lf_to_crlf_vtbl;
+       lf_to_crlf->want_lf = 0;
+       return (struct stream_filter *)lf_to_crlf;
+}
 
 /*
  * Cascade filter
@@ -1194,7 +1218,7 @@ struct stream_filter *get_stream_filter(const char *path, const unsigned char *s
 
        else if (output_eol(crlf_action) == EOL_CRLF &&
                 !(crlf_action == CRLF_AUTO || crlf_action == CRLF_GUESS))
-               filter = cascade_filter(filter, &lf_to_crlf_filter_singleton);
+               filter = cascade_filter(filter, lf_to_crlf_filter());
 
        return filter;
 }
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 8b4dd5c022a160de5c68d83b6237799c23e6ae0a..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
@@ -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 f96112d47f743289bf3893981bc89dcaa9caae19..33d07c06bd90833ce56bc64c13bdc08c1997c3fb 100644 (file)
@@ -1,3 +1,4 @@
+*           whitespace=indent-with-non-tab,trailing-space,space-before-tab,tabwidth=4
 *           encoding=US-ASCII
 git-gui.sh  encoding=UTF-8
 /po/*.po    encoding=UTF-8
index 1fb4d9b4b7393d2c803457365127692fb093338f..65709437ff06a2b371fe70fd846922c73ebc23b0 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=0.13.GITGUI
+DEF_VER=0.16.GITGUI
 
 LF='
 '
index f8971603f77a495b253b5470f5546d51dd6efd14..ba4e5c1330c84f54a6809991eec22aa2e8e25ddd 100755 (executable)
@@ -299,7 +299,9 @@ proc is_config_true {name} {
        global repo_config
        if {[catch {set v $repo_config($name)}]} {
                return 0
-       } elseif {$v eq {true} || $v eq {1} || $v eq {yes}} {
+       }
+       set v [string tolower $v]
+       if {$v eq {} || $v eq {true} || $v eq {1} || $v eq {yes} || $v eq {on}} {
                return 1
        } else {
                return 0
@@ -310,7 +312,9 @@ proc is_config_false {name} {
        global repo_config
        if {[catch {set v $repo_config($name)}]} {
                return 0
-       } elseif {$v eq {false} || $v eq {0} || $v eq {no}} {
+       }
+       set v [string tolower $v]
+       if {$v eq {false} || $v eq {0} || $v eq {no} || $v eq {off}} {
                return 1
        } else {
                return 0
@@ -460,6 +464,35 @@ proc _which {what args} {
        return {}
 }
 
+# Test a file for a hashbang to identify executable scripts on Windows.
+proc is_shellscript {filename} {
+       if {![file exists $filename]} {return 0}
+       set f [open $filename r]
+       fconfigure $f -encoding binary
+       set magic [read $f 2]
+       close $f
+       return [expr {$magic eq "#!"}]
+}
+
+# Run a command connected via pipes on stdout.
+# This is for use with textconv filters and uses sh -c "..." to allow it to
+# contain a command with arguments. On windows we must check for shell
+# scripts specifically otherwise just call the filter command.
+proc open_cmd_pipe {cmd path} {
+       global env
+       if {![file executable [shellpath]]} {
+               set exe [auto_execok [lindex $cmd 0]]
+               if {[is_shellscript [lindex $exe 0]]} {
+                       set run [linsert [auto_execok sh] end -c "$cmd \"\$0\"" $path]
+               } else {
+                       set run [concat $exe [lrange $cmd 1 end] $path]
+               }
+       } else {
+               set run [list [shellpath] -c "$cmd \"\$0\"" $path]
+       }
+       return [open |$run r]
+}
+
 proc _lappend_nice {cmd_var} {
        global _nice
        upvar $cmd_var cmd
@@ -725,7 +758,10 @@ if {[is_Windows]} {
                gitlogo put gray26  -to  5 15 11 16
                gitlogo redither
 
-               wm iconphoto . -default gitlogo
+               image create photo gitlogo32 -width 32 -height 32
+               gitlogo32 copy gitlogo -zoom 2 2
+
+               wm iconphoto . -default gitlogo gitlogo32
        }
 }
 
@@ -846,6 +882,7 @@ set default_config(gui.fastcopyblame) false
 set default_config(gui.copyblamethreshold) 40
 set default_config(gui.blamehistoryctx) 7
 set default_config(gui.diffcontext) 5
+set default_config(gui.diffopts) {}
 set default_config(gui.commitmsgwidth) 75
 set default_config(gui.newbranchtemplate) {}
 set default_config(gui.spellingdictionary) {}
@@ -859,6 +896,7 @@ set font_descs {
        {fontui   font_ui   {mc "Main Font"}}
        {fontdiff font_diff {mc "Diff/Console Font"}}
 }
+set default_config(gui.stageuntracked) ask
 
 ######################################################################
 ##
@@ -1060,6 +1098,10 @@ git-version proc _parse_config {arr_name args} {
                                } else {
                                        set arr($name) $value
                                }
+                       } elseif {[regexp {^([^\n]+)$} $line line name]} {
+                               # no value given, but interpreting them as
+                               # boolean will be handled as true
+                               set arr($name) {}
                        }
                }
        }
@@ -1075,6 +1117,10 @@ git-version proc _parse_config {arr_name args} {
                                        } else {
                                                set arr($name) $value
                                        }
+                               } elseif {[regexp {^([^=]+)$} $line line name]} {
+                                       # no value given, but interpreting them as
+                                       # boolean will be handled as true
+                                       set arr($name) {}
                                }
                        }
                        close $fd_rc
@@ -2474,6 +2520,7 @@ proc toggle_or_diff {w x y} {
                                [concat $after [list ui_ready]]
                }
        } else {
+               set selected_paths($path) 1
                show_diff $path $w $lno
        }
 }
@@ -3362,6 +3409,7 @@ foreach {n c} {0 black 1 red4 2 green4 3 yellow4 4 blue4 5 magenta4 6 cyan4 7 gr
        $ui_diff tag configure clri3$n -background $c
 }
 $ui_diff tag configure clr1 -font font_diffbold
+$ui_diff tag configure clr4 -underline 1
 
 $ui_diff tag conf d_info -foreground blue -font font_diffbold
 
@@ -3878,7 +3926,7 @@ after 1 {
                $ui_comm configure -state disabled -background gray
        }
 }
-if {[is_enabled multicommit]} {
+if {[is_enabled multicommit] && ![is_config_false gui.gcwarning]} {
        after 1000 hint_gc
 }
 if {[is_enabled retcode]} {
index 691941e95948e7d332d6984aa6e2cc0956147550..324f7744c495dc2eb9a1d4acde09352d7948efe8 100644 (file)
@@ -219,7 +219,8 @@ constructor new {i_commit i_path i_jump} {
        eval grid $w_columns $w.file_pane.out.sby -sticky nsew
        grid conf \
                $w.file_pane.out.sbx \
-               -column [expr {[llength $w_columns] - 1}] \
+               -column 0 \
+               -columnspan [expr {[llength $w_columns] + 1}] \
                -sticky we
        grid columnconfigure \
                $w.file_pane.out \
@@ -229,12 +230,14 @@ constructor new {i_commit i_path i_jump} {
 
        set finder [::searchbar::new \
                $w.file_pane.out.ff $w_file \
-               -column [expr {[llength $w_columns] - 1}] \
+               -column 0 \
+               -columnspan [expr {[llength $w_columns] + 1}] \
                ]
 
        set gotoline [::linebar::new \
                $w.file_pane.out.lf $w_file \
-               -column [expr {[llength $w_columns] - 1}] \
+               -column 0 \
+               -columnspan [expr {[llength $w_columns] + 1}] \
                ]
 
        set w_cviewer $w.file_pane.cm.t
@@ -473,14 +476,7 @@ method _load {jump} {
        }
        if {$commit eq {}} {
                if {$do_textconv ne 0} {
-                       # Run textconv with sh -c "..." to allow it to
-                       # contain command + arguments. On windows, just
-                       # call the filter command.
-                       if {![file executable [shellpath]]} {
-                               set fd [open |[linsert $textconv end $path] r]
-                       } else {
-                               set fd [open |[list [shellpath] -c "$textconv \"\$0\"" $path] r]
-                       }
+                       set fd [open_cmd_pipe $textconv $path]
                } else {
                        set fd [open $path r]
                }
@@ -572,7 +568,11 @@ method _read_file {fd jump} {
        foreach i $w_columns {$i conf -state disabled}
 
        if {[eof $fd]} {
-               close $fd
+               fconfigure $fd -blocking 1; # enable error reporting on close
+               if {[catch {close $fd} err]} {
+                       tk_messageBox -icon error -title [mc Error] \
+                               -message $err
+               }
 
                # If we don't force Tk to update the widgets *right now*
                # none of our jump commands will cause a change in the UI.
@@ -1062,7 +1062,7 @@ method _gitkcommit {} {
                set radius [get_config gui.blamehistoryctx]
                set cmdline [list --select-commit=$cmit]
 
-                if {$radius > 0} {
+               if {$radius > 0} {
                        set author_time {}
                        set committer_time {}
 
@@ -1170,7 +1170,7 @@ method _read_diff_load_commit {fd cparent new_path tline} {
        }
 
        if {[eof $fd]} {
-               close $fd;
+               close $fd
                set current_fd {}
 
                _load_new_commit $this  \
@@ -1201,6 +1201,7 @@ method _open_tooltip {cur_w} {
                _hide_tooltip $this
 
                set tooltip_wm [toplevel $cur_w.tooltip -borderwidth 1]
+               catch {wm attributes $tooltip_wm -type tooltip}
                wm overrideredirect $tooltip_wm 1
                wm transient $tooltip_wm [winfo toplevel $cur_w]
                set tooltip_t $tooltip_wm.label
index a8c622351167be937b9f02df149a1a6ec2a16e98..0328338fda22c90c674630e0351982ff1bb2fbc4 100644 (file)
@@ -26,8 +26,14 @@ constructor new {commit {path {}}} {
        wm withdraw $top
        wm title $top [append "[appname] ([reponame]): " [mc "File Browser"]]
 
+       if {$path ne {}} {
+               if {[string index $path end] ne {/}} {
+                       append path /
+               }
+       }
+
        set browser_commit $commit
-       set browser_path $browser_commit:$path
+       set browser_path "$browser_commit:[escape_path $path]"
 
        ${NS}::label $w.path \
                -textvariable @browser_path \
index 54c7957a66aa5784d47708edc05a1c95178ed7a2..6dae7937d589c174132e9f8b9bd77133e189590f 100644 (file)
@@ -497,6 +497,7 @@ method _open_tooltip {} {
 
        if {$tooltip_wm eq {}} {
                set tooltip_wm [toplevel $w_list.tooltip -borderwidth 1]
+               catch {wm attributes $tooltip_wm -type tooltip}
                wm overrideredirect $tooltip_wm 1
                wm transient $tooltip_wm [winfo toplevel $w_list]
                set tooltip_t $tooltip_wm.label
index c27b71476ac35dbad02b727f28aba5d7c0777e75..f08506f3834a1ec821390190b920146d83078997 100644 (file)
@@ -138,6 +138,7 @@ proc make_dialog {t w args} {
        upvar $t top $w pfx this this
        global use_ttk
        uplevel [linsert $args 0 make_toplevel $t $w]
+       catch {wm attributes $top -type dialog}
        pave_toplevel $pfx
 }
 
index 372bed9948390483d66036231fce2fe8964d7bb6..0d81432af53ba873d89421fa4767243818ab1f0a 100644 (file)
@@ -263,7 +263,9 @@ proc commit_commitmsg {curHEAD msg_p} {
        global is_detached repo_config
        global pch_error
 
-       if {$is_detached && $repo_config(gui.warndetachedcommit)} {
+       if {$is_detached
+           && ![file exists [gitdir rebase-merge head-name]]
+           &&  [is_config_true gui.warndetachedcommit]} {
                set msg [mc "You are about to commit on a detached head.\
 This is a potentially dangerous thing to do because if you switch\
 to another branch you will loose your changes and it can be difficult\
index cf8a95ec346a9a8afa60a3812d59a8caa4bb4c3f..ec4405567a9b86a9bfd8bf50815b3c9c14e2df40 100644 (file)
@@ -309,6 +309,7 @@ proc start_show_diff {cont_info {add_opts {}}} {
 
        lappend cmd -p
        lappend cmd --color
+       set cmd [concat $cmd $repo_config(gui.diffopts)]
        if {$repo_config(gui.diffcontext) >= 1} {
                lappend cmd "-U$repo_config(gui.diffcontext)"
        }
@@ -502,9 +503,9 @@ proc read_diff {fd conflict_size cont_info} {
 
                foreach {posbegin colbegin posend colend} $markup {
                        set prefix clr
-                       foreach style [split $colbegin ";"] {
+                       foreach style [lsort -integer [split $colbegin ";"]] {
                                if {$style eq "7"} {append prefix i; continue}
-                               if {$style < 30 || $style > 47} {continue}
+                               if {$style != 4 && ($style < 30 || $style > 47)} {continue}
                                set a "$mark linestart + $posbegin chars"
                                set b "$mark linestart + $posend chars"
                                catch {$ui_diff tag add $prefix$style $a $b}
index e38b647b71ea335d6771121cfd079de919ced55b..8efbbdde21123dd65412cd5fe6dbb506966b0af9 100644 (file)
@@ -356,21 +356,33 @@ proc do_add_all {} {
        global file_states
 
        set paths [list]
-       set unknown_paths [list]
+       set untracked_paths [list]
        foreach path [array names file_states] {
                switch -glob -- [lindex $file_states($path) 0] {
                U? {continue}
                ?M -
                ?T -
                ?D {lappend paths $path}
-               ?O {lappend unknown_paths $path}
+               ?O {lappend untracked_paths $path}
                }
        }
-       if {[llength $unknown_paths]} {
-               set reply [ask_popup [mc "There are unknown files do you also want
-to stage those?"]]
+       if {[llength $untracked_paths]} {
+               set reply 0
+               switch -- [get_config gui.stageuntracked] {
+               no {
+                       set reply 0
+               }
+               yes {
+                       set reply 1
+               }
+               ask -
+               default {
+                       set reply [ask_popup [mc "Stage %d untracked files?" \
+                                                                         [llength $untracked_paths]]]
+               }
+               }
                if {$reply} {
-                       set paths [concat $paths $unknown_paths]
+                       set paths [concat $paths $untracked_paths]
                }
        }
        add_helper {Adding all changed files} $paths
index c160012de6e4d19c02810d57f0b3268c1037523c..a026de954c3d9cbfd03d4dec9a73a74647bf74ba 100644 (file)
@@ -15,7 +15,7 @@ constructor new {i_w i_text args} {
 
        ${NS}::frame  $w
        ${NS}::label  $w.l       -text [mc "Goto Line:"]
-       entry  $w.ent \
+       tentry  $w.ent \
                -textvariable ${__this}::linenum \
                -background lightgreen \
                -validate key \
index 3807c8d28324a277204db9191e99ddb856041c22..0cf1da1d7ebe75fe91322d9b404dbf4bd8a3b00f 100644 (file)
@@ -153,9 +153,12 @@ proc do_options {} {
                {i-20..200 gui.copyblamethreshold {mc "Minimum Letters To Blame Copy On"}}
                {i-0..300 gui.blamehistoryctx {mc "Blame History Context Radius (days)"}}
                {i-1..99 gui.diffcontext {mc "Number of Diff Context Lines"}}
+               {t gui.diffopts {mc "Additional Diff Parameters"}}
                {i-0..99 gui.commitmsgwidth {mc "Commit Message Text Width"}}
                {t gui.newbranchtemplate {mc "New Branch Name Template"}}
                {c gui.encoding {mc "Default File Contents Encoding"}}
+               {b gui.warndetachedcommit {mc "Warn before committing to a detached head"}}
+               {s gui.stageuntracked {mc "Staging of untracked files"} {list "yes" "no" "ask"}}
                } {
                set type [lindex $option 0]
                set name [lindex $option 1]
@@ -208,6 +211,23 @@ proc do_options {} {
                                }
                                pack $w.$f.$optid -side top -anchor w -fill x
                        }
+                       s {
+                               set opts [eval [lindex $option 3]]
+                               ${NS}::frame $w.$f.$optid
+                               ${NS}::label $w.$f.$optid.l -text "$text:"
+                               if {$use_ttk} {
+                                       ttk::combobox $w.$f.$optid.v \
+                                               -textvariable ${f}_config_new($name) \
+                                               -values $opts -state readonly
+                               } else {
+                                       eval tk_optionMenu $w.$f.$optid.v \
+                                               ${f}_config_new($name) \
+                                               $opts
+                               }
+                               pack $w.$f.$optid.l -side left -anchor w -fill x
+                               pack $w.$f.$optid.v -side right -anchor e -padx 5
+                               pack $w.$f.$optid -side top -anchor w -fill x
+                       }
                        }
                }
        }
index ef3486f083c74f7f5e5fe9af861818ed0d64e89c..ef1e55521d7cea10e280f720ad700a4cd4b71d65 100644 (file)
@@ -7,9 +7,16 @@ field w
 field ctext
 
 field searchstring   {}
-field casesensitive  1
+field regexpsearch
+field default_regexpsearch
+field casesensitive
+field default_casesensitive
+field smartcase
 field searchdirn     -forwards
 
+field history
+field history_index
+
 field smarktop
 field smarkbot
 
@@ -18,15 +25,37 @@ constructor new {i_w i_text args} {
        set w      $i_w
        set ctext  $i_text
 
+       set default_regexpsearch [is_config_true gui.search.regexp]
+       switch -- [get_config gui.search.case] {
+       no {
+               set default_casesensitive 0
+               set smartcase 0
+       }
+       smart {
+               set default_casesensitive 0
+               set smartcase 1
+       }
+       yes -
+       default {
+               set default_casesensitive 1
+               set smartcase 0
+       }
+       }
+
+       set history [list]
+
        ${NS}::frame  $w
        ${NS}::label  $w.l       -text [mc Find:]
-       entry  $w.ent -textvariable ${__this}::searchstring -background lightgreen
+       tentry  $w.ent -textvariable ${__this}::searchstring -background lightgreen
        ${NS}::button $w.bn      -text [mc Next] -command [cb find_next]
        ${NS}::button $w.bp      -text [mc Prev] -command [cb find_prev]
-       ${NS}::checkbutton $w.cs -text [mc Case-Sensitive] \
+       ${NS}::checkbutton $w.re -text [mc RegExp] \
+               -variable ${__this}::regexpsearch -command [cb _incrsearch]
+       ${NS}::checkbutton $w.cs -text [mc Case] \
                -variable ${__this}::casesensitive -command [cb _incrsearch]
        pack   $w.l   -side left
        pack   $w.cs  -side right
+       pack   $w.re  -side right
        pack   $w.bp  -side right
        pack   $w.bn  -side right
        pack   $w.ent -side left -expand 1 -fill x
@@ -37,6 +66,8 @@ constructor new {i_w i_text args} {
        trace add variable searchstring write [cb _incrsearch_cb]
        bind $w.ent <Return> [cb find_next]
        bind $w.ent <Shift-Return> [cb find_prev]
+       bind $w.ent <Key-Up>   [cb _prev_search]
+       bind $w.ent <Key-Down> [cb _next_search]
        
        bind $w <Destroy> [list delete_this $this]
        return $this
@@ -45,6 +76,10 @@ constructor new {i_w i_text args} {
 method show {} {
        if {![visible $this]} {
                grid $w
+               $w.ent delete 0 end
+               set regexpsearch  $default_regexpsearch
+               set casesensitive $default_casesensitive
+               set history_index [llength $history]
        }
        focus -force $w.ent
 }
@@ -53,6 +88,7 @@ method hide {} {
        if {[visible $this]} {
                focus $ctext
                grid remove $w
+               _save_search $this
        }
 }
 
@@ -98,6 +134,9 @@ method _do_search {start {mlenvar {}} {dir {}} {endbound {}}} {
                upvar $mlenvar mlen
                lappend cmd -count mlen
        }
+       if {$regexpsearch} {
+               lappend cmd -regexp
+       }
        if {!$casesensitive} {
                lappend cmd -nocase
        }
@@ -105,14 +144,16 @@ method _do_search {start {mlenvar {}} {dir {}} {endbound {}}} {
                set dir $searchdirn
        }
        lappend cmd $dir -- $searchstring
-       if {$endbound ne {}} {
-               set here [eval $cmd [list $start] [list $endbound]]
-       } else {
-               set here [eval $cmd [list $start]]
-               if {$here eq {}} {
-                       set here [eval $cmd [_get_wrap_anchor $this $dir]]
+       if {[catch {
+               if {$endbound ne {}} {
+                       set here [eval $cmd [list $start] [list $endbound]]
+               } else {
+                       set here [eval $cmd [list $start]]
+                       if {$here eq {}} {
+                               set here [eval $cmd [_get_wrap_anchor $this $dir]]
+                       }
                }
-       }
+       } err]} { set here {} }
        return $here
 }
 
@@ -126,17 +167,74 @@ method _incrsearch {} {
                $ctext mark set anchor [_get_new_anchor $this]
        }
        if {$searchstring ne {}} {
+               if {$smartcase && [regexp {[[:upper:]]} $searchstring]} {
+                       set casesensitive 1
+               }
                set here [_do_search $this anchor mlen]
                if {$here ne {}} {
                        $ctext see $here
                        $ctext tag remove sel 1.0 end
                        $ctext tag add sel $here "$here + $mlen c"
-                       $w.ent configure -background lightgreen
+                       #$w.ent configure -background lightgreen
+                       $w.ent state !pressed
                        _set_marks $this 1
                } else {
-                       $w.ent configure -background lightpink
+                       #$w.ent configure -background lightpink
+                       $w.ent state pressed
                }
+       } elseif {$smartcase} {
+               # clearing the field resets the smart case detection
+               set casesensitive 0
+       }
+}
+
+method _save_search {} {
+       if {$searchstring eq {}} {
+               return
+       }
+       if {[llength $history] > 0} {
+               foreach {s_regexp s_case s_expr} [lindex $history end] break
+       } else {
+               set s_regexp $regexpsearch
+               set s_case   $casesensitive
+               set s_expr   ""
+       }
+       if {$searchstring eq $s_expr} {
+               # update modes
+               set history [lreplace $history end end \
+                               [list $regexpsearch $casesensitive $searchstring]]
+       } else {
+               lappend history [list $regexpsearch $casesensitive $searchstring]
+       }
+       set history_index [llength $history]
+}
+
+method _prev_search {} {
+       if {$history_index > 0} {
+               incr history_index -1
+               foreach {s_regexp s_case s_expr} [lindex $history $history_index] break
+               $w.ent delete 0 end
+               $w.ent insert 0 $s_expr
+               set regexpsearch $s_regexp
+               set casesensitive $s_case
+       }
+}
+
+method _next_search {} {
+       if {$history_index < [llength $history]} {
+               incr history_index
+       }
+       if {$history_index < [llength $history]} {
+               foreach {s_regexp s_case s_expr} [lindex $history $history_index] break
+       } else {
+               set s_regexp $default_regexpsearch
+               set s_case   $default_casesensitive
+               set s_expr   ""
        }
+       $w.ent delete 0 end
+       $w.ent insert 0 $s_expr
+       set regexpsearch $s_regexp
+       set casesensitive $s_case
 }
 
 method find_prev {} {
@@ -149,6 +247,7 @@ method find_next {{dir -forwards}} {
        set searchdirn $dir
        $ctext mark unset anchor
        if {$searchstring ne {}} {
+               _save_search $this
                set start [_get_new_anchor $this]
                if {$dir eq "-forwards"} {
                        set start "$start + 1c"
index 5f75bc96b3504bdd67ae3500cfdd30f7d4fcb32a..aa6457bbb5f1b0d64d6e04f27394912483250117 100644 (file)
@@ -117,7 +117,7 @@ proc read_sshkey_output {fd w} {
        } else {
                set finfo [find_ssh_key]
                if {$finfo eq {}} {
-                       set sshkey_title [mc "Generation succeded, but no keys found."]
+                       set sshkey_title [mc "Generation succeeded, but no keys found."]
                        $w.contents insert end $sshkey_output
                } else {
                        set sshkey_title [mc "Your key is in: %s" [lindex $finfo 0]]
index 1da458673b557fe84ac8e430e97b7ad53c69a07a..8b88d3678b7ddd802260f47bcfeff8a895d93f3f 100644 (file)
@@ -23,10 +23,59 @@ proc InitTheme {} {
        ttk::style configure Gold.TFrame -background gold -relief flat
        # listboxes should have a theme border so embed in ttk::frame
        ttk::style layout SListbox.TFrame {
-        SListbox.Frame.Entry.field -sticky news -border true -children {
-            SListbox.Frame.padding -sticky news
-        }
-    }
+               SListbox.Frame.Entry.field -sticky news -border true -children {
+                       SListbox.Frame.padding -sticky news
+               }
+       }
+
+       # Handle either current Tk or older versions of 8.5
+       if {[catch {set theme [ttk::style theme use]}]} {
+               set theme  $::ttk::currentTheme
+       }
+
+       if {[lsearch -exact {default alt classic clam} $theme] != -1} {
+               # Simple override of standard ttk::entry to change the field
+               # packground according to a state flag. We should use 'user1'
+               # but not all versions of 8.5 support that so make use of 'pressed'
+               # which is not normally in use for entry widgets.
+               ttk::style layout Edged.Entry [ttk::style layout TEntry]
+               ttk::style map Edged.Entry {*}[ttk::style map TEntry]
+               ttk::style configure Edged.Entry {*}[ttk::style configure TEntry] \
+                       -fieldbackground lightgreen
+               ttk::style map Edged.Entry -fieldbackground {
+                       {pressed !disabled} lightpink
+               }
+       } else {
+               # For fancier themes, in particular the Windows ones, the field
+               # element may not support changing the background color. So instead
+               # override the fill using the default fill element. If we overrode
+               # the vista theme field element we would loose the themed border
+               # of the widget.
+               catch {
+                       ttk::style element create color.fill from default
+               }
+
+               ttk::style layout Edged.Entry {
+                       Edged.Entry.field -sticky nswe -border 0 -children {
+                               Edged.Entry.border -sticky nswe -border 1 -children {
+                                       Edged.Entry.padding -sticky nswe -children {
+                                               Edged.Entry.color.fill -sticky nswe -children {
+                                                       Edged.Entry.textarea -sticky nswe
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               ttk::style configure Edged.Entry {*}[ttk::style configure TEntry] \
+                       -background lightgreen -padding 0 -borderwidth 0
+               ttk::style map Edged.Entry {*}[ttk::style map TEntry] \
+                       -background {{pressed !disabled} lightpink}
+       }
+
+       if {[lsearch [bind . <<ThemeChanged>>] InitTheme] == -1} {
+               bind . <<ThemeChanged>> +[namespace code [list InitTheme]]
+       }
 }
 
 proc gold_frame {w args} {
@@ -74,6 +123,7 @@ proc paddedlabel {w args} {
 # place a themed frame over the surface.
 proc Dialog {w args} {
        eval [linsert $args 0 toplevel $w -class Dialog]
+       catch {wm attributes $w -type dialog}   
        pave_toplevel $w
        return $w
 }
@@ -143,6 +193,47 @@ proc tspinbox {w args} {
        }
 }
 
+proc tentry {w args} {
+       global use_ttk
+       if {$use_ttk} {
+               InitTheme
+               ttk::entry $w -style Edged.Entry
+       } else {
+               entry $w
+       }
+
+       rename $w _$w
+       interp alias {} $w {} tentry_widgetproc $w
+       eval [linsert $args 0 tentry_widgetproc $w configure]
+       return $w
+}
+proc tentry_widgetproc {w cmd args} {
+       global use_ttk
+       switch -- $cmd {
+               state {
+                       if {$use_ttk} {
+                               return [uplevel 1 [list _$w $cmd] $args]
+                       } else {
+                               if {[lsearch -exact $args pressed] != -1} {
+                                       _$w configure -background lightpink
+                               } else {
+                                       _$w configure -background lightgreen
+                               }
+                       }
+               }
+               configure {
+                       if {$use_ttk} {
+                               if {[set n [lsearch -exact $args -background]] != -1} {
+                                       set args [lreplace $args $n [incr n]]
+                                       if {[llength $args] == 0} {return}
+                               }
+                       }
+                       return [uplevel 1 [list _$w $cmd] $args]
+               }
+               default { return [uplevel 1 [list _$w $cmd] $args] }
+       }
+}
+
 # Tk 8.6 provides a standard font selection dialog. This uses the native
 # dialogs on Windows and MacOSX or a standard Tk dialog on X11.
 proc tchoosefont {w title familyvar sizevar} {
index 95e6e5553ea86482d0fe9be77b07e805e01e3393..6ec94113db7d8c75d78e5300469bb8154e37c940 100644 (file)
@@ -87,8 +87,14 @@ proc tools_exec {fullname} {
                        return
                }
        } elseif {[is_config_true "guitool.$fullname.confirm"]} {
-               if {[ask_popup [mc "Are you sure you want to run %s?" $fullname]] ne {yes}} {
-                       return
+               if {[is_config_true "guitool.$fullname.needsfile"]} {
+                       if {[ask_popup [mc "Are you sure you want to run %1\$s on file \"%2\$s\"?" $fullname $current_diff_path]] ne {yes}} {
+                               return
+                       }
+               } else {
+                       if {[ask_popup [mc "Are you sure you want to run %s?" $fullname]] ne {yes}} {
+                               return
+                       }
                }
        }
 
index 7fad9b7d91a6d6a0671ca7bac714dcc4fd022403..e5d211edea05cbfb856e81a9d683a5fb0f4f4b20 100644 (file)
@@ -124,6 +124,7 @@ proc do_push_anywhere {} {
 
        set w .push_setup
        toplevel $w
+       catch {wm attributes $w -type dialog}
        wm withdraw $w
        wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
        pave_toplevel $w
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;
index 4f0c3bd90c7f90dad1674f50999da534c33c0261..f80f2594cb2e498fa788d38f5b06c88e2fef95ca 100755 (executable)
@@ -759,6 +759,7 @@ sub check_loadavg {
        extra_options => "opt",
        search_use_regexp => "sr",
        ctag => "by_tag",
+       diff_style => "ds",
        # this must be last entry (for manipulation from JavaScript)
        javascript => "js"
 );
@@ -2225,93 +2226,119 @@ sub format_diff_cc_simplified {
        return $result;
 }
 
-# format patch (diff) line (not to be used for diff headers)
-sub format_diff_line {
-       my $line = shift;
-       my ($from, $to) = @_;
-       my $diff_class = "";
-
-       chomp $line;
+sub diff_line_class {
+       my ($line, $from, $to) = @_;
 
+       # ordinary diff
+       my $num_sign = 1;
+       # combined diff
        if ($from && $to && ref($from->{'href'}) eq "ARRAY") {
-               # combined diff
-               my $prefix = substr($line, 0, scalar @{$from->{'href'}});
-               if ($line =~ m/^\@{3}/) {
-                       $diff_class = " chunk_header";
-               } elsif ($line =~ m/^\\/) {
-                       $diff_class = " incomplete";
-               } elsif ($prefix =~ tr/+/+/) {
-                       $diff_class = " add";
-               } elsif ($prefix =~ tr/-/-/) {
-                       $diff_class = " rem";
-               }
-       } else {
-               # assume ordinary diff
-               my $char = substr($line, 0, 1);
-               if ($char eq '+') {
-                       $diff_class = " add";
-               } elsif ($char eq '-') {
-                       $diff_class = " rem";
-               } elsif ($char eq '@') {
-                       $diff_class = " chunk_header";
-               } elsif ($char eq "\\") {
-                       $diff_class = " incomplete";
-               }
+               $num_sign = scalar @{$from->{'href'}};
+       }
+
+       my @diff_line_classifier = (
+               { regexp => qr/^\@\@{$num_sign} /, class => "chunk_header"},
+               { regexp => qr/^\\/,               class => "incomplete"  },
+               { regexp => qr/^ {$num_sign}/,     class => "ctx" },
+               # classifier for context must come before classifier add/rem,
+               # or we would have to use more complicated regexp, for example
+               # qr/(?= {0,$m}\+)[+ ]{$num_sign}/, where $m = $num_sign - 1;
+               { regexp => qr/^[+ ]{$num_sign}/,   class => "add" },
+               { regexp => qr/^[- ]{$num_sign}/,   class => "rem" },
+       );
+       for my $clsfy (@diff_line_classifier) {
+               return $clsfy->{'class'}
+                       if ($line =~ $clsfy->{'regexp'});
        }
-       $line = untabify($line);
-       if ($from && $to && $line =~ m/^\@{2} /) {
-               my ($from_text, $from_start, $from_lines, $to_text, $to_start, $to_lines, $section) =
-                       $line =~ m/^\@{2} (-(\d+)(?:,(\d+))?) (\+(\d+)(?:,(\d+))?) \@{2}(.*)$/;
 
-               $from_lines = 0 unless defined $from_lines;
-               $to_lines   = 0 unless defined $to_lines;
+       # fallback
+       return "";
+}
 
-               if ($from->{'href'}) {
-                       $from_text = $cgi->a({-href=>"$from->{'href'}#l$from_start",
-                                            -class=>"list"}, $from_text);
-               }
-               if ($to->{'href'}) {
-                       $to_text   = $cgi->a({-href=>"$to->{'href'}#l$to_start",
-                                            -class=>"list"}, $to_text);
-               }
-               $line = "<span class=\"chunk_info\">@@ $from_text $to_text @@</span>" .
-                       "<span class=\"section\">" . esc_html($section, -nbsp=>1) . "</span>";
-               return "<div class=\"diff$diff_class\">$line</div>\n";
-       } elsif ($from && $to && $line =~ m/^\@{3}/) {
-               my ($prefix, $ranges, $section) = $line =~ m/^(\@+) (.*?) \@+(.*)$/;
-               my (@from_text, @from_start, @from_nlines, $to_text, $to_start, $to_nlines);
+# assumes that $from and $to are defined and correctly filled,
+# and that $line holds a line of chunk header for unified diff
+sub format_unidiff_chunk_header {
+       my ($line, $from, $to) = @_;
 
-               @from_text = split(' ', $ranges);
-               for (my $i = 0; $i < @from_text; ++$i) {
-                       ($from_start[$i], $from_nlines[$i]) =
-                               (split(',', substr($from_text[$i], 1)), 0);
-               }
+       my ($from_text, $from_start, $from_lines, $to_text, $to_start, $to_lines, $section) =
+               $line =~ m/^\@{2} (-(\d+)(?:,(\d+))?) (\+(\d+)(?:,(\d+))?) \@{2}(.*)$/;
 
-               $to_text   = pop @from_text;
-               $to_start  = pop @from_start;
-               $to_nlines = pop @from_nlines;
+       $from_lines = 0 unless defined $from_lines;
+       $to_lines   = 0 unless defined $to_lines;
 
-               $line = "<span class=\"chunk_info\">$prefix ";
-               for (my $i = 0; $i < @from_text; ++$i) {
-                       if ($from->{'href'}[$i]) {
-                               $line .= $cgi->a({-href=>"$from->{'href'}[$i]#l$from_start[$i]",
-                                                 -class=>"list"}, $from_text[$i]);
-                       } else {
-                               $line .= $from_text[$i];
-                       }
-                       $line .= " ";
-               }
-               if ($to->{'href'}) {
-                       $line .= $cgi->a({-href=>"$to->{'href'}#l$to_start",
-                                         -class=>"list"}, $to_text);
+       if ($from->{'href'}) {
+               $from_text = $cgi->a({-href=>"$from->{'href'}#l$from_start",
+                                    -class=>"list"}, $from_text);
+       }
+       if ($to->{'href'}) {
+               $to_text   = $cgi->a({-href=>"$to->{'href'}#l$to_start",
+                                    -class=>"list"}, $to_text);
+       }
+       $line = "<span class=\"chunk_info\">@@ $from_text $to_text @@</span>" .
+               "<span class=\"section\">" . esc_html($section, -nbsp=>1) . "</span>";
+       return $line;
+}
+
+# assumes that $from and $to are defined and correctly filled,
+# and that $line holds a line of chunk header for combined diff
+sub format_cc_diff_chunk_header {
+       my ($line, $from, $to) = @_;
+
+       my ($prefix, $ranges, $section) = $line =~ m/^(\@+) (.*?) \@+(.*)$/;
+       my (@from_text, @from_start, @from_nlines, $to_text, $to_start, $to_nlines);
+
+       @from_text = split(' ', $ranges);
+       for (my $i = 0; $i < @from_text; ++$i) {
+               ($from_start[$i], $from_nlines[$i]) =
+                       (split(',', substr($from_text[$i], 1)), 0);
+       }
+
+       $to_text   = pop @from_text;
+       $to_start  = pop @from_start;
+       $to_nlines = pop @from_nlines;
+
+       $line = "<span class=\"chunk_info\">$prefix ";
+       for (my $i = 0; $i < @from_text; ++$i) {
+               if ($from->{'href'}[$i]) {
+                       $line .= $cgi->a({-href=>"$from->{'href'}[$i]#l$from_start[$i]",
+                                         -class=>"list"}, $from_text[$i]);
                } else {
-                       $line .= $to_text;
+                       $line .= $from_text[$i];
                }
-               $line .= " $prefix</span>" .
-                        "<span class=\"section\">" . esc_html($section, -nbsp=>1) . "</span>";
-               return "<div class=\"diff$diff_class\">$line</div>\n";
+               $line .= " ";
        }
-       return "<div class=\"diff$diff_class\">" . esc_html($line, -nbsp=>1) . "</div>\n";
+       if ($to->{'href'}) {
+               $line .= $cgi->a({-href=>"$to->{'href'}#l$to_start",
+                                 -class=>"list"}, $to_text);
+       } else {
+               $line .= $to_text;
+       }
+       $line .= " $prefix</span>" .
+                "<span class=\"section\">" . esc_html($section, -nbsp=>1) . "</span>";
+       return $line;
+}
+
+# process patch (diff) line (not to be used for diff headers),
+# returning class and HTML-formatted (but not wrapped) line
+sub process_diff_line {
+       my $line = shift;
+       my ($from, $to) = @_;
+
+       my $diff_class = diff_line_class($line, $from, $to);
+
+       chomp $line;
+       $line = untabify($line);
+
+       if ($from && $to && $line =~ m/^\@{2} /) {
+               $line = format_unidiff_chunk_header($line, $from, $to);
+               return $diff_class, $line;
+
+       } elsif ($from && $to && $line =~ m/^\@{3}/) {
+               $line = format_cc_diff_chunk_header($line, $from, $to);
+               return $diff_class, $line;
+
+       }
+       return $diff_class, esc_html($line, -nbsp=>1);
 }
 
 # Generates undef or something like "_snapshot_" or "snapshot (_tbz2_ _zip_)",
@@ -4833,8 +4860,97 @@ sub git_difftree_body {
        print "</table>\n";
 }
 
+sub print_sidebyside_diff_chunk {
+       my @chunk = @_;
+       my (@ctx, @rem, @add);
+
+       return unless @chunk;
+
+       # incomplete last line might be among removed or added lines,
+       # or both, or among context lines: find which
+       for (my $i = 1; $i < @chunk; $i++) {
+               if ($chunk[$i][0] eq 'incomplete') {
+                       $chunk[$i][0] = $chunk[$i-1][0];
+               }
+       }
+
+       # guardian
+       push @chunk, ["", ""];
+
+       foreach my $line_info (@chunk) {
+               my ($class, $line) = @$line_info;
+
+               # print chunk headers
+               if ($class && $class eq 'chunk_header') {
+                       print $line;
+                       next;
+               }
+
+               ## print from accumulator when type of class of lines change
+               # empty contents block on start rem/add block, or end of chunk
+               if (@ctx && (!$class || $class eq 'rem' || $class eq 'add')) {
+                       print join '',
+                               '<div class="chunk_block ctx">',
+                                       '<div class="old">',
+                                       @ctx,
+                                       '</div>',
+                                       '<div class="new">',
+                                       @ctx,
+                                       '</div>',
+                               '</div>';
+                       @ctx = ();
+               }
+               # empty add/rem block on start context block, or end of chunk
+               if ((@rem || @add) && (!$class || $class eq 'ctx')) {
+                       if (!@add) {
+                               # pure removal
+                               print join '',
+                                       '<div class="chunk_block rem">',
+                                               '<div class="old">',
+                                               @rem,
+                                               '</div>',
+                                       '</div>';
+                       } elsif (!@rem) {
+                               # pure addition
+                               print join '',
+                                       '<div class="chunk_block add">',
+                                               '<div class="new">',
+                                               @add,
+                                               '</div>',
+                                       '</div>';
+                       } else {
+                               # assume that it is change
+                               print join '',
+                                       '<div class="chunk_block chg">',
+                                               '<div class="old">',
+                                               @rem,
+                                               '</div>',
+                                               '<div class="new">',
+                                               @add,
+                                               '</div>',
+                                       '</div>';
+                       }
+                       @rem = @add = ();
+               }
+
+               ## adding lines to accumulator
+               # guardian value
+               last unless $line;
+               # rem, add or change
+               if ($class eq 'rem') {
+                       push @rem, $line;
+               } elsif ($class eq 'add') {
+                       push @add, $line;
+               }
+               # context line
+               if ($class eq 'ctx') {
+                       push @ctx, $line;
+               }
+       }
+}
+
 sub git_patchset_body {
-       my ($fd, $difftree, $hash, @hash_parents) = @_;
+       my ($fd, $diff_style, $difftree, $hash, @hash_parents) = @_;
        my ($hash_parent) = $hash_parents[0];
 
        my $is_combined = (@hash_parents > 1);
@@ -4844,6 +4960,7 @@ sub git_patchset_body {
        my $diffinfo;
        my $to_name;
        my (%from, %to);
+       my @chunk; # for side-by-side diff
 
        print "<div class=\"patchset\">\n";
 
@@ -4950,10 +5067,29 @@ sub git_patchset_body {
 
                        next PATCH if ($patch_line =~ m/^diff /);
 
-                       print format_diff_line($patch_line, \%from, \%to);
+                       my ($class, $line) = process_diff_line($patch_line, \%from, \%to);
+                       my $diff_classes = "diff";
+                       $diff_classes .= " $class" if ($class);
+                       $line = "<div class=\"$diff_classes\">$line</div>\n";
+
+                       if ($diff_style eq 'sidebyside' && !$is_combined) {
+                               if ($class eq 'chunk_header') {
+                                       print_sidebyside_diff_chunk(@chunk);
+                                       @chunk = ( [ $class, $line ] );
+                               } else {
+                                       push @chunk, [ $class, $line ];
+                               }
+                       } else {
+                               # default 'inline' style and unknown styles
+                               print $line;
+                       }
                }
 
        } continue {
+               if (@chunk) {
+                       print_sidebyside_diff_chunk(@chunk);
+                       @chunk = ();
+               }
                print "</div>\n"; # class="patch"
        }
 
@@ -6949,6 +7085,7 @@ sub git_object {
 
 sub git_blobdiff {
        my $format = shift || 'html';
+       my $diff_style = $input_params{'diff_style'} || 'inline';
 
        my $fd;
        my @difftree;
@@ -7027,6 +7164,7 @@ sub git_blobdiff {
                my $formats_nav =
                        $cgi->a({-href => href(action=>"blobdiff_plain", -replay=>1)},
                                "raw");
+               $formats_nav .= diff_style_nav($diff_style);
                git_header_html(undef, $expires);
                if (defined $hash_base && (my %co = parse_commit($hash_base))) {
                        git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav);
@@ -7058,7 +7196,8 @@ sub git_blobdiff {
        if ($format eq 'html') {
                print "<div class=\"page_body\">\n";
 
-               git_patchset_body($fd, [ \%diffinfo ], $hash_base, $hash_parent_base);
+               git_patchset_body($fd, $diff_style,
+                                 [ \%diffinfo ], $hash_base, $hash_parent_base);
                close $fd;
 
                print "</div>\n"; # class="page_body"
@@ -7083,9 +7222,31 @@ sub git_blobdiff_plain {
        git_blobdiff('plain');
 }
 
+# assumes that it is added as later part of already existing navigation,
+# so it returns "| foo | bar" rather than just "foo | bar"
+sub diff_style_nav {
+       my ($diff_style, $is_combined) = @_;
+       $diff_style ||= 'inline';
+
+       return "" if ($is_combined);
+
+       my @styles = (inline => 'inline', 'sidebyside' => 'side by side');
+       my %styles = @styles;
+       @styles =
+               @styles[ map { $_ * 2 } 0..$#styles/2 ];
+
+       return join '',
+               map { " | ".$_ }
+               map {
+                       $_ eq $diff_style ? $styles{$_} :
+                       $cgi->a({-href => href(-replay=>1, diff_style => $_)}, $styles{$_})
+               } @styles;
+}
+
 sub git_commitdiff {
        my %params = @_;
        my $format = $params{-format} || 'html';
+       my $diff_style = $input_params{'diff_style'} || 'inline';
 
        my ($patch_max) = gitweb_get_feature('patches');
        if ($format eq 'patch') {
@@ -7111,6 +7272,7 @@ sub git_commitdiff {
                                $cgi->a({-href => href(action=>"patch", -replay=>1)},
                                        "patch");
                }
+               $formats_nav .= diff_style_nav($diff_style, @{$co{'parents'}} > 1);
 
                if (defined $hash_parent &&
                    $hash_parent ne '-c' && $hash_parent ne '--cc') {
@@ -7128,8 +7290,8 @@ sub git_commitdiff {
                                }
                        }
                        $formats_nav .= ': ' .
-                               $cgi->a({-href => href(action=>"commitdiff",
-                                                      hash=>$hash_parent)},
+                               $cgi->a({-href => href(-replay=>1,
+                                                      hash=>$hash_parent, hash_base=>undef)},
                                        esc_html($hash_parent_short)) .
                                ')';
                } elsif (!$co{'parent'}) {
@@ -7139,28 +7301,28 @@ sub git_commitdiff {
                        # single parent commit
                        $formats_nav .=
                                ' (parent: ' .
-                               $cgi->a({-href => href(action=>"commitdiff",
-                                                      hash=>$co{'parent'})},
+                               $cgi->a({-href => href(-replay=>1,
+                                                      hash=>$co{'parent'}, hash_base=>undef)},
                                        esc_html(substr($co{'parent'}, 0, 7))) .
                                ')';
                } else {
                        # merge commit
                        if ($hash_parent eq '--cc') {
                                $formats_nav .= ' | ' .
-                                       $cgi->a({-href => href(action=>"commitdiff",
+                                       $cgi->a({-href => href(-replay=>1,
                                                               hash=>$hash, hash_parent=>'-c')},
                                                'combined');
                        } else { # $hash_parent eq '-c'
                                $formats_nav .= ' | ' .
-                                       $cgi->a({-href => href(action=>"commitdiff",
+                                       $cgi->a({-href => href(-replay=>1,
                                                               hash=>$hash, hash_parent=>'--cc')},
                                                'compact');
                        }
                        $formats_nav .=
                                ' (merge: ' .
                                join(' ', map {
-                                       $cgi->a({-href => href(action=>"commitdiff",
-                                                              hash=>$_)},
+                                       $cgi->a({-href => href(-replay=>1,
+                                                              hash=>$_, hash_base=>undef)},
                                                esc_html(substr($_, 0, 7)));
                                } @{$co{'parents'}} ) .
                                ')';
@@ -7289,7 +7451,8 @@ sub git_commitdiff {
                                  $use_parents ? @{$co{'parents'}} : $hash_parent);
                print "<br/>\n";
 
-               git_patchset_body($fd, \@difftree, $hash,
+               git_patchset_body($fd, $diff_style,
+                                 \@difftree, $hash,
                                  $use_parents ? @{$co{'parents'}} : $hash_parent);
                close $fd;
                print "</div>\n"; # class="page_body"
index 7d88509208417e4b1222629002ea339ecc32526e..c7827e8f1d2f9239bca42d80d2efbaa025300bbb 100644 (file)
@@ -475,6 +475,36 @@ div.diff.nodifferences {
        color: #600000;
 }
 
+/* side-by-side diff */
+div.chunk_block {
+       overflow: hidden;
+}
+
+div.chunk_block div.old {
+       float: left;
+       width: 50%;
+       overflow: hidden;
+}
+
+div.chunk_block div.new {
+       margin-left: 50%;
+       width: 50%;
+}
+
+div.chunk_block.rem div.old div.diff.rem {
+       background-color: #fff5f5;
+}
+div.chunk_block.add div.new div.diff.add {
+       background-color: #f8fff8;
+}
+div.chunk_block.chg div     div.diff {
+       background-color: #fffff0;
+}
+div.chunk_block.ctx div     div.diff.ctx {
+       color: #404040;
+}
+
+
 div.index_include {
        border: solid #d9d8d1;
        border-width: 0px 0px 1px;
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 e6c75976e8886321732ef2b0b686b08e04a0c200..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
@@ -814,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);
@@ -862,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);
 
@@ -1057,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);
@@ -1079,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)
@@ -1148,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);
@@ -1205,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 e1ad1a48ce3b8bd8517568a67477d8d0e32dfaa8..80e0e8c051ad26a3a1353a4beb21e5c6ebdd6823 100644 (file)
@@ -161,7 +161,6 @@ static struct imap_server_conf server = {
 struct imap_store_conf {
        struct store_conf gen;
        struct imap_server_conf *server;
-       unsigned use_namespace:1;
 };
 
 #define NIL    (void *)0x1
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 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 ce10aacf2978024eda0234482964577e9235f2d2..2de27af751476a62dc9b0afe48eb360f83a0702b 100644 (file)
@@ -573,7 +573,7 @@ int notes_merge(struct notes_merge_options *o,
               o->local_ref, o->remote_ref);
 
        /* Dereference o->local_ref into local_sha1 */
-       if (!resolve_ref(o->local_ref, local_sha1, 0, NULL))
+       if (read_ref_full(o->local_ref, local_sha1, 0, NULL))
                die("Failed to resolve local notes ref '%s'", o->local_ref);
        else if (!check_refname_format(o->local_ref, 0) &&
                is_null_sha1(local_sha1))
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 */
index 5d81d39a525830f6bacba88143ab6a4552748441..da71a85851aa3664f14b406c57cbedbee79591f2 100644 (file)
@@ -51,8 +51,11 @@ static struct complete_reflogs *read_complete_reflog(const char *ref)
        if (reflogs->nr == 0) {
                unsigned char sha1[20];
                const char *name = resolve_ref(ref, sha1, 1, NULL);
-               if (name)
+               if (name) {
+                       name = xstrdup(name);
                        for_each_reflog_ent(name, read_one_reflog, reflogs);
+                       free((char *)name);
+               }
        }
        if (reflogs->nr == 0) {
                int len = strlen(ref);
diff --git a/refs.c b/refs.c
index e7843eb6b70b7de6c1ed1992db7adee1d99b27bc..f5cb297292f5ae577e3d2719f5f78512aae8cf28 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -334,7 +334,7 @@ static void get_ref_dir(const char *submodule, const char *base,
                                        hashclr(sha1);
                                        flag |= REF_ISBROKEN;
                                }
-                       } else if (!resolve_ref(ref, sha1, 1, &flag)) {
+                       } else if (read_ref_full(ref, sha1, 1, &flag)) {
                                hashclr(sha1);
                                flag |= REF_ISBROKEN;
                        }
@@ -612,13 +612,18 @@ struct ref_filter {
        void *cb_data;
 };
 
-int read_ref(const char *ref, unsigned char *sha1)
+int read_ref_full(const char *ref, unsigned char *sha1, int reading, int *flags)
 {
-       if (resolve_ref(ref, sha1, 1, NULL))
+       if (resolve_ref(ref, sha1, reading, flags))
                return 0;
        return -1;
 }
 
+int read_ref(const char *ref, unsigned char *sha1)
+{
+       return read_ref_full(ref, sha1, 1, NULL);
+}
+
 #define DO_FOR_EACH_INCLUDE_BROKEN 01
 static int do_one_ref(const char *base, each_ref_fn fn, int trim,
                      int flags, void *cb_data, struct ref_entry *entry)
@@ -663,7 +668,7 @@ int peel_ref(const char *ref, unsigned char *sha1)
                goto fallback;
        }
 
-       if (!resolve_ref(ref, base, 1, &flag))
+       if (read_ref_full(ref, base, 1, &flag))
                return -1;
 
        if ((flag & REF_ISPACKED)) {
@@ -746,7 +751,7 @@ static int do_head_ref(const char *submodule, each_ref_fn fn, void *cb_data)
                return 0;
        }
 
-       if (resolve_ref("HEAD", sha1, 1, &flag))
+       if (!read_ref_full("HEAD", sha1, 1, &flag))
                return fn("HEAD", sha1, flag, cb_data);
 
        return 0;
@@ -826,7 +831,7 @@ int head_ref_namespaced(each_ref_fn fn, void *cb_data)
        int flag;
 
        strbuf_addf(&buf, "%sHEAD", get_git_namespace());
-       if (resolve_ref(buf.buf, sha1, 1, &flag))
+       if (!read_ref_full(buf.buf, sha1, 1, &flag))
                ret = fn(buf.buf, sha1, flag, cb_data);
        strbuf_release(&buf);
 
@@ -998,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;
@@ -1022,7 +1020,7 @@ int refname_match(const char *abbrev_name, const char *full_name, const char **r
 static struct ref_lock *verify_lock(struct ref_lock *lock,
        const unsigned char *old_sha1, int mustexist)
 {
-       if (!resolve_ref(lock->ref_name, lock->old_sha1, mustexist, NULL)) {
+       if (read_ref_full(lock->ref_name, lock->old_sha1, mustexist, NULL)) {
                error("Can't verify ref %s", lock->ref_name);
                unlock_ref(lock);
                return NULL;
@@ -1377,7 +1375,8 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)
                goto rollback;
        }
 
-       if (resolve_ref(newref, sha1, 1, &flag) && delete_ref(newref, sha1, REF_NODEREF)) {
+       if (!read_ref_full(newref, sha1, 1, &flag) &&
+           delete_ref(newref, sha1, REF_NODEREF)) {
                if (errno==EISDIR) {
                        if (remove_empty_directories(git_path("%s", newref))) {
                                error("Directory not empty: %s", newref);
@@ -1929,7 +1928,7 @@ static int do_for_each_reflog(const char *base, each_ref_fn fn, void *cb_data)
                                retval = do_for_each_reflog(log, fn, cb_data);
                        } else {
                                unsigned char sha1[20];
-                               if (!resolve_ref(log, sha1, 0, NULL))
+                               if (read_ref_full(log, sha1, 0, NULL))
                                        retval = error("bad ref for %s", log);
                                else
                                        retval = fn(log, sha1, 0, cb_data);
@@ -2072,7 +2071,6 @@ char *shorten_unambiguous_ref(const char *ref, int strict)
                 */
                for (j = 0; j < rules_to_fail; j++) {
                        const char *rule = ref_rev_parse_rules[j];
-                       unsigned char short_objectname[20];
                        char refname[PATH_MAX];
 
                        /* skip matched rule */
@@ -2086,7 +2084,7 @@ char *shorten_unambiguous_ref(const char *ref, int strict)
                         */
                        mksnpath(refname, sizeof(refname),
                                 rule, short_name_len, short_name);
-                       if (!read_ref(refname, short_objectname))
+                       if (ref_exists(refname))
                                break;
                }
 
index e2ef99114478c49863809ea5cef46392a5a8c0e9..6655bb05b2d31bca080cf3cfc431394b82d89160 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -1507,13 +1507,13 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs)
         * nothing to report.
         */
        base = branch->merge[0]->dst;
-       if (!resolve_ref(base, sha1, 1, NULL))
+       if (read_ref(base, sha1))
                return 0;
        theirs = lookup_commit_reference(sha1);
        if (!theirs)
                return 0;
 
-       if (!resolve_ref(branch->refname, sha1, 1, NULL))
+       if (read_ref(branch->refname, sha1))
                return 0;
        ours = lookup_commit_reference(sha1);
        if (!ours)
index 6dcae3882bf969cce9ae0a973a80abf76e3bb814..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;
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 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 d9068981f8475c37d30e584bc6b795075a2f3063..c05c676ca206c88bf77941d76b0bb717b374c9f8 100755 (executable)
@@ -242,6 +242,14 @@ test_expect_success \
     'git archive --list outside of a git repo' \
     'GIT_DIR=some/non-existing/directory git archive --list'
 
+test_expect_success 'clients cannot access unreachable commits' '
+       test_commit unreachable &&
+       sha1=`git rev-parse HEAD` &&
+       git reset --hard HEAD^ &&
+       git archive $sha1 >remote.tar &&
+       test_must_fail git archive --remote=. $sha1 >remote.tar
+'
+
 test_expect_success 'git-archive --prefix=olde-' '
        git archive --prefix=olde- >h.tar HEAD &&
        (
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 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 3f86e8c5e8c6fedb569d50ee20cf6d71542e5860..83f7ea59c9b4e05aa200bc4ebd77f0c16bd8ef33 100755 (executable)
@@ -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' '
index 53297156a314a5b5e03385a3ad887eff959359c4..ab249178123653943bb087ccc40f2b420cc1e67c 100755 (executable)
@@ -273,6 +273,53 @@ test_expect_success \
        'commitdiff(2): directory becomes symlink' \
        'gitweb_run "p=.git;a=commitdiff;hp=foo-becomes-a-directory;h=foo-symlinked-to-bar"'
 
+# ----------------------------------------------------------------------
+# commitdiff testing (incomplete lines)
+
+test_expect_success 'setup incomplete lines' '
+       cat >file<<-\EOF &&
+       Dominus regit me,
+       et nihil mihi deerit.
+       In loco pascuae ibi me collocavit,
+       super aquam refectionis educavit me;
+       animam meam convertit,
+       deduxit me super semitas jusitiae,
+       propter nomen suum.
+       CHANGE_ME
+       EOF
+       git commit -a -m "Preparing for incomplete lines" &&
+       echo "incomplete" | tr -d "\\012" >>file &&
+       git commit -a -m "Add incomplete line" &&
+       git tag incomplete_lines_add &&
+       sed -e s/CHANGE_ME/change_me/ <file >file+ &&
+       mv -f file+ file &&
+       git commit -a -m "Incomplete context line" &&
+       git tag incomplete_lines_ctx &&
+       echo "Dominus regit me," >file &&
+       echo "incomplete line" | tr -d "\\012" >>file &&
+       git commit -a -m "Change incomplete line" &&
+       git tag incomplete_lines_chg
+       echo "Dominus regit me," >file &&
+       git commit -a -m "Remove incomplete line" &&
+       git tag incomplete_lines_rem
+'
+
+test_expect_success 'commitdiff(1): addition of incomplete line' '
+       gitweb_run "p=.git;a=commitdiff;h=incomplete_lines_add"
+'
+
+test_expect_success 'commitdiff(1): incomplete line as context line' '
+       gitweb_run "p=.git;a=commitdiff;h=incomplete_lines_ctx"
+'
+
+test_expect_success 'commitdiff(1): change incomplete line' '
+       gitweb_run "p=.git;a=commitdiff;h=incomplete_lines_chg"
+'
+
+test_expect_success 'commitdiff(1): removal of incomplete line' '
+       gitweb_run "p=.git;a=commitdiff;h=incomplete_lines_rem"
+'
+
 # ----------------------------------------------------------------------
 # commit, commitdiff: merge, large
 test_expect_success \
@@ -282,7 +329,8 @@ test_expect_success \
         git add b &&
         git commit -a -m "On branch" &&
         git checkout master &&
-        git pull . b'
+        git pull . b &&
+        git tag merge_commit'
 
 test_expect_success \
        'commit(0): merge commit' \
@@ -331,6 +379,29 @@ test_expect_success \
        'commitdiff(1): large commit' \
        'gitweb_run "p=.git;a=commitdiff;h=b"'
 
+# ----------------------------------------------------------------------
+# side-by-side diff
+
+test_expect_success 'side-by-side: addition of incomplete line' '
+       gitweb_run "p=.git;a=commitdiff;h=incomplete_lines_add;ds=sidebyside"
+'
+
+test_expect_success 'side-by-side: incomplete line as context line' '
+       gitweb_run "p=.git;a=commitdiff;h=incomplete_lines_ctx;ds=sidebyside"
+'
+
+test_expect_success 'side-by-side: changed incomplete line' '
+       gitweb_run "p=.git;a=commitdiff;h=incomplete_lines_chg;ds=sidebyside"
+'
+
+test_expect_success 'side-by-side: removal of incomplete line' '
+       gitweb_run "p=.git;a=commitdiff;h=incomplete_lines_rem;ds=sidebyside"
+'
+
+test_expect_success 'side-by-side: merge commit' '
+       gitweb_run "p=.git;a=commitdiff;h=merge_commit;ds=sidebyside"
+'
+
 # ----------------------------------------------------------------------
 # tags testing
 
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/t/t9807-submit.sh b/t/t9807-submit.sh
new file mode 100755 (executable)
index 0000000..2cb724e
--- /dev/null
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+test_description='git-p4 submit'
+
+. ./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"
+       )
+'
+
+test_expect_success 'submit with no client dir' '
+       test_when_finished cleanup_git &&
+       "$GITP4" clone --dest="$git" //depot &&
+       (
+               cd "$git" &&
+               echo file2 >file2 &&
+               git add file2 &&
+               git commit -m "git commit 2" &&
+               rm -rf "$cli" &&
+               git config git-p4.skipSubmitEdit true &&
+               "$GITP4" submit
+       )
+'
+
+test_expect_success 'kill p4d' '
+       kill_p4d
+'
+
+test_done
diff --git a/t/t9808-chdir.sh b/t/t9808-chdir.sh
new file mode 100755 (executable)
index 0000000..eb8cc95
--- /dev/null
@@ -0,0 +1,49 @@
+#!/bin/sh
+
+test_description='git-p4 relative chdir'
+
+. ./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"
+       )
+'
+
+# P4 reads from P4CONFIG file to find its server params, if the
+# environment variable is set
+test_expect_success 'P4CONFIG and absolute dir clone' '
+       printf "P4PORT=$P4PORT\nP4CLIENT=$P4CLIENT\n" >p4config &&
+       test_when_finished "rm \"$TRASH_DIRECTORY/p4config\"" &&
+       test_when_finished cleanup_git &&
+       (
+               P4CONFIG=p4config && export P4CONFIG &&
+               unset P4PORT P4CLIENT &&
+               "$GITP4" clone --verbose --dest="$git" //depot
+       )
+'
+
+# same thing, but with relative directory name, note missing $ on --dest
+test_expect_success 'P4CONFIG and relative dir clone' '
+       printf "P4PORT=$P4PORT\nP4CLIENT=$P4CLIENT\n" >p4config &&
+       test_when_finished "rm \"$TRASH_DIRECTORY/p4config\"" &&
+       test_when_finished cleanup_git &&
+       (
+               P4CONFIG=p4config && export P4CONFIG &&
+               unset P4PORT P4CLIENT &&
+               "$GITP4" clone --verbose --dest="git" //depot
+       )
+'
+
+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"