Merge branch 'js/maint-clone-insteadof' into maint
authorJunio C Hamano <gitster@pobox.com>
Thu, 3 Jul 2008 04:32:44 +0000 (21:32 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 3 Jul 2008 04:32:44 +0000 (21:32 -0700)
* js/maint-clone-insteadof:
clone: respect the settings in $HOME/.gitconfig and /etc/gitconfig
clone: respect url.insteadOf setting in global configs

13 files changed:
Documentation/RelNotes-1.5.6.2.txt [new file with mode: 0644]
Documentation/git-rev-parse.txt
Documentation/git-svn.txt
RelNotes
builtin-cat-file.c
builtin-describe.c
builtin-fetch.c
builtin-log.c
builtin-reset.c
builtin-upload-archive.c
git-svn.perl
t/t6120-describe.sh
t/t7102-reset.sh
diff --git a/Documentation/RelNotes-1.5.6.2.txt b/Documentation/RelNotes-1.5.6.2.txt
new file mode 100644 (file)
index 0000000..02d5910
--- /dev/null
@@ -0,0 +1,31 @@
+GIT v1.5.6.2 Release Notes
+==========================
+
+Futureproof
+-----------
+
+ * "git-shell" accepts requests without a dash between "git" and
+   subcommand name (e.g. "git upload-pack") which the newer client will
+   start to make sometime in the future.
+
+Fixes since v1.5.6.1
+--------------------
+
+* Optimization for a large import via "git-svn" introduced in v1.5.6 had a
+  serious memory and temporary file leak, which made it unusable for
+  moderately large import.
+
+* "git-svn" mangled remote nickname used in the configuration file
+  unnecessarily.
+
+* "git diff --check" did not report the result via its exit status
+  reliably.
+
+* "git show" segfaulted when an annotated tag that points at another
+  annotated tag was given to it.
+
+--
+exec >/var/tmp/1
+echo O=$(git describe maint)
+O=v1.5.6.1-13-g4f3dcc2
+git shortlog --no-merges $O..maint
index 9e273bc5a6ee091ad7b81254228d33fd4df5541e..59e95adf42d1d481d636929a0b3ad79eebc53426 100644 (file)
@@ -184,7 +184,10 @@ blobs contained in a commit.
   second ago\}' or '\{1979-02-26 18:30:00\}') to specify the value
   of the ref at a prior point in time.  This suffix may only be
   used immediately following a ref name and the ref must have an
-  existing log ($GIT_DIR/logs/<ref>).
+  existing log ($GIT_DIR/logs/<ref>). Note that this looks up the state
+  of your *local* ref at a given time; e.g., what was in your local
+  `master` branch last week. If you want to look at commits made during
+  certain times, see `--since` and `--until`.
 
 * A ref followed by the suffix '@' with an ordinal specification
   enclosed in a brace pair (e.g. '\{1\}', '\{15\}') to specify
index 97bed54fbde18a1e7c5516382a54b341fc81668e..c350ad0f83b413fa4c7810195f64cdfbbfdd1717 100644 (file)
@@ -513,7 +513,7 @@ have each person clone that repository with 'git clone':
        cd project
        git-init
        git remote add origin server:/pub/project
-       git config --add remote.origin.fetch=+refs/remotes/*:refs/remotes/*
+       git config --add remote.origin.fetch '+refs/remotes/*:refs/remotes/*'
        git fetch
 # Initialize git-svn locally (be sure to use the same URL and -T/-b/-t options as were used on server)
        git-svn init http://svn.foo.org/project
index ebc4b201487945106d08e8848e2c8ee9de41c984..00721600184e50466f31d236001c20577e60db7a 120000 (symlink)
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes-1.5.6.1.txt
\ No newline at end of file
+Documentation/RelNotes-1.5.6.2.txt
\ No newline at end of file
index bd343efae7d6cc6fddef4df5c3433b97bd640d3c..880e75af5e1951689a417aa47e64f99a20d46ae6 100644 (file)
@@ -181,6 +181,7 @@ static int batch_one_object(const char *obj_name, int print_contents)
                write_or_die(1, contents, size);
                printf("\n");
                fflush(stdout);
+               free(contents);
        }
 
        return 0;
index 3da99c1d06f1eeb85e760036dc881282558603d6..e515f9ca9b5d0ec13e96a7866e27bdd9e852b435 100644 (file)
@@ -204,7 +204,7 @@ static void describe(const char *arg, int last_one)
                 */
                display_name(n);
                if (longformat)
-                       show_suffix(0, n->tag->tagged->sha1);
+                       show_suffix(0, n->tag ? n->tag->tagged->sha1 : sha1);
                printf("\n");
                return;
        }
index e81ee2d02b588c83f9ac355d20559271be73871d..97fdc51e3188143e0546512f59be9d2542dcac9a 100644 (file)
@@ -181,9 +181,9 @@ static int s_update_ref(const char *action,
        lock = lock_any_ref_for_update(ref->name,
                                       check_old ? ref->old_sha1 : NULL, 0);
        if (!lock)
-               return 1;
+               return 2;
        if (write_ref_sha1(lock, ref->new_sha1, msg) < 0)
-               return 1;
+               return 2;
        return 0;
 }
 
@@ -233,10 +233,12 @@ static int update_local_ref(struct ref *ref,
 
        if (!is_null_sha1(ref->old_sha1) &&
            !prefixcmp(ref->name, "refs/tags/")) {
-               sprintf(display, "- %-*s %-*s -> %s",
+               int r;
+               r = s_update_ref("updating tag", ref, 0);
+               sprintf(display, "%c %-*s %-*s -> %s%s", r ? '!' : '-',
                        SUMMARY_WIDTH, "[tag update]", REFCOL_WIDTH, remote,
-                       pretty_ref);
-               return s_update_ref("updating tag", ref, 0);
+                       pretty_ref, r ? "  (unable to update local ref)" : "");
+               return r;
        }
 
        current = lookup_commit_reference_gently(ref->old_sha1, 1);
@@ -244,6 +246,7 @@ static int update_local_ref(struct ref *ref,
        if (!current || !updated) {
                const char *msg;
                const char *what;
+               int r;
                if (!strncmp(ref->name, "refs/tags/", 10)) {
                        msg = "storing tag";
                        what = "[new tag]";
@@ -253,27 +256,36 @@ static int update_local_ref(struct ref *ref,
                        what = "[new branch]";
                }
 
-               sprintf(display, "* %-*s %-*s -> %s", SUMMARY_WIDTH, what,
-                       REFCOL_WIDTH, remote, pretty_ref);
-               return s_update_ref(msg, ref, 0);
+               r = s_update_ref(msg, ref, 0);
+               sprintf(display, "%c %-*s %-*s -> %s%s", r ? '!' : '*',
+                       SUMMARY_WIDTH, what, REFCOL_WIDTH, remote, pretty_ref,
+                       r ? "  (unable to update local ref)" : "");
+               return r;
        }
 
        if (in_merge_bases(current, &updated, 1)) {
                char quickref[83];
+               int r;
                strcpy(quickref, find_unique_abbrev(current->object.sha1, DEFAULT_ABBREV));
                strcat(quickref, "..");
                strcat(quickref, find_unique_abbrev(ref->new_sha1, DEFAULT_ABBREV));
-               sprintf(display, "  %-*s %-*s -> %s", SUMMARY_WIDTH, quickref,
-                       REFCOL_WIDTH, remote, pretty_ref);
-               return s_update_ref("fast forward", ref, 1);
+               r = s_update_ref("fast forward", ref, 1);
+               sprintf(display, "%c %-*s %-*s -> %s%s", r ? '!' : ' ',
+                       SUMMARY_WIDTH, quickref, REFCOL_WIDTH, remote,
+                       pretty_ref, r ? "  (unable to update local ref)" : "");
+               return r;
        } else if (force || ref->force) {
                char quickref[84];
+               int r;
                strcpy(quickref, find_unique_abbrev(current->object.sha1, DEFAULT_ABBREV));
                strcat(quickref, "...");
                strcat(quickref, find_unique_abbrev(ref->new_sha1, DEFAULT_ABBREV));
-               sprintf(display, "+ %-*s %-*s -> %s  (forced update)",
-                       SUMMARY_WIDTH, quickref, REFCOL_WIDTH, remote, pretty_ref);
-               return s_update_ref("forced-update", ref, 1);
+               r = s_update_ref("forced-update", ref, 1);
+               sprintf(display, "%c %-*s %-*s -> %s  (%s)", r ? '!' : '+',
+                       SUMMARY_WIDTH, quickref, REFCOL_WIDTH, remote,
+                       pretty_ref,
+                       r ? "unable to update local ref" : "forced update");
+               return r;
        } else {
                sprintf(display, "! %-*s %-*s -> %s  (non fast forward)",
                        SUMMARY_WIDTH, "[rejected]", REFCOL_WIDTH, remote,
@@ -282,7 +294,8 @@ static int update_local_ref(struct ref *ref,
        }
 }
 
-static int store_updated_refs(const char *url, struct ref *ref_map)
+static int store_updated_refs(const char *url, const char *remote_name,
+               struct ref *ref_map)
 {
        FILE *fp;
        struct commit *commit;
@@ -368,6 +381,10 @@ static int store_updated_refs(const char *url, struct ref *ref_map)
                }
        }
        fclose(fp);
+       if (rc & 2)
+               error("some local refs could not be updated; try running\n"
+                     " 'git remote prune %s' to remove any old, conflicting "
+                     "branches", remote_name);
        return rc;
 }
 
@@ -438,7 +455,9 @@ static int fetch_refs(struct transport *transport, struct ref *ref_map)
        if (ret)
                ret = transport_fetch_refs(transport, ref_map);
        if (!ret)
-               ret |= store_updated_refs(transport->url, ref_map);
+               ret |= store_updated_refs(transport->url,
+                               transport->remote->name,
+                               ref_map);
        transport_unlock_pack(transport);
        return ret;
 }
index 9817d6fbeb69393ed321e71b6211a8630b982fab..9979e37f3823734c66f0b98eebf485a078e576bb 100644 (file)
@@ -360,7 +360,7 @@ int cmd_show(int argc, const char **argv, const char *prefix)
                                        t->tag,
                                        diff_get_color_opt(&rev.diffopt, DIFF_RESET));
                        ret = show_object(o->sha1, 1, &rev);
-                       objects[i].item = (struct object *)t->tagged;
+                       objects[i].item = parse_object(t->tagged->sha1);
                        i--;
                        break;
                }
index f34acb1915a7bdbe41113febc90283bc94d0dc1f..a0321694c5c3d5798d28f8fe14493652e0dd0054 100644 (file)
@@ -194,8 +194,40 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
        reflog_action = args_to_str(argv);
        setenv("GIT_REFLOG_ACTION", reflog_action, 0);
 
-       if (i < argc && strcmp(argv[i], "--"))
-               rev = argv[i++];
+       /*
+        * Possible arguments are:
+        *
+        * git reset [-opts] <rev> <paths>...
+        * git reset [-opts] <rev> -- <paths>...
+        * git reset [-opts] -- <paths>...
+        * git reset [-opts] <paths>...
+        *
+        * At this point, argv[i] points immediately after [-opts].
+        */
+
+       if (i < argc) {
+               if (!strcmp(argv[i], "--")) {
+                       i++; /* reset to HEAD, possibly with paths */
+               } else if (i + 1 < argc && !strcmp(argv[i+1], "--")) {
+                       rev = argv[i];
+                       i += 2;
+               }
+               /*
+                * Otherwise, argv[i] could be either <rev> or <paths> and
+                * has to be unambigous.
+                */
+               else if (!get_sha1(argv[i], sha1)) {
+                       /*
+                        * Ok, argv[i] looks like a rev; it should not
+                        * be a filename.
+                        */
+                       verify_non_filename(prefix, argv[i]);
+                       rev = argv[i++];
+               } else {
+                       /* Otherwise we treat this as a filename */
+                       verify_filename(prefix, argv[i]);
+               }
+       }
 
        if (get_sha1(rev, sha1))
                die("Failed to resolve '%s' as a valid ref.", rev);
@@ -205,9 +237,6 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
                die("Could not parse object '%s'.", rev);
        hashcpy(sha1, commit->object.sha1);
 
-       if (i < argc && !strcmp(argv[i], "--"))
-               i++;
-
        /* git reset tree [--] paths... can be used to
         * load chosen paths from the tree into the index without
         * affecting the working tree nor HEAD. */
index 48ae09e9b5268ce1f11cfba433680a147ca39f7e..371400d49a5ff9f6ce297d7af07eb3fd6426c9ee 100644 (file)
@@ -30,7 +30,7 @@ static int run_upload_archive(int argc, const char **argv, const char *prefix)
        if (argc != 2)
                usage(upload_archive_usage);
 
-       if (strlen(argv[1]) > sizeof(buf))
+       if (strlen(argv[1]) + 1 > sizeof(buf))
                die("insanely long repository name");
 
        strcpy(buf, argv[1]); /* enter-repo smudges its argument */
index 4c9c59bc3ffb9ed2f8e808cf6849562669adfd18..f789a6eeca12ed34e6ef3746c3062e56f791d7e9 100755 (executable)
@@ -1462,13 +1462,6 @@ sub verify_remotes_sanity {
        }
 }
 
-# we allow more chars than remotes2config.sh...
-sub sanitize_remote_name {
-       my ($name) = @_;
-       $name =~ tr{A-Za-z0-9:,/+-}{.}c;
-       $name;
-}
-
 sub find_existing_remote {
        my ($url, $remotes) = @_;
        return undef if $no_reuse_existing;
@@ -2853,7 +2846,7 @@ sub _new {
        unless (defined $ref_id && length $ref_id) {
                $_[2] = $ref_id = $Git::SVN::default_ref_id;
        }
-       $_[1] = $repo_id = sanitize_remote_name($repo_id);
+       $_[1] = $repo_id;
        my $dir = "$ENV{GIT_DIR}/svn/$ref_id";
        $_[3] = $path = '' unless (defined $path);
        mkpath(["$ENV{GIT_DIR}/svn"]);
@@ -3243,7 +3236,9 @@ sub close_file {
                my ($tmp_fh, $tmp_filename) = File::Temp::tempfile(UNLINK => 1);
                my $result;
                while ($result = sysread($fh, my $string, 1024)) {
-                       syswrite($tmp_fh, $string, $result);
+                       my $wrote = syswrite($tmp_fh, $string, $result);
+                       defined($wrote) && $wrote == $result
+                               or croak("write $tmp_filename: $!\n");
                }
                defined $result or croak $!;
                close $tmp_fh or croak $!;
@@ -3251,6 +3246,7 @@ sub close_file {
                close $fh or croak $!;
 
                $hash = $::_repository->hash_and_insert_object($tmp_filename);
+               unlink($tmp_filename);
                $hash =~ /^[a-f\d]{40}$/ or die "not a sha1: $hash\n";
                close $fb->{base} or croak $!;
        } else {
@@ -4704,8 +4700,7 @@ sub minimize_connections {
 
                # skip existing cases where we already connect to the root
                if (($ra->{url} eq $ra->{repos_root}) ||
-                   (Git::SVN::sanitize_remote_name($ra->{repos_root}) eq
-                    $repo_id)) {
+                   ($ra->{repos_root} eq $repo_id)) {
                        $root_repos->{$ra->{url}} = $repo_id;
                        next;
                }
@@ -4744,8 +4739,7 @@ sub minimize_connections {
        foreach my $url (keys %$new_urls) {
                # see if we can re-use an existing [svn-remote "repo_id"]
                # instead of creating a(n ugly) new section:
-               my $repo_id = $root_repos->{$url} ||
-                             Git::SVN::sanitize_remote_name($url);
+               my $repo_id = $root_repos->{$url} || $url;
 
                my $fetch = $new_urls->{$url};
                foreach my $path (keys %$fetch) {
index c6be2597f73dbd49e6301d01b5ea3c86ac8c34cb..2fb672c3b43a9efe4cb9c85465f6b33f23724e48 100755 (executable)
@@ -139,4 +139,6 @@ check_describe "test1-lightweight-*" --tags --match="test1-*"
 
 check_describe "test2-lightweight-*" --tags --match="test2-*"
 
+check_describe "test2-lightweight-*" --long --tags --match="test2-*" HEAD^
+
 test_done
index 39ba14148c953d17589450917975372802eecfed..96d15083fb5ac540a0825b8c00dc43c8843a6dec 100755 (executable)
@@ -428,4 +428,51 @@ test_expect_success '--mixed refreshes the index' '
        test_cmp expect output
 '
 
+test_expect_success 'disambiguation (1)' '
+
+       git reset --hard &&
+       >secondfile &&
+       git add secondfile &&
+       test_must_fail git reset secondfile &&
+       test -z "$(git diff --cached --name-only)" &&
+       test -f secondfile &&
+       test ! -s secondfile
+
+'
+
+test_expect_success 'disambiguation (2)' '
+
+       git reset --hard &&
+       >secondfile &&
+       git add secondfile &&
+       rm -f secondfile &&
+       test_must_fail git reset secondfile &&
+       test -n "$(git diff --cached --name-only -- secondfile)" &&
+       test ! -f secondfile
+
+'
+
+test_expect_success 'disambiguation (3)' '
+
+       git reset --hard &&
+       >secondfile &&
+       git add secondfile &&
+       rm -f secondfile &&
+       test_must_fail git reset HEAD secondfile &&
+       test -z "$(git diff --cached --name-only)" &&
+       test ! -f secondfile
+
+'
+
+test_expect_success 'disambiguation (4)' '
+
+       git reset --hard &&
+       >secondfile &&
+       git add secondfile &&
+       rm -f secondfile &&
+       test_must_fail git reset -- secondfile &&
+       test -z "$(git diff --cached --name-only)" &&
+       test ! -f secondfile
+'
+
 test_done