Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCongyi Wu <congyiwu@gmail.com>2013-01-03 22:26:11 +0400
committerCongyi Wu <congyiwu@gmail.com>2013-01-04 02:19:55 +0400
commit4128f5aa31f4620c2393cc49e6e44e23d07fe58f (patch)
treee01d34b2564939adb9593c1d675dedfa4eb6b305 /src
parent07871d3adcfdaba7ad5f99f89299258d1dbd92f9 (diff)
Fix bug in gen_pktline() for deletes of missing remote refs
* gen_pktline() in smart_protocol.c was skipping refspecs that deleted refs that were not advertised by the server. The new behavior is to send a delete command with an old-id of zero, which matches the behavior of the official git client. * Update test_network_push__delete() in reaction to above fix. * Obviate messy logic that handles missing push_spec rrefs by canonicalizing push_spec. After calculate_work(), loid, roid, and rref, are filled in with exactly what is sent to the server
Diffstat (limited to 'src')
-rw-r--r--src/push.c53
-rw-r--r--src/transports/smart_protocol.c55
2 files changed, 28 insertions, 80 deletions
diff --git a/src/push.c b/src/push.c
index 1d63d574e..efca743b3 100644
--- a/src/push.c
+++ b/src/push.c
@@ -101,24 +101,27 @@ static int parse_refspec(push_spec **spec, const char *str)
if (delim == NULL) {
s->lref = git__strdup(str);
check(s->lref);
- s->rref = NULL;
} else {
if (delim - str) {
s->lref = git__strndup(str, delim - str);
check(s->lref);
- } else
- s->lref = NULL;
+ }
if (strlen(delim + 1)) {
s->rref = git__strdup(delim + 1);
check(s->rref);
- } else
- s->rref = NULL;
+ }
}
if (!s->lref && !s->rref)
goto on_error;
+ /* If rref is ommitted, use the same ref name as lref */
+ if (!s->rref) {
+ s->rref = git__strdup(s->lref);
+ check(s->rref);
+ }
+
#undef check
*spec = s;
@@ -282,44 +285,24 @@ static int calculate_work(git_push *push)
push_spec *spec;
unsigned int i, j;
+ /* Update local and remote oids*/
+
git_vector_foreach(&push->specs, i, spec) {
if (spec->lref) {
+ /* This is a create or update. Local ref must exist. */
if (git_reference_name_to_id(
&spec->loid, push->repo, spec->lref) < 0) {
giterr_set(GIT_ENOTFOUND, "No such reference '%s'", spec->lref);
return -1;
}
+ }
- if (!spec->rref) {
- /*
- * No remote reference given; if we find a remote
- * reference with the same name we will update it,
- * otherwise a new reference will be created.
- */
- git_vector_foreach(&push->remote->refs, j, head) {
- if (!strcmp(spec->lref, head->name)) {
- /*
- * Update remote reference
- */
- git_oid_cpy(&spec->roid, &head->oid);
-
- break;
- }
- }
- } else {
- /*
- * Remote reference given; update the given
- * reference or create it.
- */
- git_vector_foreach(&push->remote->refs, j, head) {
- if (!strcmp(spec->rref, head->name)) {
- /*
- * Update remote reference
- */
- git_oid_cpy(&spec->roid, &head->oid);
-
- break;
- }
+ if (spec->rref) {
+ /* Remote ref may or may not (e.g. during create) already exist. */
+ git_vector_foreach(&push->remote->refs, j, head) {
+ if (!strcmp(spec->rref, head->name)) {
+ git_oid_cpy(&spec->roid, &head->oid);
+ break;
}
}
}
diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c
index a73315975..34f0f8449 100644
--- a/src/transports/smart_protocol.c
+++ b/src/transports/smart_protocol.c
@@ -499,61 +499,25 @@ on_error:
static int gen_pktline(git_buf *buf, git_push *push)
{
- git_remote_head *head;
push_spec *spec;
- unsigned int i, j, len;
- char hex[41]; hex[40] = '\0';
+ size_t i, len;
+ char old_id[41], new_id[41];
+
+ old_id[40] = '\0'; new_id[40] = '\0';
git_vector_foreach(&push->specs, i, spec) {
- len = 2*GIT_OID_HEXSZ + 7;
+ len = 2*GIT_OID_HEXSZ + 7 + strlen(spec->rref);
if (i == 0) {
- len +=1; /* '\0' */
+ ++len; /* '\0' */
if (push->report_status)
len += strlen(GIT_CAP_REPORT_STATUS);
}
- if (spec->lref) {
- len += spec->rref ? strlen(spec->rref) : strlen(spec->lref);
+ git_oid_fmt(old_id, &spec->roid);
+ git_oid_fmt(new_id, &spec->loid);
- if (git_oid_iszero(&spec->roid)) {
-
- /*
- * Create remote reference
- */
- git_oid_fmt(hex, &spec->loid);
- git_buf_printf(buf, "%04x%s %s %s", len,
- GIT_OID_HEX_ZERO, hex,
- spec->rref ? spec->rref : spec->lref);
-
- } else {
-
- /*
- * Update remote reference
- */
- git_oid_fmt(hex, &spec->roid);
- git_buf_printf(buf, "%04x%s ", len, hex);
-
- git_oid_fmt(hex, &spec->loid);
- git_buf_printf(buf, "%s %s", hex,
- spec->rref ? spec->rref : spec->lref);
- }
- } else {
- /*
- * Delete remote reference
- */
- git_vector_foreach(&push->remote->refs, j, head) {
- if (!strcmp(spec->rref, head->name)) {
- len += strlen(spec->rref);
-
- git_oid_fmt(hex, &head->oid);
- git_buf_printf(buf, "%04x%s %s %s", len,
- hex, GIT_OID_HEX_ZERO, head->name);
-
- break;
- }
- }
- }
+ git_buf_printf(buf, "%04x%s %s %s", len, old_id, new_id, spec->rref);
if (i == 0) {
git_buf_putc(buf, '\0');
@@ -563,6 +527,7 @@ static int gen_pktline(git_buf *buf, git_push *push)
git_buf_putc(buf, '\n');
}
+
git_buf_puts(buf, "0000");
return git_buf_oom(buf) ? -1 : 0;
}