**tail = NULL;
}
+static struct ref *try_explicit_object_name(const char *name)
+{
+ unsigned char sha1[20];
+ struct ref *ref;
+ int len;
+ if (get_sha1(name, sha1))
+ return NULL;
+ len = strlen(name) + 1;
+ ref = xcalloc(1, sizeof(*ref) + len);
+ memcpy(ref->name, name, len);
+ memcpy(ref->new_sha1, sha1, 20);
+ return ref;
+}
+
static int match_explicit_refs(struct ref *src, struct ref *dst,
struct ref ***dst_tail, struct refspec *rs)
{
case 1:
break;
case 0:
+ /* The source could be in the get_sha1() format
+ * not a reference name.
+ */
+ matched_src = try_explicit_object_name(rs[i].src);
+ if (matched_src)
+ break;
errs = 1;
error("src refspec %s does not match any.");
break;
/* pushing "master:master" when
* remote does not have master yet.
*/
- int len = strlen(matched_src->name);
+ int len = strlen(matched_src->name) + 1;
matched_dst = xcalloc(1, sizeof(*dst) + len);
memcpy(matched_dst->name, matched_src->name,
len);
}
if (errs)
continue;
- if (matched_src->peer_ref) {
- errs = 1;
- error("src ref %s is sent to more than one dst.",
- matched_src->name);
- }
- else
- matched_src->peer_ref = matched_dst;
if (matched_dst->peer_ref) {
errs = 1;
error("dst ref %s receives from more than one src.",
if (src->peer_ref)
continue;
dst_peer = find_ref_by_name(dst, src->name);
- if (dst_peer && dst_peer->peer_ref)
+ if ((dst_peer && dst_peer->peer_ref) || (!dst_peer && !all))
continue;
if (!dst_peer) {
- if (!all)
- continue;
/* Create a new one and link it */
int len = strlen(src->name) + 1;
dst_peer = xcalloc(1, sizeof(*dst_peer) + len);