Merge branch 'jk/follow-rename-score' into maint
authorJunio C Hamano <gitster@pobox.com>
Wed, 28 Dec 2011 19:49:37 +0000 (11:49 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 28 Dec 2011 19:49:37 +0000 (11:49 -0800)
* jk/follow-rename-score:
use custom rename score during --follow

59 files changed:
Documentation/RelNotes/1.7.8.1.txt
Documentation/config.txt
Documentation/git-fsck.txt
Documentation/git-mv.txt
Documentation/git-sh-setup.txt
Documentation/git-stripspace.txt
Makefile
archive.c
branch.c
branch.h
builtin/apply.c
builtin/branch.c
builtin/checkout.c
builtin/clone.c
builtin/commit.c
builtin/fetch-pack.c
builtin/init-db.c
builtin/log.c
builtin/merge.c
builtin/mv.c
builtin/revert.c
builtin/send-pack.c
builtin/stripspace.c
cache.h
compat/setenv.c
compat/snprintf.c
compat/strtoimax.c [new file with mode: 0644]
config.c
connect.c
convert.c
fast-import.c
git-compat-util.h
git-rebase--interactive.sh
http-fetch.c
http-push.c
http.c
http.h
imap-send.c
read-cache.c
remote-curl.c
sequencer.c
sequencer.h
submodule.c
t/lib-httpd/apache.conf
t/t2018-checkout-branch.sh
t/t2023-checkout-m.sh [new file with mode: 0755]
t/t3200-branch.sh
t/t3510-cherry-pick-sequence.sh
t/t4131-apply-fake-ancestor.sh
t/t4136-apply-check.sh [new file with mode: 0755]
t/t5000-tar-tree.sh
t/t5500-fetch-pack.sh
t/t5527-fetch-odd-refs.sh [new file with mode: 0755]
t/t5540-http-push.sh
t/t5541-http-push.sh
t/t7106-reset-sequence.sh [deleted file]
t/t9301-fast-import-notes.sh
transport.c
userdiff.c
index 0e8bd9f5eeba1be4971e6d81df943c9d9a5f74f9..33dc948b94492652e4ee5e80ae39288098cff99b 100644 (file)
@@ -1,17 +1,38 @@
 Git v1.7.8.1 Release Notes
 ==========================
 
-Fixes since v1.7.8.1
---------------------
+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.
 
- * After fetching from a remote that has very long refname, the reporting
-   output could have corrupted by overrunning a static buffer.
+ * "git apply --check" did not error out when given an empty input
+   without any patch.
+
+ * "git archive" mistakenly allowed remote clients to ask for commits
+   that are not at the tip of any ref.
 
  * "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.
 
+ * LF-to-CRLF streaming filter used when checking out a large-ish blob
+   fell into an infinite loop with a rare input.
+
+ * The function header pattern for files with "diff=cpp" attribute did
+   not consider "type *funcname(type param1,..." as the beginning of a
+   function.
+
+ * The error message from "git diff" and "git status" when they fail
+   to inspect changes in submodules did not report which submodule they
+   had trouble with.
+
+ * After fetching from a remote that has very long refname, the reporting
+   output could have corrupted by overrunning a static buffer.
+
+ * "git pack-objects" avoids creating cyclic dependencies among deltas
+   when seeing a broken packfile that records the same object in both
+   the deflated form and as a delta.
+
 Also contains minor fixes and documentation updates.
index 5a841da6d4cd86c4340abf001f735a37035d198f..f22d926777155b204e4408dd5fd468938f26d28d 100644 (file)
@@ -115,35 +115,32 @@ in the appropriate manual page. You will find a description of non-core
 porcelain configuration variables in the respective porcelain documentation.
 
 advice.*::
-       When set to 'true', display the given optional help message.
-       When set to 'false', do not display. The configuration variables
-       are:
+       These variables control various optional help messages designed to
+       aid new users. All 'advice.*' variables default to 'true', and you
+       can tell Git that you do not need help by setting these to 'false':
 +
 --
        pushNonFastForward::
                Advice shown when linkgit:git-push[1] refuses
-               non-fast-forward refs. Default: true.
+               non-fast-forward refs.
        statusHints::
                Directions on how to stage/unstage/add shown in the
                output of linkgit:git-status[1] and the template shown
-               when writing commit messages. Default: true.
+               when writing commit messages.
        commitBeforeMerge::
                Advice shown when linkgit:git-merge[1] refuses to
                merge to avoid overwriting local changes.
-               Default: true.
        resolveConflict::
                Advices shown by various commands when conflicts
                prevent the operation from being performed.
-               Default: true.
        implicitIdentity::
                Advice on how to set your identity configuration when
                your information is guessed from the system username and
-               domain name. Default: true.
-
+               domain name.
        detachedHead::
-               Advice shown when you used linkgit::git-checkout[1] to
+               Advice shown when you used linkgit:git-checkout[1] to
                move to the detach HEAD state, to instruct how to create
-               a local branch after the fact.  Default: true.
+               a local branch after the fact.
 --
 
 core.fileMode::
index a2a508dc2829b88e143ceb5c8e5edf0880263b2b..55b33d70310a9f328edfcf3d625a0fc9ab8a192b 100644 (file)
@@ -72,30 +72,20 @@ 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.
 
-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
-'--unreachable' flag it will also print out objects that exist but
-that aren't reachable from any of the specified head nodes.
-
-So for example
-
-       git fsck --unreachable HEAD \
-               $(git for-each-ref --format="%(objectname)" refs/heads)
+DISCUSSION
+----------
 
-will do quite a _lot_ of verification on the tree. There are a few
-extra validity tests to be added (make sure that tree objects are
-sorted properly etc), but on the whole if 'git fsck' is happy, you
-do have a valid tree.
+git-fsck 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
+'--unreachable' flag it will also print out objects that exist but that
+aren't reachable from any of the specified head nodes (or the default
+set, as mentioned above).
 
 Any corrupt objects you will have to find in backups or other archives
 (i.e., you can just remove them and do an 'rsync' with some other site in
 the hopes that somebody else has the object you have corrupted).
 
-Of course, "valid tree" doesn't mean that it wasn't generated by some
-evil person, and the end result might be crap. git is a revision
-tracking system, not a quality assurance system ;)
-
 Extracted Diagnostics
 ---------------------
 
index b8db3739640491566dee6e381bae319b7e7be8c6..e3c84486141685e2f128f64f46d24c36cc45e97f 100644 (file)
@@ -15,8 +15,8 @@ DESCRIPTION
 -----------
 This script is used to move or rename a file, directory or symlink.
 
- git mv [-f] [-n] <source> <destination>
- git mv [-f] [-n] [-k] <source> ... <destination directory>
+ git mv [-v] [-f] [-n] [-k] <source> <destination>
+ git mv [-v] [-f] [-n] [-k] <source> ... <destination directory>
 
 In the first form, it renames <source>, which must exist and be either
 a file, symlink or directory, to <destination>.
@@ -40,6 +40,10 @@ OPTIONS
 --dry-run::
        Do nothing; only show what would happen
 
+-v::
+--verbose::
+       Report the names of files as they are moved.
+
 GIT
 ---
 Part of the linkgit:git[1] suite
index a2f346ca710e03a7f5c65574659ac578ab8bf615..5e5f1c89646cf4389bfd30ba8e90eb0552e80aab 100644 (file)
@@ -68,6 +68,16 @@ require_work_tree_exists::
        cd_to_toplevel, which is impossible to do if there is no
        working tree.
 
+require_clean_work_tree <action> [<hint>]::
+       checks that the working tree and index associated with the
+       repository have no uncommitted changes to tracked files.
+       Otherwise it emits an error message of the form `Cannot
+       <action>: <reason>. <hint>`, and dies.  Example:
++
+----------------
+require_clean_work_tree rebase "Please commit or stash them."
+----------------
+
 get_author_ident_from_commit::
        outputs code for use with eval to set the GIT_AUTHOR_NAME,
        GIT_AUTHOR_EMAIL and GIT_AUTHOR_DATE variables for a given commit.
index b78f031cd4464b21be145d4ffa79ff39dc8bd2bb..a80d94650d3a6b724dc68aac18fd562ff38d2cf8 100644 (file)
@@ -3,26 +3,83 @@ git-stripspace(1)
 
 NAME
 ----
-git-stripspace - Filter out empty lines
+git-stripspace - Remove unnecessary whitespace
 
 
 SYNOPSIS
 --------
 [verse]
-'git stripspace' [-s | --strip-comments] < <stream>
+'git stripspace' [-s | --strip-comments] < input
 
 DESCRIPTION
 -----------
-Remove multiple empty lines, and empty lines at beginning and end.
+
+Clean the input in the manner used by 'git' for text such as commit
+messages, notes, tags and branch descriptions.
+
+With no arguments, this will:
+
+- remove trailing whitespace from all lines
+- collapse multiple consecutive empty lines into one empty line
+- remove empty lines from the beginning and end of the input
+- add a missing '\n' to the last line if necessary.
+
+In the case where the input consists entirely of whitespace characters, no
+output will be produced.
+
+*NOTE*: This is intended for cleaning metadata, prefer the `--whitespace=fix`
+mode of linkgit:git-apply[1] for correcting whitespace of patches or files in
+the repository.
 
 OPTIONS
 -------
 -s::
 --strip-comments::
-       In addition to empty lines, also strip lines starting with '#'.
+       Skip and remove all lines starting with '#'.
+
+EXAMPLES
+--------
+
+Given the following noisy input with '$' indicating the end of a line:
 
-<stream>::
-       Byte stream to act on.
+--------
+|A brief introduction   $
+|   $
+|$
+|A new paragraph$
+|# with a commented-out line    $
+|explaining lots of stuff.$
+|$
+|# An old paragraph, also commented-out. $
+|      $
+|The end.$
+|  $
+---------
+
+Use 'git stripspace' with no arguments to obtain:
+
+--------
+|A brief introduction$
+|$
+|A new paragraph$
+|# with a commented-out line$
+|explaining lots of stuff.$
+|$
+|# An old paragraph, also commented-out.$
+|$
+|The end.$
+---------
+
+Use 'git stripspace --strip-comments' to obtain:
+
+--------
+|A brief introduction$
+|$
+|A new paragraph$
+|explaining lots of stuff.$
+|$
+|The end.$
+---------
 
 GIT
 ---
index b1c80a678b5fdb80ec71f0a1ad567a384feba4e8..b21d2f14176d08011cea79790eb2246d50787ec9 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.
@@ -1478,7 +1478,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 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 025a97be0281b9fd3ccff2b36c03495b005ac4fe..d7fd267b7ed189eaca02caf6628969b50169ec45 100644 (file)
--- a/branch.c
+++ b/branch.c
@@ -3,7 +3,6 @@
 #include "refs.h"
 #include "remote.h"
 #include "commit.h"
-#include "sequencer.h"
 
 struct tracking {
        struct refspec spec;
@@ -160,7 +159,8 @@ int validate_new_branchname(const char *name, struct strbuf *ref,
 
 void create_branch(const char *head,
                   const char *name, const char *start_name,
-                  int force, int reflog, enum branch_track track)
+                  int force, int reflog, int clobber_head,
+                  enum branch_track track)
 {
        struct ref_lock *lock = NULL;
        struct commit *commit;
@@ -175,7 +175,8 @@ void create_branch(const char *head,
                explicit_tracking = 1;
 
        if (validate_new_branchname(name, &ref, force,
-                                   track == BRANCH_TRACK_OVERRIDE)) {
+                                   track == BRANCH_TRACK_OVERRIDE ||
+                                   clobber_head)) {
                if (!force)
                        dont_change_ref = 1;
                else
@@ -247,5 +248,4 @@ void remove_branch_state(void)
        unlink(git_path("MERGE_MSG"));
        unlink(git_path("MERGE_MODE"));
        unlink(git_path("SQUASH_MSG"));
-       remove_sequencer_state(0);
 }
index 1285158dd4f26e5bbb0e0d7133055f168fee773f..e125ff4ca89a87fadb03b3d8272b44ab33640c72 100644 (file)
--- a/branch.h
+++ b/branch.h
@@ -13,7 +13,8 @@
  * branch for (if any).
  */
 void create_branch(const char *head, const char *name, const char *start_name,
-                  int force, int reflog, enum branch_track track);
+                  int force, int reflog,
+                  int clobber_head, enum branch_track track);
 
 /*
  * Validates that the requested branch may be created, returning the
index b3b59db534ff0763c822ae9da571d5643a8b709a..c24dc546d0cc3f223c40c12aa20dc75eff13d4f9 100644 (file)
@@ -3587,15 +3587,12 @@ static int write_out_one_reject(struct patch *patch)
        return -1;
 }
 
-static int write_out_results(struct patch *list, int skipped_patch)
+static int write_out_results(struct patch *list)
 {
        int phase;
        int errs = 0;
        struct patch *l;
 
-       if (!list && !skipped_patch)
-               return error("No changes");
-
        for (phase = 0; phase < 2; phase++) {
                l = list;
                while (l) {
@@ -3721,6 +3718,9 @@ static int apply_patch(int fd, const char *filename, int options)
                offset += nr;
        }
 
+       if (!list && !skipped_patch)
+               die("unrecognized input");
+
        if (whitespace_error && (ws_error_action == die_on_ws_error))
                apply = 0;
 
@@ -3738,7 +3738,7 @@ static int apply_patch(int fd, const char *filename, int options)
            !apply_with_reject)
                exit(1);
 
-       if (apply && write_out_results(list, skipped_patch))
+       if (apply && write_out_results(list))
                exit(1);
 
        if (fake_ancestor)
index 55cad766c7e3d284b1361b1beca8c5d51de96083..df908ed8f55838702299c9a687a98502f91cf5da 100644 (file)
@@ -568,6 +568,7 @@ static void rename_branch(const char *oldname, const char *newname, int force)
        unsigned char sha1[20];
        struct strbuf oldsection = STRBUF_INIT, newsection = STRBUF_INIT;
        int recovery = 0;
+       int clobber_head_ok;
 
        if (!oldname)
                die(_("cannot rename the current branch while not on any."));
@@ -583,7 +584,13 @@ static void rename_branch(const char *oldname, const char *newname, int force)
                        die(_("Invalid branch name: '%s'"), oldname);
        }
 
-       validate_new_branchname(newname, &newref, force, 0);
+       /*
+        * A command like "git branch -M currentbranch currentbranch" cannot
+        * cause the worktree to become inconsistent with HEAD, so allow it.
+        */
+       clobber_head_ok = !strcmp(oldname, newname);
+
+       validate_new_branchname(newname, &newref, force, clobber_head_ok);
 
        strbuf_addf(&logmsg, "Branch: renamed %s to %s",
                 oldref.buf, newref.buf);
@@ -730,7 +737,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
                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,
-                             force_create, reflog, track);
+                             force_create, reflog, 0, track);
        } else
                usage_with_options(builtin_branch_usage, options);
 
index 51840b9784f0daec21087ec101304eaa6cbf73cd..e79003f5bffc8806ea6cfd67f866c3ee4e2f5c7d 100644 (file)
@@ -114,16 +114,21 @@ static int check_stage(int stage, struct cache_entry *ce, int pos)
                return error(_("path '%s' does not have their version"), ce->name);
 }
 
-static int check_all_stages(struct cache_entry *ce, int pos)
+static int check_stages(unsigned stages, struct cache_entry *ce, int pos)
 {
-       if (ce_stage(ce) != 1 ||
-           active_nr <= pos + 2 ||
-           strcmp(active_cache[pos+1]->name, ce->name) ||
-           ce_stage(active_cache[pos+1]) != 2 ||
-           strcmp(active_cache[pos+2]->name, ce->name) ||
-           ce_stage(active_cache[pos+2]) != 3)
-               return error(_("path '%s' does not have all three versions"),
-                            ce->name);
+       unsigned seen = 0;
+       const char *name = ce->name;
+
+       while (pos < active_nr) {
+               ce = active_cache[pos];
+               if (strcmp(name, ce->name))
+                       break;
+               seen |= (1 << ce_stage(ce));
+               pos++;
+       }
+       if ((stages & seen) != stages)
+               return error(_("path '%s' does not have all necessary versions"),
+                            name);
        return 0;
 }
 
@@ -150,18 +155,27 @@ static int checkout_merged(int pos, struct checkout *state)
        int status;
        unsigned char sha1[20];
        mmbuffer_t result_buf;
+       unsigned char threeway[3][20];
+       unsigned mode = 0;
+
+       memset(threeway, 0, sizeof(threeway));
+       while (pos < active_nr) {
+               int stage;
+               stage = ce_stage(ce);
+               if (!stage || strcmp(path, ce->name))
+                       break;
+               hashcpy(threeway[stage - 1], ce->sha1);
+               if (stage == 2)
+                       mode = create_ce_mode(ce->ce_mode);
+               pos++;
+               ce = active_cache[pos];
+       }
+       if (is_null_sha1(threeway[1]) || is_null_sha1(threeway[2]))
+               return error(_("path '%s' does not have necessary versions"), path);
 
-       if (ce_stage(ce) != 1 ||
-           active_nr <= pos + 2 ||
-           strcmp(active_cache[pos+1]->name, path) ||
-           ce_stage(active_cache[pos+1]) != 2 ||
-           strcmp(active_cache[pos+2]->name, path) ||
-           ce_stage(active_cache[pos+2]) != 3)
-               return error(_("path '%s' does not have all 3 versions"), path);
-
-       read_mmblob(&ancestor, active_cache[pos]->sha1);
-       read_mmblob(&ours, active_cache[pos+1]->sha1);
-       read_mmblob(&theirs, active_cache[pos+2]->sha1);
+       read_mmblob(&ancestor, threeway[0]);
+       read_mmblob(&ours, threeway[1]);
+       read_mmblob(&theirs, threeway[2]);
 
        /*
         * NEEDSWORK: re-create conflicts from merges with
@@ -192,9 +206,7 @@ static int checkout_merged(int pos, struct checkout *state)
        if (write_sha1_file(result_buf.ptr, result_buf.size,
                            blob_type, sha1))
                die(_("Unable to add merge result for '%s'"), path);
-       ce = make_cache_entry(create_ce_mode(active_cache[pos+1]->ce_mode),
-                             sha1,
-                             path, 2, 0);
+       ce = make_cache_entry(mode, sha1, path, 2, 0);
        if (!ce)
                die(_("make_cache_entry failed for path '%s'"), path);
        status = checkout_entry(ce, state, NULL);
@@ -252,7 +264,7 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec,
                        } else if (stage) {
                                errs |= check_stage(stage, ce, pos);
                        } else if (opts->merge) {
-                               errs |= check_all_stages(ce, pos);
+                               errs |= check_stages((1<<2) | (1<<3), ce, pos);
                        } else {
                                errs = 1;
                                error(_("path '%s' is unmerged"), ce->name);
@@ -540,7 +552,9 @@ static void update_refs_for_switch(struct checkout_opts *opts,
                else
                        create_branch(old->name, opts->new_branch, new->name,
                                      opts->new_branch_force ? 1 : 0,
-                                     opts->new_branch_log, opts->track);
+                                     opts->new_branch_log,
+                                     opts->new_branch_force ? 1 : 0,
+                                     opts->track);
                new->name = opts->new_branch;
                setup_branch_path(new);
        }
@@ -565,8 +579,12 @@ static void update_refs_for_switch(struct checkout_opts *opts,
                create_symref("HEAD", new->path, msg.buf);
                if (!opts->quiet) {
                        if (old->path && !strcmp(new->path, old->path)) {
-                               fprintf(stderr, _("Already on '%s'\n"),
-                                       new->name);
+                               if (opts->new_branch_force)
+                                       fprintf(stderr, _("Reset branch '%s'\n"),
+                                               new->name);
+                               else
+                                       fprintf(stderr, _("Already on '%s'\n"),
+                                               new->name);
                        } else if (opts->new_branch) {
                                if (opts->branch_exists)
                                        fprintf(stderr, _("Switched to and reset branch '%s'\n"), new->name);
@@ -1057,7 +1075,8 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
                struct strbuf buf = STRBUF_INIT;
 
                opts.branch_exists = validate_new_branchname(opts.new_branch, &buf,
-                                                            !!opts.new_branch_force, 0);
+                                                            !!opts.new_branch_force,
+                                                            !!opts.new_branch_force);
 
                strbuf_release(&buf);
        }
index efe8b6cce5a9f2ae40c6f69755debecfb6b501ca..86db95473021bc8d0b1cc8850185e1660fd9c776 100644 (file)
@@ -84,8 +84,8 @@ static struct option builtin_clone_options[] = {
                   "directory from which templates will be used"),
        OPT_CALLBACK(0 , "reference", &option_reference, "repo",
                     "reference repository", &opt_parse_reference),
-       OPT_STRING('o', "origin", &option_origin, "branch",
-                  "use <branch> instead of 'origin' to track upstream"),
+       OPT_STRING('o', "origin", &option_origin, "name",
+                  "use <name> instead of 'origin' to track upstream"),
        OPT_STRING('b', "branch", &option_branch, "branch",
                   "checkout <branch> instead of the remote's HEAD"),
        OPT_STRING('u', "upload-pack", &option_upload_pack, "path",
index 8f2bebecf313a0e4b742f9327ec178c7e3547dd2..d8d6dd5eaaa5691a0b5059b9a43dd69761dcf72f 100644 (file)
@@ -103,7 +103,7 @@ static enum commit_whence whence;
 static int use_editor = 1, include_status = 1;
 static int show_ignored_in_status;
 static const char *only_include_assumed;
-static struct strbuf message;
+static struct strbuf message = STRBUF_INIT;
 
 static int null_termination;
 static enum {
@@ -138,7 +138,7 @@ static struct option builtin_commit_options[] = {
        OPT_STRING('C', "reuse-message", &use_message, "commit", "reuse message from specified commit"),
        OPT_STRING(0, "fixup", &fixup_message, "commit", "use autosquash formatted message to fixup specified commit"),
        OPT_STRING(0, "squash", &squash_message, "commit", "use autosquash formatted message to squash specified commit"),
-       OPT_BOOLEAN(0, "reset-author", &renew_authorship, "the commit is authored by me now (used with -C-c/--amend)"),
+       OPT_BOOLEAN(0, "reset-author", &renew_authorship, "the commit is authored by me now (used with -C/-c/--amend)"),
        OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"),
        OPT_FILENAME('t', "template", &template_file, "use specified template file"),
        OPT_BOOLEAN('e', "edit", &edit_flag, "force edit of commit"),
index c6bc8eb0aa6f5a6bc35c69e7893118a17813db7d..6207ecd2982761a47474b57cc945a2fc66ed84a1 100644 (file)
@@ -556,11 +556,16 @@ static void filter_refs(struct ref **refs, int nr_match, char **match)
                        continue;
                }
                else {
-                       int order = path_match(ref->name, nr_match, match);
-                       if (order) {
-                               return_refs[order-1] = ref;
-                               continue; /* we will link it later */
+                       int i;
+                       for (i = 0; i < nr_match; i++) {
+                               if (!strcmp(ref->name, match[i])) {
+                                       match[i][0] = '\0';
+                                       return_refs[i] = ref;
+                                       break;
+                               }
                        }
+                       if (i < nr_match)
+                               continue; /* we will link it later */
                }
                free(ref);
        }
@@ -976,7 +981,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
                                   args.verbose ? CONNECT_VERBOSE : 0);
        }
 
-       get_remote_heads(fd[0], &ref, 0, NULL, 0, NULL);
+       get_remote_heads(fd[0], &ref, 0, NULL);
 
        ref = fetch_pack(&args, fd, conn, ref, dest,
                nr_heads, heads, pack_lockfile_ptr);
index d07554c8844a9b7dd3d4ae2b5efe2cbde623e4af..0dacb8b79c57cae2b789eb84d7cfbdb1654ba52f 100644 (file)
@@ -351,7 +351,7 @@ static void separate_git_dir(const char *git_dir)
                else if (S_ISDIR(st.st_mode))
                        src = git_link;
                else
-                       die(_("unable to handle file type %d"), st.st_mode);
+                       die(_("unable to handle file type %d"), (int)st.st_mode);
 
                if (rename(src, git_dir))
                        die_errno(_("unable to move %s to %s"), src, git_dir);
index f5d49305903911eb7aa0fb3f73e0fd950b896228..56bc555d11e25056eab45e92ac43ee885fb55bf7 100644 (file)
@@ -72,8 +72,6 @@ static int decorate_callback(const struct option *opt, const char *arg, int unse
 
 static void cmd_log_init_defaults(struct rev_info *rev)
 {
-       rev->abbrev = DEFAULT_ABBREV;
-       rev->commit_format = CMIT_FMT_DEFAULT;
        if (fmt_pretty)
                get_commit_format(fmt_pretty, rev);
        rev->verbose_header = 1;
index 138737624807389ccb903a5cd03840d63b7cbf6f..7d92e2064b97828ebd5209d97b1d49807149f212 100644 (file)
@@ -48,7 +48,7 @@ static int show_diffstat = 1, shortlog_len, squash;
 static int option_commit = 1, allow_fast_forward = 1;
 static int fast_forward_only, option_edit;
 static int allow_trivial = 1, have_message;
-static struct strbuf merge_msg;
+static struct strbuf merge_msg = STRBUF_INIT;
 static struct commit_list *remoteheads;
 static struct strategy **use_strategies;
 static size_t use_strategies_nr, use_strategies_alloc;
index 5efe6c5760c43d0059a940ab9d4610b97092c8bd..2a144b011caa8ecb70f55976bdec60cae89fad9e 100644 (file)
@@ -59,6 +59,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
        int i, newfd;
        int verbose = 0, show_only = 0, force = 0, ignore_errors = 0;
        struct option builtin_mv_options[] = {
+               OPT__VERBOSE(&verbose, "be verbose"),
                OPT__DRY_RUN(&show_only, "dry run"),
                OPT__FORCE(&force, "force move/rename even if target exists"),
                OPT_BOOLEAN('k', NULL, &ignore_errors, "skip move/rename errors"),
@@ -93,7 +94,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
                destination = copy_pathspec(dest_path[0], argv, argc, 1);
        } else {
                if (argc != 1)
-                       usage_with_options(builtin_mv_usage, builtin_mv_options);
+                       die("destination '%s' is not a directory", dest_path[0]);
                destination = dest_path;
        }
 
@@ -176,7 +177,8 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
                                 * check both source and destination
                                 */
                                if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
-                                       warning(_("%s; will overwrite!"), bad);
+                                       if (verbose)
+                                               warning(_("overwriting '%s'"), dst);
                                        bad = NULL;
                                } else
                                        bad = _("Cannot overwrite");
index 1ea525c10e4c00b66006bf46465ebd490823f25f..028bcbcd75d21ada2bc0406ff74e3073014bb41f 100644 (file)
@@ -60,13 +60,14 @@ struct replay_opts {
        int allow_rerere_auto;
 
        int mainline;
-       int commit_argc;
-       const char **commit_argv;
 
        /* Merge strategy */
        const char *strategy;
        const char **xopts;
        size_t xopts_nr, xopts_alloc;
+
+       /* Only used by REPLAY_NONE */
+       struct rev_info *revs;
 };
 
 #define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
@@ -169,9 +170,9 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
                        die(_("program error"));
        }
 
-       opts->commit_argc = parse_options(argc, argv, NULL, options, usage_str,
-                                       PARSE_OPT_KEEP_ARGV0 |
-                                       PARSE_OPT_KEEP_UNKNOWN);
+       argc = parse_options(argc, argv, NULL, options, usage_str,
+                       PARSE_OPT_KEEP_ARGV0 |
+                       PARSE_OPT_KEEP_UNKNOWN);
 
        /* Check for incompatible subcommands */
        verify_opt_mutually_compatible(me,
@@ -213,9 +214,6 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
                                NULL);
        }
 
-       else if (opts->commit_argc < 2)
-               usage_with_options(usage_str, options);
-
        if (opts->allow_ff)
                verify_opt_compatible(me, "--ff",
                                "--signoff", opts->signoff,
@@ -223,7 +221,20 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
                                "-x", opts->record_origin,
                                "--edit", opts->edit,
                                NULL);
-       opts->commit_argv = argv;
+
+       if (opts->subcommand != REPLAY_NONE) {
+               opts->revs = NULL;
+       } else {
+               opts->revs = xmalloc(sizeof(*opts->revs));
+               init_revisions(opts->revs, NULL);
+               opts->revs->no_walk = 1;
+               if (argc < 2)
+                       usage_with_options(usage_str, options);
+               argc = setup_revisions(argc, argv, opts->revs, NULL);
+       }
+
+       if (argc > 1)
+               usage_with_options(usage_str, options);
 }
 
 struct commit_message {
@@ -631,23 +642,15 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
        return res;
 }
 
-static void prepare_revs(struct rev_info *revs, struct replay_opts *opts)
+static void prepare_revs(struct replay_opts *opts)
 {
-       int argc;
-
-       init_revisions(revs, NULL);
-       revs->no_walk = 1;
        if (opts->action != REVERT)
-               revs->reverse = 1;
-
-       argc = setup_revisions(opts->commit_argc, opts->commit_argv, revs, NULL);
-       if (argc > 1)
-               usage(*revert_or_cherry_pick_usage(opts));
+               opts->revs->reverse ^= 1;
 
-       if (prepare_revision_walk(revs))
+       if (prepare_revision_walk(opts->revs))
                die(_("revision walk setup failed"));
 
-       if (!revs->commits)
+       if (!opts->revs->commits)
                die(_("empty commit set passed"));
 }
 
@@ -844,14 +847,13 @@ static void read_populate_opts(struct replay_opts **opts_ptr)
 static void walk_revs_populate_todo(struct commit_list **todo_list,
                                struct replay_opts *opts)
 {
-       struct rev_info revs;
        struct commit *commit;
        struct commit_list **next;
 
-       prepare_revs(&revs, opts);
+       prepare_revs(opts);
 
        next = todo_list;
-       while ((commit = get_revision(&revs)))
+       while ((commit = get_revision(opts->revs)))
                next = commit_list_append(commit, next);
 }
 
@@ -942,7 +944,7 @@ static int sequencer_rollback(struct replay_opts *opts)
        }
        if (reset_for_rollback(sha1))
                goto fail;
-       remove_sequencer_state(1);
+       remove_sequencer_state();
        strbuf_release(&buf);
        return 0;
 fail:
@@ -1016,33 +1018,64 @@ static int pick_commits(struct commit_list *todo_list, struct replay_opts *opts)
        for (cur = todo_list; cur; cur = cur->next) {
                save_todo(cur, opts);
                res = do_pick_commit(cur->item, opts);
-               if (res) {
-                       if (!cur->next)
-                               /*
-                                * An error was encountered while
-                                * picking the last commit; the
-                                * sequencer state is useless now --
-                                * the user simply needs to resolve
-                                * the conflict and commit
-                                */
-                               remove_sequencer_state(0);
+               if (res)
                        return res;
-               }
        }
 
        /*
         * Sequence of picks finished successfully; cleanup by
         * removing the .git/sequencer directory
         */
-       remove_sequencer_state(1);
+       remove_sequencer_state();
        return 0;
 }
 
+static int continue_single_pick(void)
+{
+       const char *argv[] = { "commit", NULL };
+
+       if (!file_exists(git_path("CHERRY_PICK_HEAD")) &&
+           !file_exists(git_path("REVERT_HEAD")))
+               return error(_("no cherry-pick or revert in progress"));
+       return run_command_v_opt(argv, RUN_GIT_CMD);
+}
+
+static int sequencer_continue(struct replay_opts *opts)
+{
+       struct commit_list *todo_list = NULL;
+
+       if (!file_exists(git_path(SEQ_TODO_FILE)))
+               return continue_single_pick();
+       read_populate_opts(&opts);
+       read_populate_todo(&todo_list, opts);
+
+       /* Verify that the conflict has been resolved */
+       if (file_exists(git_path("CHERRY_PICK_HEAD")) ||
+           file_exists(git_path("REVERT_HEAD"))) {
+               int ret = continue_single_pick();
+               if (ret)
+                       return ret;
+       }
+       if (index_differs_from("HEAD", 0))
+               return error_dirty_index(opts);
+       todo_list = todo_list->next;
+       return pick_commits(todo_list, opts);
+}
+
+static int single_pick(struct commit *cmit, struct replay_opts *opts)
+{
+       setenv(GIT_REFLOG_ACTION, action_name(opts), 0);
+       return do_pick_commit(cmit, opts);
+}
+
 static int pick_revisions(struct replay_opts *opts)
 {
        struct commit_list *todo_list = NULL;
        unsigned char sha1[20];
 
+       if (opts->subcommand == REPLAY_NONE)
+               assert(opts->revs);
+
        read_and_refresh_cache(opts);
 
        /*
@@ -1051,21 +1084,32 @@ static int pick_revisions(struct replay_opts *opts)
         * one that is being continued
         */
        if (opts->subcommand == REPLAY_REMOVE_STATE) {
-               remove_sequencer_state(1);
+               remove_sequencer_state();
                return 0;
        }
        if (opts->subcommand == REPLAY_ROLLBACK)
                return sequencer_rollback(opts);
-       if (opts->subcommand == REPLAY_CONTINUE) {
-               if (!file_exists(git_path(SEQ_TODO_FILE)))
-                       return error(_("No %s in progress"), action_name(opts));
-               read_populate_opts(&opts);
-               read_populate_todo(&todo_list, opts);
-
-               /* Verify that the conflict has been resolved */
-               if (!index_differs_from("HEAD", 0))
-                       todo_list = todo_list->next;
-               return pick_commits(todo_list, opts);
+       if (opts->subcommand == REPLAY_CONTINUE)
+               return sequencer_continue(opts);
+
+       /*
+        * If we were called as "git cherry-pick <commit>", just
+        * cherry-pick/revert it, set CHERRY_PICK_HEAD /
+        * REVERT_HEAD, and don't touch the sequencer state.
+        * This means it is possible to cherry-pick in the middle
+        * of a cherry-pick sequence.
+        */
+       if (opts->revs->cmdline.nr == 1 &&
+           opts->revs->cmdline.rev->whence == REV_CMD_REV &&
+           opts->revs->no_walk &&
+           !opts->revs->cmdline.rev->flags) {
+               struct commit *cmit;
+               if (prepare_revision_walk(opts->revs))
+                       die(_("revision walk setup failed"));
+               cmit = get_revision(opts->revs);
+               if (!cmit || get_revision(opts->revs))
+                       die("BUG: expected exactly one commit from walk");
+               return single_pick(cmit, opts);
        }
 
        /*
index e0b8030f2b31ee337bc2d2e0925788ec6cd92e0f..cd1115ffc687c642acd4bda09b1ea7976e1e0478 100644 (file)
@@ -494,8 +494,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
 
        memset(&extra_have, 0, sizeof(extra_have));
 
-       get_remote_heads(fd[0], &remote_refs, 0, NULL, REF_NORMAL,
-                        &extra_have);
+       get_remote_heads(fd[0], &remote_refs, REF_NORMAL, &extra_have);
 
        transport_verify_remote_names(nr_refspecs, refspecs);
 
index 1288ffcc52530f8ef9561acd2eb2ec5322c9e230..f16986c0ae811f6b998d20be39da1af6095fcfe8 100644 (file)
@@ -75,7 +75,7 @@ int cmd_stripspace(int argc, const char **argv, const char *prefix)
                                !strcmp(argv[1], "--strip-comments")))
                strip_comments = 1;
        else if (argc > 1)
-               usage("git stripspace [-s | --strip-comments] < <stream>");
+               usage("git stripspace [-s | --strip-comments] < input");
 
        if (strbuf_read(&buf, 0, 1024) < 0)
                die_errno("could not read the input");
diff --git a/cache.h b/cache.h
index 2e6ad3604e4cc6efd60a69407159967a1940e680..79c612fc2f51a5adf059a7a9ec2b8e7882388faa 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -1028,12 +1028,11 @@ extern char *git_getpass(const char *prompt);
 extern struct child_process *git_connect(int fd[2], const char *url, const char *prog, int flags);
 extern int finish_connect(struct child_process *conn);
 extern int git_connection_is_socket(struct child_process *conn);
-extern int path_match(const char *path, int nr, char **match);
 struct extra_have_objects {
        int nr, alloc;
        unsigned char (*array)[20];
 };
-extern struct ref **get_remote_heads(int in, struct ref **list, int nr_match, char **match, unsigned int flags, struct extra_have_objects *);
+extern struct ref **get_remote_heads(int in, struct ref **list, unsigned int flags, struct extra_have_objects *);
 extern int server_supports(const char *feature);
 
 extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path);
index 3a22ea7b751efb768d72afa2f97fd963e10eec7e..fc1439a6439393ff5224e98ab126607ceaa4994d 100644 (file)
@@ -6,7 +6,10 @@ int gitsetenv(const char *name, const char *value, int replace)
        size_t namelen, valuelen;
        char *envstr;
 
-       if (!name || !value) return -1;
+       if (!name || strchr(name, '=') || !value) {
+               errno = EINVAL;
+               return -1;
+       }
        if (!replace) {
                char *oldval = NULL;
                oldval = getenv(name);
@@ -16,7 +19,10 @@ int gitsetenv(const char *name, const char *value, int replace)
        namelen = strlen(name);
        valuelen = strlen(value);
        envstr = malloc((namelen + valuelen + 2));
-       if (!envstr) return -1;
+       if (!envstr) {
+               errno = ENOMEM;
+               return -1;
+       }
 
        memcpy(envstr, name, namelen);
        envstr[namelen] = '=';
index e1e0e7543d9414726122c121b7909bf73809a81a..42ea1ac110813bbd16e77cfbc36f16e6a5e9ddb2 100644 (file)
 #undef vsnprintf
 int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap)
 {
+       va_list cp;
        char *s;
        int ret = -1;
 
        if (maxsize > 0) {
-               ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap);
+               va_copy(cp, ap);
+               ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, cp);
+               va_end(cp);
                if (ret == maxsize-1)
                        ret = -1;
                /* Windows does not NUL-terminate if result fills buffer */
@@ -42,7 +45,9 @@ int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap)
                if (! str)
                        break;
                s = str;
-               ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap);
+               va_copy(cp, ap);
+               ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, cp);
+               va_end(cp);
                if (ret == maxsize-1)
                        ret = -1;
        }
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
+}
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 51990fa0cb300a95b125b0727f10133961d0167b..c8d0ea5d75e89a6b15b62e7057e97947036e11ea 100644 (file)
--- a/connect.c
+++ b/connect.c
@@ -53,7 +53,6 @@ static void add_extra_have(struct extra_have_objects *extra, unsigned char *sha1
  * Read all the refs from the other end
  */
 struct ref **get_remote_heads(int in, struct ref **list,
-                             int nr_match, char **match,
                              unsigned int flags,
                              struct extra_have_objects *extra_have)
 {
@@ -92,8 +91,6 @@ struct ref **get_remote_heads(int in, struct ref **list,
 
                if (!check_ref(name, name_len, flags))
                        continue;
-               if (nr_match && !path_match(name, nr_match, match))
-                       continue;
                ref = alloc_ref(buffer + 41);
                hashcpy(ref->old_sha1, old_sha1);
                *list = ref;
@@ -108,27 +105,6 @@ int server_supports(const char *feature)
                strstr(server_capabilities, feature) != NULL;
 }
 
-int path_match(const char *path, int nr, char **match)
-{
-       int i;
-       int pathlen = strlen(path);
-
-       for (i = 0; i < nr; i++) {
-               char *s = match[i];
-               int len = strlen(s);
-
-               if (!len || len > pathlen)
-                       continue;
-               if (memcmp(path + pathlen - len, s, len))
-                       continue;
-               if (pathlen > len && path[pathlen - len - 1] != '/')
-                       continue;
-               *s = 0;
-               return (i + 1);
-       }
-       return 0;
-}
-
 enum protocol {
        PROTO_LOCAL = 1,
        PROTO_SSH,
@@ -175,6 +151,15 @@ static void get_host_and_port(char **host, const char **port)
        }
 }
 
+static void enable_keepalive(int sockfd)
+{
+       int ka = 1;
+
+       if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &ka, sizeof(ka)) < 0)
+               fprintf(stderr, "unable to set SO_KEEPALIVE on socket: %s\n",
+                       strerror(errno));
+}
+
 #ifndef NO_IPV6
 
 static const char *ai_name(const struct addrinfo *ai)
@@ -239,6 +224,8 @@ static int git_tcp_connect_sock(char *host, int flags)
        if (sockfd < 0)
                die("unable to connect to %s:\n%s", host, error_message.buf);
 
+       enable_keepalive(sockfd);
+
        if (flags & CONNECT_VERBOSE)
                fprintf(stderr, "done.\n");
 
@@ -312,6 +299,8 @@ static int git_tcp_connect_sock(char *host, int flags)
        if (sockfd < 0)
                die("unable to connect to %s:\n%s", host, error_message.buf);
 
+       enable_keepalive(sockfd);
+
        if (flags & CONNECT_VERBOSE)
                fprintf(stderr, "done.\n");
 
index 86e9c29ec05139844ff46868e2b52dfbc274cc39..12868ed7bda11648704ffe4e5d3415067764a6e2 100644 (file)
--- a/convert.c
+++ b/convert.c
@@ -876,43 +876,109 @@ int is_null_stream_filter(struct stream_filter *filter)
 /*
  * LF-to-CRLF filter
  */
+
+struct lf_to_crlf_filter {
+       struct stream_filter filter;
+       unsigned has_held:1;
+       char held;
+};
+
 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;
+
+       /*
+        * We may be holding onto the CR to see if it is followed by a
+        * LF, in which case we would need to go to the main loop.
+        * Otherwise, just emit it to the output stream.
+        */
+       if (lf_to_crlf->has_held && (lf_to_crlf->held != '\r' || !input)) {
+               output[o++] = lf_to_crlf->held;
+               lf_to_crlf->has_held = 0;
+       }
+
+       /* We are told to drain */
+       if (!input) {
+               *osize_p -= o;
+               return 0;
+       }
 
-       if (!input)
-               return 0; /* we do not keep any states */
        count = *isize_p;
-       if (count) {
-               size_t i, o;
-               for (i = o = 0; o < *osize_p && i < count; i++) {
+       if (count || lf_to_crlf->has_held) {
+               size_t i;
+               int was_cr = 0;
+
+               if (lf_to_crlf->has_held) {
+                       was_cr = 1;
+                       lf_to_crlf->has_held = 0;
+               }
+
+               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';
+                       } else if (was_cr) {
+                               /*
+                                * Previous round saw CR and it is not followed
+                                * by a LF; emit the CR before processing the
+                                * current character.
+                                */
+                               output[o++] = '\r';
+                       }
+
+                       /*
+                        * We may have consumed the last output slot,
+                        * in which case we need to break out of this
+                        * loop; hold the current character before
+                        * returning.
+                        */
+                       if (*osize_p <= o) {
+                               lf_to_crlf->has_held = 1;
+                               lf_to_crlf->held = ch;
+                               continue; /* break but increment i */
                        }
+
+                       if (ch == '\r') {
+                               was_cr = 1;
+                               continue;
+                       }
+
+                       was_cr = 0;
                        output[o++] = ch;
                }
 
                *osize_p -= o;
                *isize_p -= i;
+
+               if (!lf_to_crlf->has_held && was_cr) {
+                       lf_to_crlf->has_held = 1;
+                       lf_to_crlf->held = '\r';
+               }
        }
        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 = xcalloc(1, sizeof(*lf_to_crlf));
 
+       lf_to_crlf->filter.vtbl = &lf_to_crlf_vtbl;
+       return (struct stream_filter *)lf_to_crlf;
+}
 
 /*
  * Cascade filter
@@ -1194,7 +1260,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;
 }
index 8d8ea3c45c0be5481c7b452c27ee0d163d69fb00..f4bfe0f6650fdb2666f031ca1f551134f872e098 100644 (file)
@@ -2173,6 +2173,11 @@ static uintmax_t do_change_note_fanout(
 
                if (tmp_hex_sha1_len == 40 && !get_sha1_hex(hex_sha1, sha1)) {
                        /* This is a note entry */
+                       if (fanout == 0xff) {
+                               /* Counting mode, no rename */
+                               num_notes++;
+                               continue;
+                       }
                        construct_path_with_fanout(hex_sha1, fanout, realpath);
                        if (!strcmp(fullpath, realpath)) {
                                /* Note entry is in correct location */
@@ -2379,7 +2384,7 @@ static void file_change_cr(struct branch *b, int rename)
                leaf.tree);
 }
 
-static void note_change_n(struct branch *b, unsigned char old_fanout)
+static void note_change_n(struct branch *b, unsigned char *old_fanout)
 {
        const char *p = command_buf.buf + 2;
        static struct strbuf uq = STRBUF_INIT;
@@ -2390,6 +2395,23 @@ static void note_change_n(struct branch *b, unsigned char old_fanout)
        uint16_t inline_data = 0;
        unsigned char new_fanout;
 
+       /*
+        * When loading a branch, we don't traverse its tree to count the real
+        * number of notes (too expensive to do this for all non-note refs).
+        * This means that recently loaded notes refs might incorrectly have
+        * b->num_notes == 0, and consequently, old_fanout might be wrong.
+        *
+        * Fix this by traversing the tree and counting the number of notes
+        * when b->num_notes == 0. If the notes tree is truly empty, the
+        * calculation should not take long.
+        */
+       if (b->num_notes == 0 && *old_fanout == 0) {
+               /* Invoke change_note_fanout() in "counting mode". */
+               b->num_notes = change_note_fanout(&b->branch_tree, 0xff);
+               *old_fanout = convert_num_notes_to_fanout(b->num_notes);
+       }
+
+       /* Now parse the notemodify command. */
        /* <dataref> or 'inline' */
        if (*p == ':') {
                char *x;
@@ -2450,7 +2472,7 @@ static void note_change_n(struct branch *b, unsigned char old_fanout)
                            typename(type), command_buf.buf);
        }
 
-       construct_path_with_fanout(sha1_to_hex(commit_sha1), old_fanout, path);
+       construct_path_with_fanout(sha1_to_hex(commit_sha1), *old_fanout, path);
        if (tree_content_remove(&b->branch_tree, path, NULL))
                b->num_notes--;
 
@@ -2637,7 +2659,7 @@ static void parse_new_commit(void)
                else if (!prefixcmp(command_buf.buf, "C "))
                        file_change_cr(b, 0);
                else if (!prefixcmp(command_buf.buf, "N "))
-                       note_change_n(b, prev_fanout);
+                       note_change_n(b, &prev_fanout);
                else if (!strcmp("deleteall", command_buf.buf))
                        file_change_deleteall(b);
                else if (!prefixcmp(command_buf.buf, "ls "))
index 8b4dd5c022a160de5c68d83b6237799c23e6ae0a..230e198fc35390fbccb496d2b74425382439dc4a 100644 (file)
@@ -351,6 +351,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 804001bb4e29873ef08d950a40cf1f1745e2aa27..5812222eb9afa2b2903040d7cf32ab0fb33c3508 100644 (file)
@@ -143,6 +143,21 @@ die_with_patch () {
        die "$2"
 }
 
+exit_with_patch () {
+       echo "$1" > "$state_dir"/stopped-sha
+       make_patch $1
+       git rev-parse --verify HEAD > "$amend"
+       warn "You can amend the commit now, with"
+       warn
+       warn "  git commit --amend"
+       warn
+       warn "Once you are satisfied with your changes, run"
+       warn
+       warn "  git rebase --continue"
+       warn
+       exit $2
+}
+
 die_abort () {
        rm -rf "$state_dir"
        die "$1"
@@ -408,7 +423,13 @@ do_next () {
                mark_action_done
                pick_one $sha1 ||
                        die_with_patch $sha1 "Could not apply $sha1... $rest"
-               git commit --amend --no-post-rewrite
+               git commit --amend --no-post-rewrite || {
+                       warn "Could not amend commit after successfully picking $sha1... $rest"
+                       warn "This is most likely due to an empty commit message, or the pre-commit hook"
+                       warn "failed. If the pre-commit hook failed, you may need to resolve the issue before"
+                       warn "you are able to reword the commit."
+                       exit_with_patch $sha1 1
+               }
                record_in_rewritten $sha1
                ;;
        edit|e)
@@ -417,19 +438,8 @@ do_next () {
                mark_action_done
                pick_one $sha1 ||
                        die_with_patch $sha1 "Could not apply $sha1... $rest"
-               echo "$sha1" > "$state_dir"/stopped-sha
-               make_patch $sha1
-               git rev-parse --verify HEAD > "$amend"
                warn "Stopped at $sha1... $rest"
-               warn "You can amend the commit now, with"
-               warn
-               warn "  git commit --amend"
-               warn
-               warn "Once you are satisfied with your changes, run"
-               warn
-               warn "  git rebase --continue"
-               warn
-               exit 0
+               exit_with_patch $sha1 0
                ;;
        squash|s|fixup|f)
                case "$command" in
index 69299b7bd2a956266bf581df9c23589a97fca805..94d47cbb287f7d3ea76b71f3ef39ddeea3b9202c 100644 (file)
@@ -67,7 +67,7 @@ int main(int argc, const char **argv)
 
        git_config(git_default_config, NULL);
 
-       http_init(NULL, url);
+       http_init(NULL, url, 0);
        walker = get_http_walker(url);
        walker->get_tree = get_tree;
        walker->get_history = get_history;
index edd553b7f69ed92fde301966e605e7562703718a..cdfdd4f79199261b2a62012381728d676484e424 100644 (file)
@@ -1820,7 +1820,7 @@ int main(int argc, char **argv)
 
        memset(remote_dir_exists, -1, 256);
 
-       http_init(NULL, repo->url);
+       http_init(NULL, repo->url, 1);
 
 #ifdef USE_CURL_MULTI
        is_running_queue = 0;
diff --git a/http.c b/http.c
index 44fcc4d178fcedaa87f1917608dd32a65c24c98a..5a1047345997cf35c40cfff5420f5519958257c3 100644 (file)
--- a/http.c
+++ b/http.c
@@ -42,6 +42,7 @@ static int curl_ftp_no_epsv;
 static const char *curl_http_proxy;
 static const char *curl_cookie_file;
 static char *user_name, *user_pass, *description;
+static int http_proactive_auth;
 static const char *user_agent;
 
 #if LIBCURL_VERSION_NUM >= 0x071700
@@ -276,6 +277,9 @@ static CURL *get_curl_handle(void)
        curl_easy_setopt(result, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
 #endif
 
+       if (http_proactive_auth)
+               init_curl_http_auth(result);
+
        if (ssl_cert != NULL)
                curl_easy_setopt(result, CURLOPT_SSLCERT, ssl_cert);
        if (has_cert_password())
@@ -364,7 +368,7 @@ static void set_from_env(const char **var, const char *envname)
                *var = val;
 }
 
-void http_init(struct remote *remote, const char *url)
+void http_init(struct remote *remote, const char *url, int proactive_auth)
 {
        char *low_speed_limit;
        char *low_speed_time;
@@ -375,6 +379,8 @@ void http_init(struct remote *remote, const char *url)
 
        curl_global_init(CURL_GLOBAL_ALL);
 
+       http_proactive_auth = proactive_auth;
+
        if (remote && remote->http_proxy)
                curl_http_proxy = xstrdup(remote->http_proxy);
 
diff --git a/http.h b/http.h
index ee1606942a9716b45da937873949220ab7f8092b..0b61653894eff606980427ee26770fa088438b94 100644 (file)
--- a/http.h
+++ b/http.h
@@ -85,7 +85,8 @@ extern void add_fill_function(void *data, int (*fill)(void *));
 extern void step_active_slots(void);
 #endif
 
-extern void http_init(struct remote *remote, const char *url);
+extern void http_init(struct remote *remote, const char *url,
+                     int proactive_auth);
 extern void http_cleanup(void);
 
 extern int active_requests;
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 5790a91044e4fdf5b2eec515051a66c110e0daa4..27e9fc6ee86005d4fd6cec5b3c2ae29dc2fd6bf3 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)
index 0e720ee8bbf4cbc6a50336a1f1c93bfc63842fe3..48c20b86f3cfc6c189972718046a6890aaefacf3 100644 (file)
@@ -188,7 +188,7 @@ static int write_discovery(int in, int out, void *data)
        return err;
 }
 
-static struct ref *parse_git_refs(struct discovery *heads)
+static struct ref *parse_git_refs(struct discovery *heads, int for_push)
 {
        struct ref *list = NULL;
        struct async async;
@@ -200,7 +200,8 @@ static struct ref *parse_git_refs(struct discovery *heads)
 
        if (start_async(&async))
                die("cannot start thread to parse advertised refs");
-       get_remote_heads(async.out, &list, 0, NULL, 0, NULL);
+       get_remote_heads(async.out, &list,
+                       for_push ? REF_NORMAL : 0, NULL);
        close(async.out);
        if (finish_async(&async))
                die("ref parsing thread failed");
@@ -268,7 +269,7 @@ static struct ref *get_refs(int for_push)
                heads = discover_refs("git-upload-pack");
 
        if (heads->proto_git)
-               return parse_git_refs(heads);
+               return parse_git_refs(heads, for_push);
        return parse_info_refs(heads);
 }
 
@@ -859,7 +860,7 @@ int main(int argc, const char **argv)
 
        url = strbuf_detach(&buf, NULL);
 
-       http_init(remote, url);
+       http_init(remote, url, 0);
 
        do {
                if (strbuf_getline(&buf, stdin, '\n') == EOF) {
index bc2c046aab23c5b3de8caa02c23703856ee86fb4..d1f28a6945cbbdc8f58a32d7bb481ecd4af6cc39 100644 (file)
@@ -3,17 +3,11 @@
 #include "strbuf.h"
 #include "dir.h"
 
-void remove_sequencer_state(int aggressive)
+void remove_sequencer_state(void)
 {
        struct strbuf seq_dir = STRBUF_INIT;
-       struct strbuf seq_old_dir = STRBUF_INIT;
 
        strbuf_addf(&seq_dir, "%s", git_path(SEQ_DIR));
-       strbuf_addf(&seq_old_dir, "%s", git_path(SEQ_OLD_DIR));
-       remove_dir_recursively(&seq_old_dir, 0);
-       rename(git_path(SEQ_DIR), git_path(SEQ_OLD_DIR));
-       if (aggressive)
-               remove_dir_recursively(&seq_old_dir, 0);
+       remove_dir_recursively(&seq_dir, 0);
        strbuf_release(&seq_dir);
-       strbuf_release(&seq_old_dir);
 }
index f435fdb4b147d2e2ce5480ddb4832228af1cb73b..2d4528f2928053827aedd0b737bf01985f1c4957 100644 (file)
@@ -2,19 +2,11 @@
 #define SEQUENCER_H
 
 #define SEQ_DIR                "sequencer"
-#define SEQ_OLD_DIR    "sequencer-old"
 #define SEQ_HEAD_FILE  "sequencer/head"
 #define SEQ_TODO_FILE  "sequencer/todo"
 #define SEQ_OPTS_FILE  "sequencer/opts"
 
-/*
- * Removes SEQ_OLD_DIR and renames SEQ_DIR to SEQ_OLD_DIR, ignoring
- * any errors.  Intended to be used by 'git reset'.
- *
- * With the aggressive flag, it additionally removes SEQ_OLD_DIR,
- * ignoring any errors.  Inteded to be used by the sequencer's
- * '--quit' subcommand.
- */
-void remove_sequencer_state(int aggressive);
+/* Removes SEQ_DIR. */
+extern void remove_sequencer_state(void);
 
 #endif
index 52cdcc6a6347a786deafad34efdb9dc4dc3670ff..68c1ba90b9e746b869830ec66a6f23437a4d7d08 100644 (file)
@@ -689,7 +689,7 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked)
        cp.out = -1;
        cp.dir = path;
        if (start_command(&cp))
-               die("Could not run git status --porcelain");
+               die("Could not run 'git status --porcelain' in submodule %s", path);
 
        len = strbuf_read(&buf, cp.out, 1024);
        line = buf.buf;
@@ -714,7 +714,7 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked)
        close(cp.out);
 
        if (finish_command(&cp))
-               die("git status --porcelain failed");
+               die("'git status --porcelain' failed in submodule %s", path);
 
        strbuf_release(&buf);
        return dirty_submodule;
index 0a4cdfa93ece7d8a4177835b5569583c22303564..3c12b05d60849b4f3063527338140c717b720c5d 100644 (file)
@@ -92,6 +92,9 @@ SSLEngine On
        <Location /dumb/>
                Dav on
        </Location>
+       <Location /auth/dumb>
+               Dav on
+       </Location>
 </IfDefine>
 
 <IfDefine SVN>
index 75874e85dfbcae8ea9634693a93524841b741559..2741262369e40a05cdc6732e4c9e6f04acb63bba 100755 (executable)
@@ -189,12 +189,13 @@ test_expect_success 'checkout -b <describe>' '
        test_cmp expect actual
 '
 
-test_expect_success 'checkout -B to the current branch fails before merging' '
+test_expect_success 'checkout -B to the current branch works' '
        git checkout branch1 &&
+       git checkout -B branch1-scratch &&
+
        setup_dirty_mergeable &&
-       git commit -mfooble &&
-       test_must_fail git checkout -B branch1 initial &&
-       test_must_fail test_dirty_mergeable
+       git checkout -B branch1-scratch initial &&
+       test_dirty_mergeable
 '
 
 test_done
diff --git a/t/t2023-checkout-m.sh b/t/t2023-checkout-m.sh
new file mode 100755 (executable)
index 0000000..7e18985
--- /dev/null
@@ -0,0 +1,49 @@
+#!/bin/sh
+
+test_description='checkout -m -- <conflicted path>
+
+Ensures that checkout -m on a resolved file restores the conflicted file'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+       test_tick &&
+       test_commit both.txt both.txt initial &&
+       git branch topic &&
+       test_commit modified_in_master both.txt in_master &&
+       test_commit added_in_master each.txt in_master &&
+       git checkout topic &&
+       test_commit modified_in_topic both.txt in_topic &&
+       test_commit added_in_topic each.txt in_topic
+'
+
+test_expect_success 'git merge master' '
+    test_must_fail git merge master
+'
+
+clean_branchnames () {
+       # Remove branch names after conflict lines
+       sed 's/^\([<>]\{5,\}\) .*$/\1/'
+}
+
+test_expect_success '-m restores 2-way conflicted+resolved file' '
+       cp each.txt each.txt.conflicted &&
+       echo resolved >each.txt &&
+       git add each.txt &&
+       git checkout -m -- each.txt &&
+       clean_branchnames <each.txt >each.txt.cleaned &&
+       clean_branchnames <each.txt.conflicted >each.txt.conflicted.cleaned &&
+       test_cmp each.txt.conflicted.cleaned each.txt.cleaned
+'
+
+test_expect_success '-m restores 3-way conflicted+resolved file' '
+       cp both.txt both.txt.conflicted &&
+       echo resolved >both.txt &&
+       git add both.txt &&
+       git checkout -m -- both.txt &&
+       clean_branchnames <both.txt >both.txt.cleaned &&
+       clean_branchnames <both.txt.conflicted >both.txt.conflicted.cleaned &&
+       test_cmp both.txt.conflicted.cleaned both.txt.cleaned
+'
+
+test_done
index bc73c2099b5069ab136a1d93aef5a8ab4a0dad1f..76903323af37ed1a96b5a11c27eb1e9d63a0e9ef 100755 (executable)
@@ -115,6 +115,22 @@ test_expect_success 'git branch -M baz bam should succeed when baz is checked ou
        git branch -M baz bam
 '
 
+test_expect_success 'git branch -M master should work when master is checked out' '
+       git checkout master &&
+       git branch -M master
+'
+
+test_expect_success 'git branch -M master master should work when master is checked out' '
+       git checkout master &&
+       git branch -M master master
+'
+
+test_expect_success 'git branch -M master2 master2 should work when master is checked out' '
+       git checkout master &&
+       git branch master2 &&
+       git branch -M master2 master2
+'
+
 test_expect_success 'git branch -v -d t should work' '
        git branch t &&
        test_path_is_file .git/refs/heads/t &&
index 2c4c1c851dcbb1cd38edc2a2620e2b04e36f7192..e80050e1fef9c7c2d83a34aaa671415ea168e8c4 100755 (executable)
@@ -2,6 +2,7 @@
 
 test_description='Test cherry-pick continuation features
 
+ +  conflicting: rewrites unrelated to conflicting
   + yetanotherpick: rewrites foo to e
   + anotherpick: rewrites foo to d
   + picked: rewrites foo to c
@@ -27,6 +28,7 @@ test_cmp_rev () {
 }
 
 test_expect_success setup '
+       git config advice.detachedhead false
        echo unrelated >unrelated &&
        git add unrelated &&
        test_commit initial foo a &&
@@ -35,8 +37,8 @@ test_expect_success setup '
        test_commit picked foo c &&
        test_commit anotherpick foo d &&
        test_commit yetanotherpick foo e &&
-       git config advice.detachedhead false
-
+       pristine_detach initial &&
+       test_commit conflicting unrelated
 '
 
 test_expect_success 'cherry-pick persists data on failure' '
@@ -48,6 +50,18 @@ test_expect_success 'cherry-pick persists data on failure' '
        test_path_is_file .git/sequencer/opts
 '
 
+test_expect_success 'cherry-pick mid-cherry-pick-sequence' '
+       pristine_detach initial &&
+       test_must_fail git cherry-pick base..anotherpick &&
+       test_cmp_rev picked CHERRY_PICK_HEAD &&
+       # "oops, I forgot that these patches rely on the change from base"
+       git checkout HEAD foo &&
+       git cherry-pick base &&
+       git cherry-pick picked &&
+       git cherry-pick --continue &&
+       git diff --exit-code anotherpick
+'
+
 test_expect_success 'cherry-pick persists opts correctly' '
        pristine_detach initial &&
        test_must_fail git cherry-pick -s -m 1 --strategy=recursive -X patience -X ours base..anotherpick &&
@@ -189,10 +203,10 @@ test_expect_success '--abort refuses to clobber unrelated change, harder case' '
        test_cmp_rev initial HEAD
 '
 
-test_expect_success 'cherry-pick cleans up sequencer state when one commit is left' '
+test_expect_success 'cherry-pick still writes sequencer state when one commit is left' '
        pristine_detach initial &&
        test_must_fail git cherry-pick base..picked &&
-       test_path_is_missing .git/sequencer &&
+       test_path_is_dir .git/sequencer &&
        echo "resolved" >foo &&
        git add foo &&
        git commit &&
@@ -213,7 +227,7 @@ test_expect_success 'cherry-pick cleans up sequencer state when one commit is le
        test_cmp expect actual
 '
 
-test_expect_failure '--abort after last commit in sequence' '
+test_expect_success '--abort after last commit in sequence' '
        pristine_detach initial &&
        test_must_fail git cherry-pick base..picked &&
        git cherry-pick --abort &&
@@ -243,7 +257,66 @@ test_expect_success '--continue complains when there are unresolved conflicts' '
        test_must_fail git cherry-pick --continue
 '
 
-test_expect_success '--continue continues after conflicts are resolved' '
+test_expect_success '--continue of single cherry-pick' '
+       pristine_detach initial &&
+       echo c >expect &&
+       test_must_fail git cherry-pick picked &&
+       echo c >foo &&
+       git add foo &&
+       git cherry-pick --continue &&
+
+       test_cmp expect foo &&
+       test_cmp_rev initial HEAD^ &&
+       git diff --exit-code HEAD &&
+       test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
+'
+
+test_expect_success '--continue of single revert' '
+       pristine_detach initial &&
+       echo resolved >expect &&
+       echo "Revert \"picked\"" >expect.msg &&
+       test_must_fail git revert picked &&
+       echo resolved >foo &&
+       git add foo &&
+       git cherry-pick --continue &&
+
+       git diff --exit-code HEAD &&
+       test_cmp expect foo &&
+       test_cmp_rev initial HEAD^ &&
+       git diff-tree -s --pretty=tformat:%s HEAD >msg &&
+       test_cmp expect.msg msg &&
+       test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
+       test_must_fail git rev-parse --verify REVERT_HEAD
+'
+
+test_expect_success '--continue after resolving conflicts' '
+       pristine_detach initial &&
+       echo d >expect &&
+       cat >expect.log <<-\EOF &&
+       OBJID
+       :100644 100644 OBJID OBJID M    foo
+       OBJID
+       :100644 100644 OBJID OBJID M    foo
+       OBJID
+       :100644 100644 OBJID OBJID M    unrelated
+       OBJID
+       :000000 100644 OBJID OBJID A    foo
+       :000000 100644 OBJID OBJID A    unrelated
+       EOF
+       test_must_fail git cherry-pick base..anotherpick &&
+       echo c >foo &&
+       git add foo &&
+       git cherry-pick --continue &&
+       {
+               git rev-list HEAD |
+               git diff-tree --root --stdin |
+               sed "s/$_x40/OBJID/g"
+       } >actual.log &&
+       test_cmp expect foo &&
+       test_cmp expect.log actual.log
+'
+
+test_expect_success '--continue after resolving conflicts and committing' '
        pristine_detach initial &&
        test_must_fail git cherry-pick base..anotherpick &&
        echo "c" >foo &&
@@ -270,6 +343,29 @@ test_expect_success '--continue continues after conflicts are resolved' '
        test_cmp expect actual
 '
 
+test_expect_success '--continue asks for help after resolving patch to nil' '
+       pristine_detach conflicting &&
+       test_must_fail git cherry-pick initial..picked &&
+
+       test_cmp_rev unrelatedpick CHERRY_PICK_HEAD &&
+       git checkout HEAD -- unrelated &&
+       test_must_fail git cherry-pick --continue 2>msg &&
+       test_i18ngrep "The previous cherry-pick is now empty" msg
+'
+
+test_expect_success 'follow advice and skip nil patch' '
+       pristine_detach conflicting &&
+       test_must_fail git cherry-pick initial..picked &&
+
+       git checkout HEAD -- unrelated &&
+       test_must_fail git cherry-pick --continue &&
+       git reset &&
+       git cherry-pick --continue &&
+
+       git rev-list initial..HEAD >commits &&
+       test_line_count = 3 commits
+'
+
 test_expect_success '--continue respects opts' '
        pristine_detach initial &&
        test_must_fail git cherry-pick -x base..anotherpick &&
@@ -288,6 +384,29 @@ test_expect_success '--continue respects opts' '
        grep "cherry picked from" anotherpick_msg
 '
 
+test_expect_success '--continue of single-pick respects -x' '
+       pristine_detach initial &&
+       test_must_fail git cherry-pick -x picked &&
+       echo c >foo &&
+       git add foo &&
+       git cherry-pick --continue &&
+       test_path_is_missing .git/sequencer &&
+       git cat-file commit HEAD >msg &&
+       grep "cherry picked from" msg
+'
+
+test_expect_success '--continue respects -x in first commit in multi-pick' '
+       pristine_detach initial &&
+       test_must_fail git cherry-pick -x picked anotherpick &&
+       echo c >foo &&
+       git add foo &&
+       git cherry-pick --continue &&
+       test_path_is_missing .git/sequencer &&
+       git cat-file commit HEAD^ >msg &&
+       picked=$(git rev-parse --verify picked) &&
+       grep "cherry picked from.*$picked" msg
+'
+
 test_expect_success '--signoff is not automatically propagated to resolved conflict' '
        pristine_detach initial &&
        test_must_fail git cherry-pick --signoff base..anotherpick &&
@@ -306,6 +425,32 @@ test_expect_success '--signoff is not automatically propagated to resolved confl
        grep "Signed-off-by:" anotherpick_msg
 '
 
+test_expect_success '--signoff dropped for implicit commit of resolution, multi-pick case' '
+       pristine_detach initial &&
+       test_must_fail git cherry-pick -s picked anotherpick &&
+       echo c >foo &&
+       git add foo &&
+       git cherry-pick --continue &&
+
+       git diff --exit-code HEAD &&
+       test_cmp_rev initial HEAD^^ &&
+       git cat-file commit HEAD^ >msg &&
+       ! grep Signed-off-by: msg
+'
+
+test_expect_success 'sign-off needs to be reaffirmed after conflict resolution, single-pick case' '
+       pristine_detach initial &&
+       test_must_fail git cherry-pick -s picked &&
+       echo c >foo &&
+       git add foo &&
+       git cherry-pick --continue &&
+
+       git diff --exit-code HEAD &&
+       test_cmp_rev initial HEAD^ &&
+       git cat-file commit HEAD >msg &&
+       ! grep Signed-off-by: msg
+'
+
 test_expect_success 'malformed instruction sheet 1' '
        pristine_detach initial &&
        test_must_fail git cherry-pick base..anotherpick &&
@@ -328,4 +473,9 @@ test_expect_success 'malformed instruction sheet 2' '
        test_must_fail git cherry-pick --continue
 '
 
+test_expect_success 'empty commit set' '
+       pristine_detach initial &&
+       test_expect_code 128 git cherry-pick base..base
+'
+
 test_done
index 94373ca9a0c20a4465a8788eef3dd7596f6e6c2d..b1361ce54693a07486f5837b0fe477f828b80a4e 100755 (executable)
@@ -11,7 +11,7 @@ test_expect_success 'setup' '
        test_commit 1 &&
        test_commit 2 &&
        mkdir sub &&
-       test_commit 3 sub/3 &&
+       test_commit 3 sub/3.t &&
        test_commit 4
 '
 
diff --git a/t/t4136-apply-check.sh b/t/t4136-apply-check.sh
new file mode 100755 (executable)
index 0000000..a321f7c
--- /dev/null
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+test_description='git apply should exit non-zero with unrecognized input.'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+       test_commit 1
+'
+
+test_expect_success 'apply --check exits non-zero with unrecognized input' '
+       test_must_fail git apply --check - <<-\EOF
+       I am not a patch
+       I look nothing like a patch
+       git apply must fail
+       EOF
+'
+
+test_done
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 bafcca765e4fea92f430e7127506a2370e062ec7..9bf69e9a0f0bff632932929b5ba41f767baf3fca 100755 (executable)
@@ -97,7 +97,7 @@ test_expect_success 'setup' '
        git symbolic-ref HEAD refs/heads/B
 '
 
-pull_to_client 1st "A" $((11*3))
+pull_to_client 1st "refs/heads/B refs/heads/A" $((11*3))
 
 test_expect_success 'post 1st pull setup' '
        add A11 $A10 &&
@@ -110,9 +110,9 @@ test_expect_success 'post 1st pull setup' '
        done
 '
 
-pull_to_client 2nd "B" $((64*3))
+pull_to_client 2nd "refs/heads/B" $((64*3))
 
-pull_to_client 3rd "A" $((1*3))
+pull_to_client 3rd "refs/heads/A" $((1*3))
 
 test_expect_success 'clone shallow' '
        git clone --depth 2 "file://$(pwd)/." shallow
diff --git a/t/t5527-fetch-odd-refs.sh b/t/t5527-fetch-odd-refs.sh
new file mode 100755 (executable)
index 0000000..edea9f9
--- /dev/null
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+test_description='test fetching of oddly-named refs'
+. ./test-lib.sh
+
+# afterwards we will have:
+#  HEAD - two
+#  refs/for/refs/heads/master - one
+#  refs/heads/master - three
+test_expect_success 'setup repo with odd suffix ref' '
+       echo content >file &&
+       git add . &&
+       git commit -m one &&
+       git update-ref refs/for/refs/heads/master HEAD &&
+       echo content >>file &&
+       git commit -a -m two &&
+       echo content >>file &&
+       git commit -a -m three &&
+       git checkout HEAD^
+'
+
+test_expect_success 'suffix ref is ignored during fetch' '
+       git clone --bare file://"$PWD" suffix &&
+       echo three >expect &&
+       git --git-dir=suffix log -1 --format=%s refs/heads/master >actual &&
+       test_cmp expect actual
+'
+
+test_done
index 64767d87055c9ad65a225432b5193497c9fad405..1eea64765608dc4a2e4b19eec4155890306e5d59 100755 (executable)
@@ -40,6 +40,22 @@ test_expect_success 'setup remote repository' '
        mv test_repo.git "$HTTPD_DOCUMENT_ROOT_PATH"
 '
 
+test_expect_success 'create password-protected repository' '
+       mkdir -p "$HTTPD_DOCUMENT_ROOT_PATH/auth/dumb" &&
+       cp -Rf "$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git" \
+              "$HTTPD_DOCUMENT_ROOT_PATH/auth/dumb/test_repo.git"
+'
+
+test_expect_success 'setup askpass helper' '
+       cat >askpass <<-\EOF &&
+       #!/bin/sh
+       echo user@host
+       EOF
+       chmod +x askpass &&
+       GIT_ASKPASS="$PWD/askpass" &&
+       export GIT_ASKPASS
+'
+
 test_expect_success 'clone remote repository' '
        cd "$ROOT_PATH" &&
        git clone $HTTPD_URL/dumb/test_repo.git test_repo_clone
@@ -144,6 +160,24 @@ test_expect_success 'PUT and MOVE sends object to URLs with SHA-1 hash suffix' '
 test_http_push_nonff "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git \
        "$ROOT_PATH"/test_repo_clone master
 
+test_expect_success 'push to password-protected repository (user in URL)' '
+       test_commit pw-user &&
+       git push "$HTTPD_URL_USER/auth/dumb/test_repo.git" HEAD &&
+       git rev-parse --verify HEAD >expect &&
+       git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/auth/dumb/test_repo.git" \
+               rev-parse --verify HEAD >actual &&
+       test_cmp expect actual
+'
+
+test_expect_failure 'push to password-protected repository (no user in URL)' '
+       test_commit pw-nouser &&
+       git push "$HTTPD_URL/auth/dumb/test_repo.git" HEAD &&
+       git rev-parse --verify HEAD >expect &&
+       git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/auth/dumb/test_repo.git" \
+               rev-parse --verify HEAD >actual &&
+       test_cmp expect actual
+'
+
 stop_httpd
 
 test_done
index a73c82635ff6fba6fcef4f139ff09205c1b9b6de..9b85d420c39a0f2192b6b829a6c7912ae28d8e92 100755 (executable)
@@ -154,5 +154,37 @@ test_expect_success 'push (chunked)' '
         test $HEAD = $(git rev-parse --verify HEAD))
 '
 
+test_expect_success 'push --all can push to empty repo' '
+       d=$HTTPD_DOCUMENT_ROOT_PATH/empty-all.git &&
+       git init --bare "$d" &&
+       git --git-dir="$d" config http.receivepack true &&
+       git push --all "$HTTPD_URL"/smart/empty-all.git
+'
+
+test_expect_success 'push --mirror can push to empty repo' '
+       d=$HTTPD_DOCUMENT_ROOT_PATH/empty-mirror.git &&
+       git init --bare "$d" &&
+       git --git-dir="$d" config http.receivepack true &&
+       git push --mirror "$HTTPD_URL"/smart/empty-mirror.git
+'
+
+test_expect_success 'push --all to repo with alternates' '
+       s=$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git &&
+       d=$HTTPD_DOCUMENT_ROOT_PATH/alternates-all.git &&
+       git clone --bare --shared "$s" "$d" &&
+       git --git-dir="$d" config http.receivepack true &&
+       git --git-dir="$d" repack -adl &&
+       git push --all "$HTTPD_URL"/smart/alternates-all.git
+'
+
+test_expect_success 'push --mirror to repo with alternates' '
+       s=$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git &&
+       d=$HTTPD_DOCUMENT_ROOT_PATH/alternates-mirror.git &&
+       git clone --bare --shared "$s" "$d" &&
+       git --git-dir="$d" config http.receivepack true &&
+       git --git-dir="$d" repack -adl &&
+       git push --mirror "$HTTPD_URL"/smart/alternates-mirror.git
+'
+
 stop_httpd
 test_done
diff --git a/t/t7106-reset-sequence.sh b/t/t7106-reset-sequence.sh
deleted file mode 100755 (executable)
index 83f7ea5..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/bin/sh
-
-test_description='Test interaction of reset --hard with sequencer
-
-  + anotherpick: rewrites foo to d
-  + picked: rewrites foo to c
-  + unrelatedpick: rewrites unrelated to reallyunrelated
-  + base: rewrites foo to b
-  + initial: writes foo as a, unrelated as unrelated
-'
-
-. ./test-lib.sh
-
-pristine_detach () {
-       git cherry-pick --quit &&
-       git checkout -f "$1^0" &&
-       git read-tree -u --reset HEAD &&
-       git clean -d -f -f -q -x
-}
-
-test_expect_success setup '
-       echo unrelated >unrelated &&
-       git add unrelated &&
-       test_commit initial foo a &&
-       test_commit base foo b &&
-       test_commit unrelatedpick unrelated reallyunrelated &&
-       test_commit picked foo c &&
-       test_commit anotherpick foo d &&
-       git config advice.detachedhead false
-
-'
-
-test_expect_success 'reset --hard cleans up sequencer state, providing one-level undo' '
-       pristine_detach initial &&
-       test_must_fail git cherry-pick base..anotherpick &&
-       test_path_is_dir .git/sequencer &&
-       git reset --hard &&
-       test_path_is_missing .git/sequencer &&
-       test_path_is_dir .git/sequencer-old &&
-       git reset --hard &&
-       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 463254c72734beaf74948b6c424367ef4fea9d1a..83acf68bc3c19770eb690ece139892ca75329216 100755 (executable)
@@ -505,9 +505,63 @@ test_expect_success 'verify that non-notes are untouched by a fanout change' '
        test_cmp expect_non-note3 actual
 
 '
+
+# Change the notes for the three top commits
+test_tick
+cat >input <<INPUT_END
+commit refs/notes/many_notes
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+data <<COMMIT
+changing notes for the top three commits
+COMMIT
+from refs/notes/many_notes^0
+INPUT_END
+
+rm expect
+i=$num_commits
+j=0
+while test $j -lt 3
+do
+       cat >>input <<INPUT_END
+N inline refs/heads/many_commits~$j
+data <<EOF
+changed note for commit #$i
+EOF
+INPUT_END
+       cat >>expect <<EXPECT_END
+    commit #$i
+    changed note for commit #$i
+EXPECT_END
+       i=$(($i - 1))
+       j=$(($j + 1))
+done
+
+test_expect_success 'change a few existing notes' '
+
+       git fast-import <input &&
+       GIT_NOTES_REF=refs/notes/many_notes git log -n3 refs/heads/many_commits |
+           grep "^    " > actual &&
+       test_cmp expect actual
+
+'
+
+test_expect_success 'verify that changing notes respect existing fanout' '
+
+       # None of the entries in the top-level notes tree should be a full SHA1
+       git ls-tree --name-only refs/notes/many_notes |
+       while read path
+       do
+               if test $(expr length "$path") -ge 40
+               then
+                       return 1
+               fi
+       done
+
+'
+
 remaining_notes=10
 test_tick
-cat >>input <<INPUT_END
+cat >input <<INPUT_END
 commit refs/notes/many_notes
 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 data <<COMMIT
@@ -516,12 +570,11 @@ COMMIT
 from refs/notes/many_notes^0
 INPUT_END
 
-i=$remaining_notes
-while test $i -lt $num_commits
+i=$(($num_commits - $remaining_notes))
+for sha1 in $(git rev-list -n $i refs/heads/many_commits)
 do
-       i=$(($i + 1))
        cat >>input <<INPUT_END
-N 0000000000000000000000000000000000000000 :$i
+N 0000000000000000000000000000000000000000 $sha1
 INPUT_END
 done
 
index 51814b5da3064b617fa268a6b2bc6b3d6cb0b110..9b25ea06b1770395f650ea44618ecb1c425149bc 100644 (file)
@@ -215,7 +215,7 @@ static struct ref *get_refs_via_rsync(struct transport *transport, int for_push)
        rsync.argv = args;
        rsync.stdout_to_stderr = 1;
        args[0] = "rsync";
-       args[1] = (transport->verbose > 0) ? "-rv" : "-r";
+       args[1] = (transport->verbose > 1) ? "-rv" : "-r";
        args[2] = buf.buf;
        args[3] = temp_dir.buf;
        args[4] = NULL;
@@ -268,7 +268,7 @@ static int fetch_objs_via_rsync(struct transport *transport,
        rsync.argv = args;
        rsync.stdout_to_stderr = 1;
        args[0] = "rsync";
-       args[1] = (transport->verbose > 0) ? "-rv" : "-r";
+       args[1] = (transport->verbose > 1) ? "-rv" : "-r";
        args[2] = "--ignore-existing";
        args[3] = "--exclude";
        args[4] = "info";
@@ -351,7 +351,7 @@ static int rsync_transport_push(struct transport *transport,
        args[i++] = "-a";
        if (flags & TRANSPORT_PUSH_DRY_RUN)
                args[i++] = "--dry-run";
-       if (transport->verbose > 0)
+       if (transport->verbose > 1)
                args[i++] = "-v";
        args[i++] = "--ignore-existing";
        args[i++] = "--exclude";
@@ -502,7 +502,7 @@ static struct ref *get_refs_via_connect(struct transport *transport, int for_pus
        struct ref *refs;
 
        connect_setup(transport, for_push, 0);
-       get_remote_heads(data->fd[0], &refs, 0, NULL,
+       get_remote_heads(data->fd[0], &refs,
                         for_push ? REF_NORMAL : 0, &data->extra_have);
        data->got_remote_heads = 1;
 
@@ -527,7 +527,7 @@ static int fetch_refs_via_pack(struct transport *transport,
        args.lock_pack = 1;
        args.use_thin_pack = data->options.thin;
        args.include_tag = data->options.followtags;
-       args.verbose = (transport->verbose > 0);
+       args.verbose = (transport->verbose > 1);
        args.quiet = (transport->verbose < 0);
        args.no_progress = !transport->progress;
        args.depth = data->options.depth;
@@ -537,7 +537,7 @@ static int fetch_refs_via_pack(struct transport *transport,
 
        if (!data->got_remote_heads) {
                connect_setup(transport, 0, 0);
-               get_remote_heads(data->fd[0], &refs_tmp, 0, NULL, 0, NULL);
+               get_remote_heads(data->fd[0], &refs_tmp, 0, NULL);
                data->got_remote_heads = 1;
        }
 
@@ -772,8 +772,7 @@ static int git_transport_push(struct transport *transport, struct ref *remote_re
                struct ref *tmp_refs;
                connect_setup(transport, 1, 0);
 
-               get_remote_heads(data->fd[0], &tmp_refs, 0, NULL, REF_NORMAL,
-                                NULL);
+               get_remote_heads(data->fd[0], &tmp_refs, REF_NORMAL, NULL);
                data->got_remote_heads = 1;
        }
 
@@ -981,7 +980,7 @@ int transport_set_option(struct transport *transport,
 void transport_set_verbosity(struct transport *transport, int verbosity,
        int force_progress)
 {
-       if (verbosity >= 2)
+       if (verbosity >= 1)
                transport->verbose = verbosity <= 3 ? verbosity : 3;
        if (verbosity < 0)
                transport->verbose = -1;
index bf553ad91b55de8a762d56a6ffc6c86e959e878c..7244aac746f9f0dfbdf9784924fefd944d3dc6c2 100644 (file)
@@ -115,7 +115,7 @@ PATTERNS("cpp",
         /* Jump targets or access declarations */
         "!^[ \t]*[A-Za-z_][A-Za-z_0-9]*:.*$\n"
         /* C/++ functions/methods at top level */
-        "^([A-Za-z_][A-Za-z_0-9]*([ \t]+[A-Za-z_][A-Za-z_0-9]*([ \t]*::[ \t]*[^[:space:]]+)?){1,}[ \t]*\\([^;]*)$\n"
+        "^([A-Za-z_][A-Za-z_0-9]*([ \t*]+[A-Za-z_][A-Za-z_0-9]*([ \t]*::[ \t]*[^[:space:]]+)?){1,}[ \t]*\\([^;]*)$\n"
         /* compound type at top level */
         "^((struct|class|enum)[^;]*)$",
         /* -- */