Merge branch 'master' of git://github.com/git-l10n/git-po
authorJiang Xin <worldhello.net@gmail.com>
Sat, 6 Jan 2018 23:49:43 +0000 (07:49 +0800)
committerJiang Xin <worldhello.net@gmail.com>
Sat, 6 Jan 2018 23:49:43 +0000 (07:49 +0800)
* 'master' of git://github.com/git-l10n/git-po:
l10n: es.po: Update Spanish Translation v2.16.0
l10n: fr.po v2.16.0 round 1
l10n: bg.po: Updated Bulgarian translation (3284t)
l10n: sv.po: Update Swedish translation (3284t0f0u)
l10n: fr.po: "worktree list" mistranslated as prune
l10n: git.pot: v2.16.0 round 1 (64 new, 25 removed)
l10n: fixes to German translation
l10n: Update Spanish translation
l10n: zh_CN translate parameter name
l10n: zh_CN Fix typo
l10n: Fixes to Catalan translation

22 files changed:
Documentation/RelNotes/2.16.0.txt
Documentation/config.txt
Documentation/git-p4.txt
GIT-VERSION-GEN
Makefile
builtin/am.c
cache.h
git-p4.py
git-rebase--interactive.sh
http.c
merge-recursive.c
merge.c
send-pack.c
sequencer.c
strbuf.c
t/Makefile
t/check-non-portable-shell.pl
t/helper/test-lazy-init-name-hash.c
t/t5615-alternate-env.sh
t/t6044-merge-unrelated-index-changes.sh
t/t9807-git-p4-submit.sh
t/test-lib.sh
index 8f0461eefd98ee3f44f7903ee33b98f0dcd0eb18..c648c128e87e2ddc64fd0d4e6cf078d47ac9ce68 100644 (file)
@@ -433,6 +433,14 @@ Fixes since v2.15
    from strings read from various "state" files.
    (merge 041fe8fc83 ra/prompt-eread-fix later to maint).
 
+ * "git merge -s recursive" did not correctly abort when the index is
+   dirty, if the merged tree happened to be the same as the current
+   HEAD, which has been fixed.
+
+ * Bytes with high-bit set were encoded incorrectly and made
+   credential helper fail.
+   (merge 4c267f2ae3 jd/fix-strbuf-add-urlencode-bytes later to maint).
+
  * Other minor doc, test and build updates and code cleanups.
    (merge 1a1fc2d5b5 rd/man-prune-progress later to maint).
    (merge 0ba014035a rd/man-reflog-add-n later to maint).
@@ -456,3 +464,6 @@ Fixes since v2.15
    (merge c07b3adff1 bw/path-doc later to maint).
    (merge bf9d7df950 tz/lib-git-svn-svnserve-tests later to maint).
    (merge dec366c9a8 sr/http-sslverify-config-doc later to maint).
+   (merge 3f824e91c8 jk/test-suite-tracing later to maint).
+   (merge 1feb061701 db/doc-config-section-names-with-bs later to maint).
+   (merge 74dea0e13c jh/memihash-opt later to maint).
index 64c1dbba940f1b3fe18117199b343adf258c0d78..0e25b2c92b309330f27ce562e0f21f4e10179879 100644 (file)
@@ -41,11 +41,13 @@ in the section header, like in the example below:
 --------
 
 Subsection names are case sensitive and can contain any characters except
-newline (doublequote `"` and backslash can be included by escaping them
-as `\"` and `\\`, respectively).  Section headers cannot span multiple
-lines.  Variables may belong directly to a section or to a given subsection.
-You can have `[section]` if you have `[section "subsection"]`, but you
-don't need to.
+newline and the null byte. Doublequote `"` and backslash can be included
+by escaping them as `\"` and `\\`, respectively. Backslashes preceding
+other characters are dropped when reading; for example, `\t` is read as
+`t` and `\0` is read as `0` Section headers cannot span multiple lines.
+Variables may belong directly to a section or to a given subsection. You
+can have `[section]` if you have `[section "subsection"]`, but you don't
+need to.
 
 There is also a deprecated `[section.subsection]` syntax. With this
 syntax, the subsection name is converted to lower-case and is also
index 7436c64a95616d84af9922958e4ccacd0c28519a..d8c8f11c9f2dc94a2f4d46445e33c4f1494ab39e 100644 (file)
@@ -157,6 +157,12 @@ The p4 changes will be created as the user invoking 'git p4 submit'. The
 according to the author of the Git commit.  This option requires admin
 privileges in p4, which can be granted using 'p4 protect'.
 
+To shelve changes instead of submitting, use `--shelve` and `--update-shelve`:
+
+----
+$ git p4 submit --shelve
+$ git p4 submit --update-shelve 1234 --update-shelve 2345
+----
 
 OPTIONS
 -------
@@ -310,7 +316,7 @@ These options can be used to modify 'git p4 submit' behavior.
 
 --update-shelve CHANGELIST::
        Update an existing shelved changelist with this commit. Implies
-       --shelve.
+       --shelve. Repeat for multiple shelved changelists.
 
 --conflict=(ask|skip|quit)::
        Conflicts can occur when applying a commit to p4.  When this
index 4eba7701a0ff7667d241ad2741a5d3b2611ec9d7..e55ac4cb6821ee8492f7c1c18ae78816c870d6f0 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v2.16.0-rc0
+DEF_VER=v2.16.0-rc1
 
 LF='
 '
index 2a81ae22e92cc5a92507666340d340cef3c6b418..bb5b7cdfb695ee7f15128d5885ea74a4e34f5b9b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -426,6 +426,10 @@ all::
 # to say "export LESS=FRX (and LV=-c) if the environment variable
 # LESS (and LV) is not set, respectively".
 #
+# Define TEST_SHELL_PATH if you want to use a shell besides SHELL_PATH for
+# running the test scripts (e.g., bash has better support for "set -x"
+# tracing).
+#
 # When cross-compiling, define HOST_CPU as the canonical name of the CPU on
 # which the built Git will run (for instance "x86_64").
 
@@ -733,6 +737,8 @@ endif
 export PERL_PATH
 export PYTHON_PATH
 
+TEST_SHELL_PATH = $(SHELL_PATH)
+
 LIB_FILE = libgit.a
 XDIFF_LIB = xdiff/lib.a
 VCSSVN_LIB = vcs-svn/lib.a
@@ -1738,6 +1744,7 @@ prefix_SQ = $(subst ','\'',$(prefix))
 gitwebdir_SQ = $(subst ','\'',$(gitwebdir))
 
 SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
+TEST_SHELL_PATH_SQ = $(subst ','\'',$(TEST_SHELL_PATH))
 PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH))
 PYTHON_PATH_SQ = $(subst ','\'',$(PYTHON_PATH))
 TCLTK_PATH_SQ = $(subst ','\'',$(TCLTK_PATH))
@@ -2370,6 +2377,7 @@ GIT-LDFLAGS: FORCE
 # and the first level quoting from the shell that runs "echo".
 GIT-BUILD-OPTIONS: FORCE
        @echo SHELL_PATH=\''$(subst ','\'',$(SHELL_PATH_SQ))'\' >$@+
+       @echo TEST_SHELL_PATH=\''$(subst ','\'',$(TEST_SHELL_PATH_SQ))'\' >>$@+
        @echo PERL_PATH=\''$(subst ','\'',$(PERL_PATH_SQ))'\' >>$@+
        @echo DIFF=\''$(subst ','\'',$(subst ','\'',$(DIFF)))'\' >>$@+
        @echo PYTHON_PATH=\''$(subst ','\'',$(PYTHON_PATH_SQ))'\' >>$@+
index 06b824518fbdfd883e1905eaafdb0001b87f91a0..acfe9d3c8cd6dbd8362c17d55dc036ce6682ce8a 100644 (file)
@@ -1146,43 +1146,6 @@ static void refresh_and_write_cache(void)
                die(_("unable to write index file"));
 }
 
-/**
- * Returns 1 if the index differs from HEAD, 0 otherwise. When on an unborn
- * branch, returns 1 if there are entries in the index, 0 otherwise. If an
- * strbuf is provided, the space-separated list of files that differ will be
- * appended to it.
- */
-static int index_has_changes(struct strbuf *sb)
-{
-       struct object_id head;
-       int i;
-
-       if (!get_oid_tree("HEAD", &head)) {
-               struct diff_options opt;
-
-               diff_setup(&opt);
-               opt.flags.exit_with_status = 1;
-               if (!sb)
-                       opt.flags.quick = 1;
-               do_diff_cache(&head, &opt);
-               diffcore_std(&opt);
-               for (i = 0; sb && i < diff_queued_diff.nr; i++) {
-                       if (i)
-                               strbuf_addch(sb, ' ');
-                       strbuf_addstr(sb, diff_queued_diff.queue[i]->two->path);
-               }
-               diff_flush(&opt);
-               return opt.flags.has_changes != 0;
-       } else {
-               for (i = 0; sb && i < active_nr; i++) {
-                       if (i)
-                               strbuf_addch(sb, ' ');
-                       strbuf_addstr(sb, active_cache[i]->name);
-               }
-               return !!active_nr;
-       }
-}
-
 /**
  * Dies with a user-friendly message on how to proceed after resolving the
  * problem. This message can be overridden with state->resolvemsg.
diff --git a/cache.h b/cache.h
index a2ec8c0b55422f2b95a30d140cb2bfdf15f0721d..d8b975a5715e8a5ec7c32e176958725cba61d67a 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -644,6 +644,15 @@ extern int write_locked_index(struct index_state *, struct lock_file *lock, unsi
 extern int discard_index(struct index_state *);
 extern void move_index_extensions(struct index_state *dst, struct index_state *src);
 extern int unmerged_index(const struct index_state *);
+
+/**
+ * Returns 1 if the index differs from HEAD, 0 otherwise. When on an unborn
+ * branch, returns 1 if there are entries in the index, 0 otherwise. If an
+ * strbuf is provided, the space-separated list of files that differ will be
+ * appended to it.
+ */
+extern int index_has_changes(struct strbuf *sb);
+
 extern int verify_path(const char *path);
 extern int strcmp_offset(const char *s1, const char *s2, size_t *first_change);
 extern int index_dir_exists(struct index_state *istate, const char *name, int namelen);
index 76859b453afc2d5ba6897d15a680245b455f4f38..7bb9cadc69738a4348bb54ccce50d6bd35a0753f 100755 (executable)
--- a/git-p4.py
+++ b/git-p4.py
@@ -1178,6 +1178,12 @@ def __init__(self):
         self.needsGit = True
         self.verbose = False
 
+    # This is required for the "append" cloneExclude action
+    def ensure_value(self, attr, value):
+        if not hasattr(self, attr) or getattr(self, attr) is None:
+            setattr(self, attr, value)
+        return getattr(self, attr)
+
 class P4UserMap:
     def __init__(self):
         self.userMapFromPerforceServer = False
@@ -1343,9 +1349,10 @@ def __init__(self):
                 optparse.make_option("--shelve", dest="shelve", action="store_true",
                                      help="Shelve instead of submit. Shelved files are reverted, "
                                      "restoring the workspace to the state before the shelve"),
-                optparse.make_option("--update-shelve", dest="update_shelve", action="store", type="int",
+                optparse.make_option("--update-shelve", dest="update_shelve", action="append", type="int",
                                      metavar="CHANGELIST",
-                                     help="update an existing shelved changelist, implies --shelve")
+                                     help="update an existing shelved changelist, implies --shelve, "
+                                           "repeat in-order for multiple shelved changelists")
         ]
         self.description = "Submit changes from git to the perforce depot."
         self.usage += " [name of git branch to submit into perforce depot]"
@@ -1354,7 +1361,7 @@ def __init__(self):
         self.preserveUser = gitConfigBool("git-p4.preserveUser")
         self.dry_run = False
         self.shelve = False
-        self.update_shelve = None
+        self.update_shelve = list()
         self.prepare_p4_only = False
         self.conflict_behavior = None
         self.isWindows = (platform.system() == "Windows")
@@ -1809,9 +1816,10 @@ def applyCommit(self, id):
             mode = filesToChangeExecBit[f]
             setP4ExecBit(f, mode)
 
-        if self.update_shelve:
-            print("all_files = %s" % str(all_files))
-            p4_reopen_in_change(self.update_shelve, all_files)
+        update_shelve = 0
+        if len(self.update_shelve) > 0:
+            update_shelve = self.update_shelve.pop(0)
+            p4_reopen_in_change(update_shelve, all_files)
 
         #
         # Build p4 change description, starting with the contents
@@ -1821,7 +1829,7 @@ def applyCommit(self, id):
         logMessage = logMessage.strip()
         (logMessage, jobs) = self.separate_jobs_from_description(logMessage)
 
-        template = self.prepareSubmitTemplate(self.update_shelve)
+        template = self.prepareSubmitTemplate(update_shelve)
         submitTemplate = self.prepareLogMessage(template, logMessage, jobs)
 
         if self.preserveUser:
@@ -1894,7 +1902,7 @@ def applyCommit(self, id):
                     message = message.replace("\r\n", "\n")
                 submitTemplate = message[:message.index(separatorLine)]
 
-                if self.update_shelve:
+                if update_shelve:
                     p4_write_pipe(['shelve', '-r', '-i'], submitTemplate)
                 elif self.shelve:
                     p4_write_pipe(['shelve', '-i'], submitTemplate)
@@ -2012,6 +2020,10 @@ def run(self, args):
         else:
             return False
 
+        for i in self.update_shelve:
+            if i <= 0:
+                sys.exit("invalid changelist %d" % i)
+
         if self.master:
             allowSubmit = gitConfig("git-p4.allowSubmit")
             if len(allowSubmit) > 0 and not self.master in allowSubmit.split(","):
@@ -2022,7 +2034,7 @@ def run(self, args):
         if len(self.origin) == 0:
             self.origin = upstream
 
-        if self.update_shelve:
+        if len(self.update_shelve) > 0:
             self.shelve = True
 
         if self.preserveUser:
@@ -2134,6 +2146,11 @@ def run(self, args):
         if gitConfigBool("git-p4.detectCopiesHarder"):
             self.diffOpts += " --find-copies-harder"
 
+        num_shelves = len(self.update_shelve)
+        if num_shelves > 0 and num_shelves != len(commits):
+            sys.exit("number of commits (%d) must match number of shelved changelist (%d)" %
+                     (len(commits), num_shelves))
+
         #
         # Apply the commits, one at a time.  On failure, ask if should
         # continue to try the rest of the patches, or quit.
@@ -2404,12 +2421,6 @@ def __init__(self):
         if gitConfig("git-p4.syncFromOrigin") == "false":
             self.syncWithOrigin = False
 
-    # This is required for the "append" cloneExclude action
-    def ensure_value(self, attr, value):
-        if not hasattr(self, attr) or getattr(self, attr) is None:
-            setattr(self, attr, value)
-        return getattr(self, attr)
-
     # Force a checkpoint in fast-import and wait for it to finish
     def checkpoint(self):
         self.gitStream.write("checkpoint\n\n")
index e3f5a0abf3c76c6e6b1e4528a20fca4c8784894b..b7f95672bd90ba04564e1446c97be887645706de 100644 (file)
@@ -893,7 +893,8 @@ fi
 if test t != "$preserve_merges"
 then
        git rebase--helper --make-script ${keep_empty:+--keep-empty} \
-               $revisions ${restrict_revision+^$restrict_revision} >"$todo"
+               $revisions ${restrict_revision+^$restrict_revision} >"$todo" ||
+       die "$(gettext "Could not generate todo list")"
 else
        format=$(git config --get rebase.instructionFormat)
        # the 'rev-list .. | sed' requires %m to parse; the instruction requires %H to parse
diff --git a/http.c b/http.c
index 32d33261c98cce2d5fd25c07a503654a3d5d2e52..5977712712b22d9076d8cd5ccda0fe12b3057d27 100644 (file)
--- a/http.c
+++ b/http.c
@@ -2030,7 +2030,6 @@ int finish_http_pack_request(struct http_pack_request *preq)
        char *tmp_idx;
        size_t len;
        struct child_process ip = CHILD_PROCESS_INIT;
-       const char *ip_argv[8];
 
        close_pack_index(p);
 
@@ -2046,13 +2045,9 @@ int finish_http_pack_request(struct http_pack_request *preq)
                die("BUG: pack tmpfile does not end in .pack.temp?");
        tmp_idx = xstrfmt("%.*s.idx.temp", (int)len, preq->tmpfile);
 
-       ip_argv[0] = "index-pack";
-       ip_argv[1] = "-o";
-       ip_argv[2] = tmp_idx;
-       ip_argv[3] = preq->tmpfile;
-       ip_argv[4] = NULL;
-
-       ip.argv = ip_argv;
+       argv_array_push(&ip.args, "index-pack");
+       argv_array_pushl(&ip.args, "-o", tmp_idx, NULL);
+       argv_array_push(&ip.args, preq->tmpfile);
        ip.git_cmd = 1;
        ip.no_stdin = 1;
        ip.no_stdout = 1;
index 2ecf495cc2a4a6d4544b92db1d2a8c3c0cc36f87..780f81a8bd3a729502cf2211a63135e4fba5d6cf 100644 (file)
@@ -1952,6 +1952,13 @@ int merge_trees(struct merge_options *o,
        }
 
        if (oid_eq(&common->object.oid, &merge->object.oid)) {
+               struct strbuf sb = STRBUF_INIT;
+
+               if (index_has_changes(&sb)) {
+                       err(o, _("Dirty index: cannot merge (dirty: %s)"),
+                           sb.buf);
+                       return 0;
+               }
                output(o, 0, _("Already up to date!"));
                *result = head;
                return 1;
diff --git a/merge.c b/merge.c
index e5d796c9f2d110bdcd378b361fe2052ac1dcc266..195b5787005ee8f63bc10845f6d788aa4730a61b 100644 (file)
--- a/merge.c
+++ b/merge.c
@@ -1,4 +1,6 @@
 #include "cache.h"
+#include "diff.h"
+#include "diffcore.h"
 #include "lockfile.h"
 #include "commit.h"
 #include "run-command.h"
@@ -15,6 +17,37 @@ static const char *merge_argument(struct commit *commit)
                return EMPTY_TREE_SHA1_HEX;
 }
 
+int index_has_changes(struct strbuf *sb)
+{
+       struct object_id head;
+       int i;
+
+       if (!get_oid_tree("HEAD", &head)) {
+               struct diff_options opt;
+
+               diff_setup(&opt);
+               opt.flags.exit_with_status = 1;
+               if (!sb)
+                       opt.flags.quick = 1;
+               do_diff_cache(&head, &opt);
+               diffcore_std(&opt);
+               for (i = 0; sb && i < diff_queued_diff.nr; i++) {
+                       if (i)
+                               strbuf_addch(sb, ' ');
+                       strbuf_addstr(sb, diff_queued_diff.queue[i]->two->path);
+               }
+               diff_flush(&opt);
+               return opt.flags.has_changes != 0;
+       } else {
+               for (i = 0; sb && i < active_nr; i++) {
+                       if (i)
+                               strbuf_addch(sb, ' ');
+                       strbuf_addstr(sb, active_cache[i]->name);
+               }
+               return !!active_nr;
+       }
+}
+
 int try_merge_command(const char *strategy, size_t xopts_nr,
                      const char **xopts, struct commit_list *common,
                      const char *head_arg, struct commit_list *remotes)
index a8cc6b266e67847abafa613184752b3b781eb8dd..2112d3b27ad21e1d457b08a3aa71a811b5e8ee79 100644 (file)
@@ -58,35 +58,25 @@ static int pack_objects(int fd, struct ref *refs, struct oid_array *extra, struc
         * the revision parameters to it via its stdin and
         * let its stdout go back to the other end.
         */
-       const char *argv[] = {
-               "pack-objects",
-               "--all-progress-implied",
-               "--revs",
-               "--stdout",
-               NULL,
-               NULL,
-               NULL,
-               NULL,
-               NULL,
-               NULL,
-       };
        struct child_process po = CHILD_PROCESS_INIT;
        FILE *po_in;
        int i;
        int rc;
 
-       i = 4;
+       argv_array_push(&po.args, "pack-objects");
+       argv_array_push(&po.args, "--all-progress-implied");
+       argv_array_push(&po.args, "--revs");
+       argv_array_push(&po.args, "--stdout");
        if (args->use_thin_pack)
-               argv[i++] = "--thin";
+               argv_array_push(&po.args, "--thin");
        if (args->use_ofs_delta)
-               argv[i++] = "--delta-base-offset";
+               argv_array_push(&po.args, "--delta-base-offset");
        if (args->quiet || !args->progress)
-               argv[i++] = "-q";
+               argv_array_push(&po.args, "-q");
        if (args->progress)
-               argv[i++] = "--progress";
+               argv_array_push(&po.args, "--progress");
        if (is_repository_shallow())
-               argv[i++] = "--shallow";
-       po.argv = argv;
+               argv_array_push(&po.args, "--shallow");
        po.in = -1;
        po.out = args->stateless_rpc ? -1 : fd;
        po.git_cmd = 1;
index 894d12ad725c2f8cdbabbc87c7db558f5a872a4e..4d3f60594cbf0e9ddf2ea78e8c58eca312b4cac0 100644 (file)
@@ -493,7 +493,7 @@ static int is_index_unchanged(void)
        struct commit *head_commit;
 
        if (!resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, &head_oid, NULL))
-               return error(_("could not resolve HEAD commit\n"));
+               return error(_("could not resolve HEAD commit"));
 
        head_commit = lookup_commit(&head_oid);
 
@@ -513,7 +513,7 @@ static int is_index_unchanged(void)
 
        if (!cache_tree_fully_valid(active_cache_tree))
                if (cache_tree_update(&the_index, 0))
-                       return error(_("unable to update cache tree\n"));
+                       return error(_("unable to update cache tree"));
 
        return !oidcmp(&active_cache_tree->oid,
                       &head_commit->tree->object.oid);
@@ -699,12 +699,12 @@ static int is_original_commit_empty(struct commit *commit)
        const struct object_id *ptree_oid;
 
        if (parse_commit(commit))
-               return error(_("could not parse commit %s\n"),
+               return error(_("could not parse commit %s"),
                             oid_to_hex(&commit->object.oid));
        if (commit->parents) {
                struct commit *parent = commit->parents->item;
                if (parse_commit(parent))
-                       return error(_("could not parse parent commit %s\n"),
+                       return error(_("could not parse parent commit %s"),
                                oid_to_hex(&parent->object.oid));
                ptree_oid = &parent->tree->object.oid;
        } else {
@@ -1013,9 +1013,7 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
                        opts);
                if (res || command != TODO_REWORD)
                        goto leave;
-               flags |= EDIT_MSG | AMEND_MSG;
-               if (command == TODO_REWORD)
-                       flags |= VERIFY_MSG;
+               flags |= EDIT_MSG | AMEND_MSG | VERIFY_MSG;
                msg_file = NULL;
                goto fast_forward_edit;
        }
@@ -1263,18 +1261,23 @@ static int parse_insn_line(struct todo_item *item, const char *bol, char *eol)
        if (i >= TODO_COMMENT)
                return -1;
 
+       /* Eat up extra spaces/ tabs before object name */
+       padding = strspn(bol, " \t");
+       bol += padding;
+
        if (item->command == TODO_NOOP) {
+               if (bol != eol)
+                       return error(_("%s does not accept arguments: '%s'"),
+                                    command_to_string(item->command), bol);
                item->commit = NULL;
                item->arg = bol;
                item->arg_len = eol - bol;
                return 0;
        }
 
-       /* Eat up extra spaces/ tabs before object name */
-       padding = strspn(bol, " \t");
        if (!padding)
-               return -1;
-       bol += padding;
+               return error(_("missing arguments for %s"),
+                            command_to_string(item->command));
 
        if (item->command == TODO_EXEC) {
                item->commit = NULL;
@@ -2583,7 +2586,10 @@ int transform_todos(unsigned flags)
                        strbuf_addf(&buf, " %s", oid);
                }
                /* add all the rest */
-               strbuf_addf(&buf, " %.*s\n", item->arg_len, item->arg);
+               if (!item->arg_len)
+                       strbuf_addch(&buf, '\n');
+               else
+                       strbuf_addf(&buf, " %.*s\n", item->arg_len, item->arg);
        }
 
        i = write_message(buf.buf, buf.len, todo_file, 0);
index 8007be8fbafdc3f4542e27cfc9344044f71d43dc..1df674e9194ee6d5cd5386f477745ff6639b7b65 100644 (file)
--- a/strbuf.c
+++ b/strbuf.c
@@ -683,7 +683,7 @@ static void strbuf_add_urlencode(struct strbuf *sb, const char *s, size_t len,
                    (!reserved && is_rfc3986_reserved(ch)))
                        strbuf_addch(sb, ch);
                else
-                       strbuf_addf(sb, "%%%02x", ch);
+                       strbuf_addf(sb, "%%%02x", (unsigned char)ch);
        }
 }
 
index 1bb06c36f22d9fa0fb01fb8dfad02ffa9f338ebd..96317a35f4df9944cd3b9f64db0db3132d69da6e 100644 (file)
@@ -8,6 +8,7 @@
 
 #GIT_TEST_OPTS = --verbose --debug
 SHELL_PATH ?= $(SHELL)
+TEST_SHELL_PATH ?= $(SHELL_PATH)
 PERL_PATH ?= /usr/bin/perl
 TAR ?= $(TAR)
 RM ?= rm -f
@@ -23,6 +24,7 @@ endif
 
 # Shell quote;
 SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
+TEST_SHELL_PATH_SQ = $(subst ','\'',$(TEST_SHELL_PATH))
 PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH))
 TEST_RESULTS_DIRECTORY_SQ = $(subst ','\'',$(TEST_RESULTS_DIRECTORY))
 
@@ -42,11 +44,11 @@ failed:
        test -z "$$failed" || $(MAKE) $$failed
 
 prove: pre-clean $(TEST_LINT)
-       @echo "*** prove ***"; $(PROVE) --exec '$(SHELL_PATH_SQ)' $(GIT_PROVE_OPTS) $(T) :: $(GIT_TEST_OPTS)
+       @echo "*** prove ***"; $(PROVE) --exec '$(TEST_SHELL_PATH_SQ)' $(GIT_PROVE_OPTS) $(T) :: $(GIT_TEST_OPTS)
        $(MAKE) clean-except-prove-cache
 
 $(T):
-       @echo "*** $@ ***"; '$(SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS)
+       @echo "*** $@ ***"; '$(TEST_SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS)
 
 pre-clean:
        $(RM) -r '$(TEST_RESULTS_DIRECTORY_SQ)'
index 03dc9d28525730cdf57c74d13cab22da59dcdfbd..e07f0284372ec25c91fd62f0d136c31d80263a0d 100755 (executable)
@@ -21,6 +21,7 @@ sub err {
        /^\s*declare\s+/ and err 'arrays/declare not portable';
        /^\s*[^#]\s*which\s/ and err 'which is not portable (please use type)';
        /\btest\s+[^=]*==/ and err '"test a == b" is not portable (please use =)';
+       /\bwc -l.*"\s*=/ and err '`"$(wc -l)"` is not portable (please use test_line_count)';
        /\bexport\s+[A-Za-z0-9_]*=/ and err '"export FOO=bar" is not portable (please use FOO=bar && export FOO)';
        # this resets our $. for each file
        close ARGV if eof;
index 6368a89345e1783ec975c5f6c2c2c66b7ddb9dcb..297fb01d61eded5d83d02175199efcd217376738 100644 (file)
@@ -112,7 +112,7 @@ static void analyze_run(void)
 {
        uint64_t t1s, t1m, t2s, t2m;
        int cache_nr_limit;
-       int nr_threads_used;
+       int nr_threads_used = 0;
        int i;
        int nr;
 
index d2d883f3a1d473a2b69fab05adbb21e67e5e600c..b4905b822c07048ddfbc43cfd39265bd2116f197 100755 (executable)
@@ -7,9 +7,9 @@ check_obj () {
        alt=$1; shift
        while read obj expect
        do
-               echo "$obj" >&3 &&
-               echo "$obj $expect" >&4
-       done 3>input 4>expect &&
+               echo "$obj" >&5 &&
+               echo "$obj $expect" >&6
+       done 5>input 6>expect &&
        GIT_ALTERNATE_OBJECT_DIRECTORIES=$alt \
                git "$@" cat-file --batch-check='%(objectname) %(objecttype)' \
                <input >actual &&
index 01023486c5363da00c9e381fcf1e7d5479c348ae..23b86fb9778980ab813d5e252065ebe34fe4736d 100755 (executable)
@@ -6,18 +6,21 @@ test_description="merges with unrelated index changes"
 
 # Testcase for some simple merges
 #   A
-#   o-----o B
+#   o-------o B
 #    \
-#     \---o C
+#     \-----o C
 #      \
-#       \-o D
+#       \---o D
 #        \
-#         o E
+#         \-o E
+#          \
+#           o F
 #   Commit A: some file a
 #   Commit B: adds file b, modifies end of a
 #   Commit C: adds file c
 #   Commit D: adds file d, modifies beginning of a
 #   Commit E: renames a->subdir/a, adds subdir/e
+#   Commit F: empty commit
 
 test_expect_success 'setup trivial merges' '
        test_seq 1 10 >a &&
@@ -29,6 +32,7 @@ test_expect_success 'setup trivial merges' '
        git branch C &&
        git branch D &&
        git branch E &&
+       git branch F &&
 
        git checkout B &&
        echo b >b &&
@@ -52,7 +56,10 @@ test_expect_success 'setup trivial merges' '
        git mv a subdir/a &&
        echo e >subdir/e &&
        git add subdir &&
-       test_tick && git commit -m E
+       test_tick && git commit -m E &&
+
+       git checkout F &&
+       test_tick && git commit --allow-empty -m F
 '
 
 test_expect_success 'ff update' '
@@ -105,6 +112,15 @@ test_expect_success 'recursive' '
        test_must_fail git merge -s recursive C^0
 '
 
+test_expect_success 'recursive, when merge branch matches merge base' '
+       git reset --hard &&
+       git checkout B^0 &&
+
+       touch random_file && git add random_file &&
+
+       test_must_fail git merge -s recursive F^0
+'
+
 test_expect_success 'octopus, unrelated file touched' '
        git reset --hard &&
        git checkout B^0 &&
index 3457d5db64afc09f63e8c7de4c51b932b012c7ee..71cae2874d935e16b951160c9a3fa0014fe2db27 100755 (executable)
@@ -460,7 +460,13 @@ test_expect_success 'submit --shelve' '
        )
 '
 
-# Update an existing shelved changelist
+make_shelved_cl() {
+       test_commit "$1" >/dev/null &&
+       git p4 submit --origin HEAD^ --shelve >/dev/null &&
+       p4 -G changes -s shelved -m 1 | marshal_dump change
+}
+
+# Update existing shelved changelists
 
 test_expect_success 'submit --update-shelve' '
        test_when_finished cleanup_git &&
@@ -470,21 +476,19 @@ test_expect_success 'submit --update-shelve' '
                p4 revert ... &&
                cd "$git" &&
                git config git-p4.skipSubmitEdit true &&
-               test_commit "test-update-shelved-change" &&
-               git p4 submit --origin=HEAD^ --shelve &&
+               shelved_cl0=$(make_shelved_cl "shelved-change-0") &&
+               echo shelved_cl0=$shelved_cl0 &&
+               shelved_cl1=$(make_shelved_cl "shelved-change-1") &&
 
-               shelf_cl=$(p4 -G changes -s shelved -m 1 |\
-                       marshal_dump change) &&
-               test -n $shelf_cl &&
-               echo "updating shelved change list $shelf_cl" &&
+               echo "updating shelved change lists $shelved_cl0 and $shelved_cl1" &&
 
                echo "updated-line" >>shelf.t &&
                echo added-file.t >added-file.t &&
                git add shelf.t added-file.t &&
-               git rm -f test-update-shelved-change.t &&
+               git rm -f shelved-change-1.t &&
                git commit --amend -C HEAD &&
                git show --stat HEAD &&
-               git p4 submit -v --origin HEAD^ --update-shelve $shelf_cl &&
+               git p4 submit -v --origin HEAD~2 --update-shelve $shelved_cl0 --update-shelve $shelved_cl1 &&
                echo "done git p4 submit"
        ) &&
        (
@@ -494,7 +498,7 @@ test_expect_success 'submit --update-shelve' '
                p4 unshelve -c $change -s $change &&
                grep -q updated-line shelf.t &&
                p4 describe -S $change | grep added-file.t &&
-               test_path_is_missing test-update-shelved-change.t
+               test_path_is_missing shelved-change-1.t
        )
 '
 
index e7065df2bb028aff76f3169d84873a1a3d789571..9a0a21f49ae7bef3d0a1b653cce811d12499672e 100644 (file)
@@ -80,7 +80,7 @@ done,*)
        # from any previous runs.
        >"$GIT_TEST_TEE_OUTPUT_FILE"
 
-       (GIT_TEST_TEE_STARTED=done ${SHELL_PATH} "$0" "$@" 2>&1;
+       (GIT_TEST_TEE_STARTED=done ${TEST_SHELL_PATH} "$0" "$@" 2>&1;
         echo $? >"$BASE.exit") | tee -a "$GIT_TEST_TEE_OUTPUT_FILE"
        test "$(cat "$BASE.exit")" = 0
        exit
@@ -264,7 +264,6 @@ do
                shift ;;
        -x)
                trace=t
-               verbose=t
                shift ;;
        --verbose-log)
                verbose_log=t
@@ -283,6 +282,11 @@ then
        test -z "$verbose_log" && verbose=t
 fi
 
+if test -n "$trace" && test -z "$verbose_log"
+then
+       verbose=t
+fi
+
 if test -n "$color"
 then
        # Save the color control sequences now rather than run tput
@@ -586,7 +590,9 @@ maybe_setup_valgrind () {
 }
 
 want_trace () {
-       test "$trace" = t && test "$verbose" = t
+       test "$trace" = t && {
+               test "$verbose" = t || test "$verbose_log" = t
+       }
 }
 
 # This is a separate function because some tests use
@@ -601,26 +607,40 @@ test_eval_inner_ () {
 }
 
 test_eval_ () {
-       # We run this block with stderr redirected to avoid extra cruft
-       # during a "-x" trace. Once in "set -x" mode, we cannot prevent
+       # If "-x" tracing is in effect, then we want to avoid polluting stderr
+       # with non-test commands. But once in "set -x" mode, we cannot prevent
        # the shell from printing the "set +x" to turn it off (nor the saving
        # of $? before that). But we can make sure that the output goes to
        # /dev/null.
        #
-       # The test itself is run with stderr put back to &4 (so either to
-       # /dev/null, or to the original stderr if --verbose was used).
+       # There are a few subtleties here:
+       #
+       #   - we have to redirect descriptor 4 in addition to 2, to cover
+       #     BASH_XTRACEFD
+       #
+       #   - the actual eval has to come before the redirection block (since
+       #     it needs to see descriptor 4 to set up its stderr)
+       #
+       #   - likewise, any error message we print must be outside the block to
+       #     access descriptor 4
+       #
+       #   - checking $? has to come immediately after the eval, but it must
+       #     be _inside_ the block to avoid polluting the "set -x" output
+       #
+
+       test_eval_inner_ "$@" </dev/null >&3 2>&4
        {
-               test_eval_inner_ "$@" </dev/null >&3 2>&4
                test_eval_ret_=$?
                if want_trace
                then
                        set +x
-                       if test "$test_eval_ret_" != 0
-                       then
-                               say_color error >&4 "error: last command exited with \$?=$test_eval_ret_"
-                       fi
                fi
-       } 2>/dev/null
+       } 2>/dev/null 4>&2
+
+       if test "$test_eval_ret_" != 0 && want_trace
+       then
+               say_color error >&4 "error: last command exited with \$?=$test_eval_ret_"
+       fi
        return $test_eval_ret_
 }