do not send a pack file when 'got send' is only deleting branches The git protocol spec says the client MUST NOT send a pack file if the only command used is 'delete'. Fixes 'got send -d' against Github's server which closed the session upon receiving the empty pack file we sent. This problem wasn't caught by regression tests since git-daemon does accept an empty pack file. Problem reported by jrick.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
diff --git a/got/got.c b/got/got.c
index eaabe5b..f48598b 100644
--- a/got/got.c
+++ b/got/got.c
@@ -7432,12 +7432,15 @@ send_progress(void *arg, off_t packfile_size, int ncommits, int nobj_total,
if (got_path_cmp(branchname, refname,
strlen(branchname), strlen(refname)) == 0) {
status = "deleted";
+ a->sent_something = 1;
break;
}
}
}
- printf("\nServer has %s %s", status, refname);
+ if (a->printed_something)
+ putchar('\n');
+ printf("Server has %s %s", status, refname);
a->printed_something = 1;
return NULL;
}
diff --git a/lib/send.c b/lib/send.c
index 52892c3..110f62e 100644
--- a/lib/send.c
+++ b/lib/send.c
@@ -453,7 +453,7 @@ got_send_pack(const char *remote_name, struct got_pathlist_head *branch_names,
struct got_object_id *my_id = NULL;
int i, nours = 0, ntheirs = 0;
size_t nalloc_ours = 0, nalloc_theirs = 0;
- int refs_to_send = 0;
+ int refs_to_send = 0, refs_to_delete = 0;
off_t bytes_sent = 0;
struct pack_progress_arg ppa;
uint8_t packsha1[SHA1_DIGEST_LENGTH];
@@ -746,37 +746,43 @@ got_send_pack(const char *remote_name, struct got_pathlist_head *branch_names,
TAILQ_FOREACH(pe, delete_branches, entry) {
const char *branchname = pe->path;
if (find_their_ref(&their_refs, branchname))
- refs_to_send++;
+ refs_to_delete++;
}
- if (refs_to_send == 0) {
+ if (refs_to_send == 0 && refs_to_delete == 0) {
got_privsep_send_stop(imsg_sendfds[0]);
goto done;
}
- memset(&ppa, 0, sizeof(ppa));
- ppa.progress_cb = progress_cb;
- ppa.progress_arg = progress_arg;
- err = got_pack_create(packsha1, packfile, their_ids, ntheirs,
- our_ids, nours, repo, 0, 1, pack_progress, &ppa,
- cancel_cb, cancel_arg);
- if (err)
- goto done;
+ if (refs_to_send > 0) {
+ memset(&ppa, 0, sizeof(ppa));
+ ppa.progress_cb = progress_cb;
+ ppa.progress_arg = progress_arg;
+ err = got_pack_create(packsha1, packfile, their_ids, ntheirs,
+ our_ids, nours, repo, 0, 1, pack_progress, &ppa,
+ cancel_cb, cancel_arg);
+ if (err)
+ goto done;
- if (fflush(packfile) == -1) {
- err = got_error_from_errno("fflush");
- goto done;
- }
+ if (fflush(packfile) == -1) {
+ err = got_error_from_errno("fflush");
+ goto done;
+ }
- npackfd = dup(fileno(packfile));
- if (npackfd == -1) {
- err = got_error_from_errno("dup");
- goto done;
+ npackfd = dup(fileno(packfile));
+ if (npackfd == -1) {
+ err = got_error_from_errno("dup");
+ goto done;
+ }
+ err = got_privsep_send_packfd(&sendibuf, npackfd);
+ if (err != NULL)
+ goto done;
+ npackfd = -1;
+ } else {
+ err = got_privsep_send_packfd(&sendibuf, -1);
+ if (err != NULL)
+ goto done;
}
- err = got_privsep_send_packfd(&sendibuf, npackfd);
- if (err != NULL)
- goto done;
- npackfd = -1;
while (!done) {
int success = 0;
diff --git a/libexec/got-send-pack/got-send-pack.c b/libexec/got-send-pack/got-send-pack.c
index 70cdbda..2a886f2 100644
--- a/libexec/got-send-pack/got-send-pack.c
+++ b/libexec/got-send-pack/got-send-pack.c
@@ -820,9 +820,11 @@ send_pack(int fd, struct got_pathlist_head *refs,
if (err)
goto done;
- err = send_pack_file(fd, packfd, ibuf);
- if (err)
- goto done;
+ if (packfd != -1) {
+ err = send_pack_file(fd, packfd, ibuf);
+ if (err)
+ goto done;
+ }
err = readpkt(&n, fd, buf, sizeof(buf));
if (err)
diff --git a/regress/cmdline/send.sh b/regress/cmdline/send.sh
index d8ab1ac..b7603c9 100755
--- a/regress/cmdline/send.sh
+++ b/regress/cmdline/send.sh
@@ -354,19 +354,15 @@ EOF
fi
got send -r $testroot/repo -d refs/heads/branch2 origin \
- > $testroot/stdout.raw 2>$testroot/stderr
+ > $testroot/stdout 2>$testroot/stderr
ret="$?"
if [ "$ret" != "0" ]; then
echo "got send command failed unexpectedly" >&2
test_done "$testroot" "$ret"
return 1
fi
- tr -d '\r' < $testroot/stdout.raw > $testroot/stdout
echo 'Connecting to "origin" 127.0.0.1' > $testroot/stdout.expected
- echo -n "packing 0 references; 0 objects; deltify: 0%; " \
- >> $testroot/stdout.expected
- echo "uploading pack: 32B 100%" >> $testroot/stdout.expected
echo "Server has deleted refs/heads/branch2" \
>> $testroot/stdout.expected