Skip to content

Commit 91048a9

Browse files
committed
push --force-with-lease: implement logic to populate old_sha1_expect[]
This plugs the push_cas_option data collected by the command line option parser to the transport system with a new function apply_push_cas(), which is called after match_push_refs() has already been called. At this point, we know which remote we are talking to, and what remote refs we are going to update, so we can fill in the details that may have been missing from the command line, such as (1) what abbreviated refname the user gave us matches the actual refname at the remote; and (2) which remote-tracking branch in our local repository to read the value of the object to expect at the remote. to populate the old_sha1_expect[] field of each of the remote ref. As stated in the documentation, the use of remote-tracking branch as the default is a tentative one, and we may come up with a better logic as we gain experience. Still nobody uses this information, which is the topic of the next patch. Signed-off-by: Junio C Hamano <[email protected]>
1 parent 28f5d17 commit 91048a9

File tree

6 files changed

+87
-0
lines changed

6 files changed

+87
-0
lines changed

builtin/push.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,13 @@ static int push_with_options(struct transport *transport, int flags)
299299
if (thin)
300300
transport_set_option(transport, TRANS_OPT_THIN, "yes");
301301

302+
if (!is_empty_cas(&cas)) {
303+
if (!transport->smart_options)
304+
die("underlying transport does not support --%s option",
305+
CAS_OPT_NAME);
306+
transport->smart_options->cas = &cas;
307+
}
308+
302309
if (verbosity > 0)
303310
fprintf(stderr, _("Pushing to %s\n"), transport->url);
304311
err = transport_push(transport, refspec_nr, refspec, flags,

builtin/send-pack.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,9 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
242242
if (match_push_refs(local_refs, &remote_refs, nr_refspecs, refspecs, flags))
243243
return -1;
244244

245+
if (!is_empty_cas(&cas))
246+
apply_push_cas(&cas, remote, remote_refs);
247+
245248
set_ref_status_for_push(remote_refs, args.send_mirror,
246249
args.force_update);
247250

remote.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1978,3 +1978,64 @@ int parseopt_push_cas_option(const struct option *opt, const char *arg, int unse
19781978
{
19791979
return parse_push_cas_option(opt->value, arg, unset);
19801980
}
1981+
1982+
int is_empty_cas(const struct push_cas_option *cas)
1983+
{
1984+
return !cas->use_tracking_for_rest && !cas->nr;
1985+
}
1986+
1987+
/*
1988+
* Look at remote.fetch refspec and see if we have a remote
1989+
* tracking branch for the refname there. Fill its current
1990+
* value in sha1[].
1991+
* If we cannot do so, return negative to signal an error.
1992+
*/
1993+
static int remote_tracking(struct remote *remote, const char *refname,
1994+
unsigned char sha1[20])
1995+
{
1996+
char *dst;
1997+
1998+
dst = apply_refspecs(remote->fetch, remote->fetch_refspec_nr, refname);
1999+
if (!dst)
2000+
return -1; /* no tracking ref for refname at remote */
2001+
if (read_ref(dst, sha1))
2002+
return -1; /* we know what the tracking ref is but we cannot read it */
2003+
return 0;
2004+
}
2005+
2006+
static void apply_cas(struct push_cas_option *cas,
2007+
struct remote *remote,
2008+
struct ref *ref)
2009+
{
2010+
int i;
2011+
2012+
/* Find an explicit --<option>=<name>[:<value>] entry */
2013+
for (i = 0; i < cas->nr; i++) {
2014+
struct push_cas *entry = &cas->entry[i];
2015+
if (!refname_match(entry->refname, ref->name, ref_rev_parse_rules))
2016+
continue;
2017+
ref->expect_old_sha1 = 1;
2018+
if (!entry->use_tracking)
2019+
hashcpy(ref->old_sha1_expect, cas->entry[i].expect);
2020+
else if (remote_tracking(remote, ref->name, ref->old_sha1_expect))
2021+
ref->expect_old_no_trackback = 1;
2022+
return;
2023+
}
2024+
2025+
/* Are we using "--<option>" to cover all? */
2026+
if (!cas->use_tracking_for_rest)
2027+
return;
2028+
2029+
ref->expect_old_sha1 = 1;
2030+
if (remote_tracking(remote, ref->name, ref->old_sha1_expect))
2031+
ref->expect_old_no_trackback = 1;
2032+
}
2033+
2034+
void apply_push_cas(struct push_cas_option *cas,
2035+
struct remote *remote,
2036+
struct ref *remote_refs)
2037+
{
2038+
struct ref *ref;
2039+
for (ref = remote_refs; ref; ref = ref->next)
2040+
apply_cas(cas, remote, ref);
2041+
}

remote.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,13 @@ struct ref {
7777
struct ref *next;
7878
unsigned char old_sha1[20];
7979
unsigned char new_sha1[20];
80+
unsigned char old_sha1_expect[20]; /* used by expect-old */
8081
char *symref;
8182
unsigned int
8283
force:1,
8384
forced_update:1,
85+
expect_old_sha1:1,
86+
expect_old_no_trackback:1,
8487
deletion:1,
8588
matched:1;
8689

@@ -248,4 +251,7 @@ extern int parseopt_push_cas_option(const struct option *, const char *arg, int
248251
extern int parse_push_cas_option(struct push_cas_option *, const char *arg, int unset);
249252
extern void clear_cas_option(struct push_cas_option *);
250253

254+
extern int is_empty_cas(const struct push_cas_option *);
255+
void apply_push_cas(struct push_cas_option *, struct remote *, struct ref *);
256+
251257
#endif

transport.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,6 +1142,12 @@ int transport_push(struct transport *transport,
11421142
return -1;
11431143
}
11441144

1145+
if (transport->smart_options &&
1146+
transport->smart_options->cas &&
1147+
!is_empty_cas(transport->smart_options->cas))
1148+
apply_push_cas(transport->smart_options->cas,
1149+
transport->remote, remote_refs);
1150+
11451151
set_ref_status_for_push(remote_refs,
11461152
flags & TRANSPORT_PUSH_MIRROR,
11471153
flags & TRANSPORT_PUSH_FORCE);

transport.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ struct git_transport_options {
1414
int depth;
1515
const char *uploadpack;
1616
const char *receivepack;
17+
struct push_cas_option *cas;
1718
};
1819

1920
struct transport {
@@ -127,6 +128,9 @@ struct transport *transport_get(struct remote *, const char *);
127128
/* Transfer the data as a thin pack if not null */
128129
#define TRANS_OPT_THIN "thin"
129130

131+
/* Check the current value of the remote ref */
132+
#define TRANS_OPT_CAS "cas"
133+
130134
/* Keep the pack that was transferred if not null */
131135
#define TRANS_OPT_KEEP "keep"
132136

0 commit comments

Comments
 (0)