summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Junio C Hamano <gitster@pobox.com>2009-01-28 00:36:52 -0800
committerLibravatar Junio C Hamano <gitster@pobox.com>2009-01-28 00:36:52 -0800
commit297f6a535cb46d246d47a9ff2473cef4ee1ada27 (patch)
tree025e614babe85b8a9994354dca4bc6f6a4c4f471
parenttests: Avoid single-shot environment export for shell function invocation (diff)
parentsend-pack: do not send unknown object name from ".have" to pack-objects (diff)
downloadtgif-297f6a535cb46d246d47a9ff2473cef4ee1ada27.tar.xz
Merge branch 'maint'
* maint: send-pack: do not send unknown object name from ".have" to pack-objects test-path-utils: Fix off by one, found by valgrind get_sha1_basic(): fix invalid memory access, found by valgrind
-rw-r--r--builtin-send-pack.c43
-rw-r--r--sha1_name.c2
-rwxr-xr-xt/t5519-push-alternates.sh106
-rw-r--r--test-path-utils.c2
4 files changed, 129 insertions, 24 deletions
diff --git a/builtin-send-pack.c b/builtin-send-pack.c
index a9fdbf9d45..d65d019692 100644
--- a/builtin-send-pack.c
+++ b/builtin-send-pack.c
@@ -15,6 +15,20 @@ static struct send_pack_args args = {
/* .receivepack = */ "git-receive-pack",
};
+static int feed_object(const unsigned char *sha1, int fd, int negative)
+{
+ char buf[42];
+
+ if (negative && !has_sha1_file(sha1))
+ return 1;
+
+ memcpy(buf + negative, sha1_to_hex(sha1), 40);
+ if (negative)
+ buf[0] = '^';
+ buf[40 + negative] = '\n';
+ return write_or_whine(fd, buf, 41 + negative, "send-pack: send refs");
+}
+
/*
* Make a pack stream and spit it out into file descriptor fd
*/
@@ -35,7 +49,6 @@ static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *ext
};
struct child_process po;
int i;
- char buf[42];
if (args.use_thin_pack)
argv[4] = "--thin";
@@ -51,31 +64,17 @@ static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *ext
* We feed the pack-objects we just spawned with revision
* parameters by writing to the pipe.
*/
- for (i = 0; i < extra->nr; i++) {
- memcpy(buf + 1, sha1_to_hex(&extra->array[i][0]), 40);
- buf[0] = '^';
- buf[41] = '\n';
- if (!write_or_whine(po.in, buf, 42, "send-pack: send refs"))
+ for (i = 0; i < extra->nr; i++)
+ if (!feed_object(extra->array[i], po.in, 1))
break;
- }
while (refs) {
if (!is_null_sha1(refs->old_sha1) &&
- has_sha1_file(refs->old_sha1)) {
- memcpy(buf + 1, sha1_to_hex(refs->old_sha1), 40);
- buf[0] = '^';
- buf[41] = '\n';
- if (!write_or_whine(po.in, buf, 42,
- "send-pack: send refs"))
- break;
- }
- if (!is_null_sha1(refs->new_sha1)) {
- memcpy(buf, sha1_to_hex(refs->new_sha1), 40);
- buf[40] = '\n';
- if (!write_or_whine(po.in, buf, 41,
- "send-pack: send refs"))
- break;
- }
+ !feed_object(refs->old_sha1, po.in, 1))
+ break;
+ if (!is_null_sha1(refs->new_sha1) &&
+ !feed_object(refs->new_sha1, po.in, 0))
+ break;
refs = refs->next;
}
diff --git a/sha1_name.c b/sha1_name.c
index 159c2ab84f..722fc35a6d 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -309,7 +309,7 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
/* basic@{time or number} format to query ref-log */
reflog_len = at = 0;
- if (str[len-1] == '}') {
+ if (len && str[len-1] == '}') {
for (at = 0; at < len - 1; at++) {
if (str[at] == '@' && str[at+1] == '{') {
reflog_len = (len-1) - (at+2);
diff --git a/t/t5519-push-alternates.sh b/t/t5519-push-alternates.sh
new file mode 100755
index 0000000000..6dfc55ad61
--- /dev/null
+++ b/t/t5519-push-alternates.sh
@@ -0,0 +1,106 @@
+#!/bin/sh
+
+test_description='push to a repository that borrows from elsewhere'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+ mkdir alice-pub &&
+ (
+ cd alice-pub &&
+ GIT_DIR=. git init
+ ) &&
+ mkdir alice-work &&
+ (
+ cd alice-work &&
+ git init &&
+ >file &&
+ git add . &&
+ git commit -m initial &&
+ git push ../alice-pub master
+ ) &&
+
+ # Project Bob is a fork of project Alice
+ mkdir bob-pub &&
+ (
+ cd bob-pub &&
+ GIT_DIR=. git init &&
+ mkdir -p objects/info &&
+ echo ../../alice-pub/objects >objects/info/alternates
+ ) &&
+ git clone alice-pub bob-work &&
+ (
+ cd bob-work &&
+ git push ../bob-pub master
+ )
+'
+
+test_expect_success 'alice works and pushes' '
+ (
+ cd alice-work &&
+ echo more >file &&
+ git commit -a -m second &&
+ git push ../alice-pub
+ )
+'
+
+test_expect_success 'bob fetches from alice, works and pushes' '
+ (
+ # Bob acquires what Alice did in his work tree first.
+ # Even though these objects are not directly in
+ # the public repository of Bob, this push does not
+ # need to send the commit Bob received from Alice
+ # to his public repository, as all the object Alice
+ # has at her public repository are available to it
+ # via its alternates.
+ cd bob-work &&
+ git pull ../alice-pub master &&
+ echo more bob >file &&
+ git commit -a -m third &&
+ git push ../bob-pub
+ ) &&
+
+ # Check that the second commit by Alice is not sent
+ # to ../bob-pub
+ (
+ cd bob-pub &&
+ second=$(git rev-parse HEAD^) &&
+ rm -f objects/info/alternates &&
+ test_must_fail git cat-file -t $second &&
+ echo ../../alice-pub/objects >objects/info/alternates
+ )
+'
+
+test_expect_success 'clean-up in case the previous failed' '
+ (
+ cd bob-pub &&
+ echo ../../alice-pub/objects >objects/info/alternates
+ )
+'
+
+test_expect_success 'alice works and pushes again' '
+ (
+ # Alice does not care what Bob does. She does not
+ # even have to be aware of his existence. She just
+ # keeps working and pushing
+ cd alice-work &&
+ echo more alice >file &&
+ git commit -a -m fourth &&
+ git push ../alice-pub
+ )
+'
+
+test_expect_success 'bob works and pushes' '
+ (
+ # This time Bob does not pull from Alice, and
+ # the master branch at her public repository points
+ # at a commit Bob does not know about. This should
+ # not prevent the push by Bob from succeeding.
+ cd bob-work &&
+ echo yet more bob >file &&
+ git commit -a -m fifth &&
+ git push ../bob-pub
+ )
+'
+
+test_done
diff --git a/test-path-utils.c b/test-path-utils.c
index a0bcb0e210..2c0f5a37e8 100644
--- a/test-path-utils.c
+++ b/test-path-utils.c
@@ -3,7 +3,7 @@
int main(int argc, char **argv)
{
if (argc == 3 && !strcmp(argv[1], "normalize_absolute_path")) {
- char *buf = xmalloc(strlen(argv[2])+1);
+ char *buf = xmalloc(PATH_MAX + 1);
int rv = normalize_absolute_path(buf, argv[2]);
assert(strlen(buf) == rv);
puts(buf);