summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/RelNotes-1.5.6.2.txt31
-rw-r--r--Documentation/git-rev-parse.txt5
-rw-r--r--Documentation/git-svn.txt2
l---------RelNotes2
-rw-r--r--builtin-cat-file.c1
-rw-r--r--builtin-describe.c2
-rw-r--r--builtin-fetch.c51
-rw-r--r--builtin-log.c2
-rw-r--r--builtin-reset.c39
-rw-r--r--builtin-upload-archive.c2
-rwxr-xr-xgit-svn.perl20
-rwxr-xr-xt/t6120-describe.sh2
-rwxr-xr-xt/t7102-reset.sh47
13 files changed, 166 insertions, 40 deletions
diff --git a/Documentation/RelNotes-1.5.6.2.txt b/Documentation/RelNotes-1.5.6.2.txt
new file mode 100644
index 0000000000..02d5910d5c
--- /dev/null
+++ b/Documentation/RelNotes-1.5.6.2.txt
@@ -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
diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index 9e273bc5a6..59e95adf42 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -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
diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt
index 97bed54fbd..c350ad0f83 100644
--- a/Documentation/git-svn.txt
+++ b/Documentation/git-svn.txt
@@ -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
diff --git a/RelNotes b/RelNotes
index ebc4b20148..0072160018 120000
--- 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
diff --git a/builtin-cat-file.c b/builtin-cat-file.c
index bd343efae7..880e75af5e 100644
--- a/builtin-cat-file.c
+++ b/builtin-cat-file.c
@@ -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;
diff --git a/builtin-describe.c b/builtin-describe.c
index 3da99c1d06..e515f9ca9b 100644
--- a/builtin-describe.c
+++ b/builtin-describe.c
@@ -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;
}
diff --git a/builtin-fetch.c b/builtin-fetch.c
index e81ee2d02b..97fdc51e31 100644
--- a/builtin-fetch.c
+++ b/builtin-fetch.c
@@ -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;
}
diff --git a/builtin-log.c b/builtin-log.c
index 9817d6fbeb..9979e37f38 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -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;
}
diff --git a/builtin-reset.c b/builtin-reset.c
index f34acb1915..a0321694c5 100644
--- a/builtin-reset.c
+++ b/builtin-reset.c
@@ -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. */
diff --git a/builtin-upload-archive.c b/builtin-upload-archive.c
index 48ae09e9b5..371400d49a 100644
--- a/builtin-upload-archive.c
+++ b/builtin-upload-archive.c
@@ -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 */
diff --git a/git-svn.perl b/git-svn.perl
index 4c9c59bc3f..f789a6eeca 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -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) {
diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh
index c6be2597f7..2fb672c3b4 100755
--- a/t/t6120-describe.sh
+++ b/t/t6120-describe.sh
@@ -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
diff --git a/t/t7102-reset.sh b/t/t7102-reset.sh
index 39ba14148c..96d15083fb 100755
--- a/t/t7102-reset.sh
+++ b/t/t7102-reset.sh
@@ -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