Skip to content

Commit ff27adf

Browse files
author
Junio C Hamano
committed
Support +<src>:<dst> format in push as well.
Signed-off-by: Junio C Hamano <[email protected]>
1 parent efe9bf0 commit ff27adf

File tree

3 files changed

+24
-6
lines changed

3 files changed

+24
-6
lines changed

cache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@ struct ref {
309309
struct ref *next;
310310
unsigned char old_sha1[20];
311311
unsigned char new_sha1[20];
312+
unsigned char force;
312313
struct ref *peer_ref; /* when renaming */
313314
char name[0];
314315
};

connect.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,26 @@ int path_match(const char *path, int nr, char **match)
8282
struct refspec {
8383
char *src;
8484
char *dst;
85+
char force;
8586
};
8687

88+
/*
89+
* A:B means fast forward remote B with local A.
90+
* +A:B means overwrite remote B with local A.
91+
* +A is a shorthand for +A:A.
92+
* A is a shorthand for A:A.
93+
*/
8794
static struct refspec *parse_ref_spec(int nr_refspec, char **refspec)
8895
{
8996
int i;
90-
struct refspec *rs = xmalloc(sizeof(*rs) * (nr_refspec + 1));
97+
struct refspec *rs = xcalloc(sizeof(*rs), (nr_refspec + 1));
9198
for (i = 0; i < nr_refspec; i++) {
9299
char *sp, *dp, *ep;
93100
sp = refspec[i];
101+
if (*sp == '+') {
102+
rs[i].force = 1;
103+
sp++;
104+
}
94105
ep = strchr(sp, ':');
95106
if (ep) {
96107
dp = ep + 1;
@@ -216,8 +227,10 @@ static int match_explicit_refs(struct ref *src, struct ref *dst,
216227
error("dst ref %s receives from more than one src.",
217228
matched_dst->name);
218229
}
219-
else
230+
else {
220231
matched_dst->peer_ref = matched_src;
232+
matched_dst->force = rs[i].force;
233+
}
221234
}
222235
return -errs;
223236
}

send-pack.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,8 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
206206
/* This part determines what can overwrite what.
207207
* The rules are:
208208
*
209-
* (0) you can always use --force.
209+
* (0) you can always use --force or +A:B notation to
210+
* selectively force individual ref pairs.
210211
*
211212
* (1) if the old thing does not exist, it is OK.
212213
*
@@ -218,16 +219,19 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
218219
* descendant of old, it is OK.
219220
*/
220221

221-
if (!force_update && !is_zero_sha1(ref->old_sha1)) {
222+
if (!force_update &&
223+
!is_zero_sha1(ref->old_sha1) &&
224+
!ref->force) {
222225
if (!has_sha1_file(ref->old_sha1)) {
223226
error("remote '%s' object %s does not "
224227
"exist on local",
225228
ref->name, sha1_to_hex(ref->old_sha1));
226229
continue;
227230
}
231+
228232
/* We assume that local is fsck-clean. Otherwise
229-
* you _could_ have a old tag which points at
230-
* something you do not have which may or may not
233+
* you _could_ have an old tag which points at
234+
* something you do not have, which may or may not
231235
* be a commit.
232236
*/
233237
if (!ref_newer(ref->peer_ref->new_sha1,

0 commit comments

Comments
 (0)