From 47a59185369b8905ad3a4012688cba92fd2ac1ff Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 8 Jul 2013 13:56:53 -0700 Subject: cache.h: move remote/connect API out of it The definition of "struct ref" in "cache.h", a header file so central to the system, always confused me. This structure is not about the local ref used by sha1-name API to name local objects. It is what refspecs are expanded into, after finding out what refs the other side has, to define what refs are updated after object transfer succeeds to what values. It belongs to "remote.h" together with "struct refspec". While we are at it, also move the types and functions related to the Git transport connection to a new header file connect.h Signed-off-by: Junio C Hamano --- builtin/fetch-pack.c | 2 ++ builtin/receive-pack.c | 1 + builtin/send-pack.c | 1 + 3 files changed, 4 insertions(+) (limited to 'builtin') diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c index aba4465552..c6888c66ce 100644 --- a/builtin/fetch-pack.c +++ b/builtin/fetch-pack.c @@ -1,6 +1,8 @@ #include "builtin.h" #include "pkt-line.h" #include "fetch-pack.h" +#include "remote.h" +#include "connect.h" static const char fetch_pack_usage[] = "git fetch-pack [--all] [--stdin] [--quiet|-q] [--keep|-k] [--thin] " diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index e3eb5fc058..7434d9b4a2 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -8,6 +8,7 @@ #include "commit.h" #include "object.h" #include "remote.h" +#include "connect.h" #include "transport.h" #include "string-list.h" #include "sha1-array.h" diff --git a/builtin/send-pack.c b/builtin/send-pack.c index 152c4ea092..e86d3b5d67 100644 --- a/builtin/send-pack.c +++ b/builtin/send-pack.c @@ -5,6 +5,7 @@ #include "sideband.h" #include "run-command.h" #include "remote.h" +#include "connect.h" #include "send-pack.h" #include "quote.h" #include "transport.h" -- cgit v1.2.1 From ab22d2eb83c1810043bfa07dd142594580e093be Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 8 Jul 2013 14:50:27 -0700 Subject: builtin/push.c: use OPT_BOOL, not OPT_BOOLEAN The command line parser of "git push" for "--tags", "--delete", and "--thin" options still used outdated OPT_BOOLEAN. Because these options do not give escalating levels when given multiple times, they should use OPT_BOOL. Signed-off-by: Junio C Hamano --- builtin/push.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'builtin') diff --git a/builtin/push.c b/builtin/push.c index 2d84d10720..342d792f93 100644 --- a/builtin/push.c +++ b/builtin/push.c @@ -427,15 +427,15 @@ int cmd_push(int argc, const char **argv, const char *prefix) OPT_BIT( 0 , "all", &flags, N_("push all refs"), TRANSPORT_PUSH_ALL), OPT_BIT( 0 , "mirror", &flags, N_("mirror all refs"), (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE)), - OPT_BOOLEAN( 0, "delete", &deleterefs, N_("delete refs")), - OPT_BOOLEAN( 0 , "tags", &tags, N_("push tags (can't be used with --all or --mirror)")), + OPT_BOOL( 0, "delete", &deleterefs, N_("delete refs")), + OPT_BOOL( 0 , "tags", &tags, N_("push tags (can't be used with --all or --mirror)")), OPT_BIT('n' , "dry-run", &flags, N_("dry run"), TRANSPORT_PUSH_DRY_RUN), OPT_BIT( 0, "porcelain", &flags, N_("machine-readable output"), TRANSPORT_PUSH_PORCELAIN), OPT_BIT('f', "force", &flags, N_("force updates"), TRANSPORT_PUSH_FORCE), { OPTION_CALLBACK, 0, "recurse-submodules", &flags, N_("check"), N_("control recursive pushing of submodules"), PARSE_OPT_OPTARG, option_parse_recurse_submodules }, - OPT_BOOLEAN( 0 , "thin", &thin, N_("use thin pack")), + OPT_BOOL( 0 , "thin", &thin, N_("use thin pack")), OPT_STRING( 0 , "receive-pack", &receivepack, "receive-pack", N_("receive pack program")), OPT_STRING( 0 , "exec", &receivepack, "receive-pack", N_("receive pack program")), OPT_BIT('u', "set-upstream", &flags, N_("set upstream for git pull/status"), -- cgit v1.2.1 From 28f5d176110d2ed768a0a49159993c7a02d8cb15 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 8 Jul 2013 15:34:36 -0700 Subject: remote.c: add command line option parser for "--force-with-lease" Update "git push" and "git send-pack" to parse this commnd line option. The intended sematics is: * "--force-with-lease" alone, without specifying the details, will protect _all_ remote refs that are going to be updated by requiring their current value to be the same as some reasonable default, unless otherwise specified; * "--force-with-lease=refname", without specifying the expected value, will protect that refname, if it is going to be updated, by requiring its current value to be the same as some reasonable default. * "--force-with-lease=refname:value" will protect that refname, if it is going to be updated, by requiring its current value to be the same as the specified value; and * "--no-force-with-lease" will cancel all the previous --force-with-lease on the command line. For now, "some reasonable default" is tentatively defined as "the value of the remote-tracking branch we have for the ref of the remote being updated", and it is an error if we do not have such a remote-tracking branch. But this is known to be fragile, its use is not yet recommended, and hopefully we will find more reasonable default as we gain experience with this feature. The manual marks the feature as experimental unless the expected value is specified explicitly for this reason. Because the command line options are parsed _before_ we know which remote we are pushing to, there needs further processing to the parsed data after we instantiate the transport object to: * expand "refname" given by the user to a full refname to be matched with the list of "struct ref" used in match_push_refs() and set_ref_status_for_push(); and * learning the actual local ref that is the remote-tracking branch for the specified remote ref. Further, some processing need to be deferred until we find the set of remote refs and match_push_refs() returns in order to find the ones that need to be checked after explicit ones have been processed for "--force-with-lease" (no specific details). These post-processing will be the topic of the next patch. This option was originally called "cas" (for "compare and swap"), the name which nobody liked because it was too technical. The second attempt called it "lockref" (because it is conceptually like pushing after taking a lock) but the word "lock" was hated because it implied that it may reject push by others, which is not the way this option works. This round calls it "force-with-lease". You assume you took the lease on the ref when you fetched to decide what the rebased history should be, and you can push back only if the lease has not been broken. Signed-off-by: Junio C Hamano --- builtin/push.c | 6 ++++++ builtin/send-pack.c | 17 +++++++++++++++++ 2 files changed, 23 insertions(+) (limited to 'builtin') diff --git a/builtin/push.c b/builtin/push.c index 342d792f93..31a5ba085d 100644 --- a/builtin/push.c +++ b/builtin/push.c @@ -21,6 +21,8 @@ static const char *receivepack; static int verbosity; static int progress = -1; +static struct push_cas_option cas; + static const char **refspec; static int refspec_nr; static int refspec_alloc; @@ -432,6 +434,10 @@ int cmd_push(int argc, const char **argv, const char *prefix) OPT_BIT('n' , "dry-run", &flags, N_("dry run"), TRANSPORT_PUSH_DRY_RUN), OPT_BIT( 0, "porcelain", &flags, N_("machine-readable output"), TRANSPORT_PUSH_PORCELAIN), OPT_BIT('f', "force", &flags, N_("force updates"), TRANSPORT_PUSH_FORCE), + { OPTION_CALLBACK, + 0, CAS_OPT_NAME, &cas, N_("refname>:smart_options) + die("underlying transport does not support --%s option", + CAS_OPT_NAME); + transport->smart_options->cas = &cas; + } + if (verbosity > 0) fprintf(stderr, _("Pushing to %s\n"), transport->url); err = transport_push(transport, refspec_nr, refspec, flags, diff --git a/builtin/send-pack.c b/builtin/send-pack.c index a23b26db17..6027ead5a9 100644 --- a/builtin/send-pack.c +++ b/builtin/send-pack.c @@ -242,6 +242,9 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix) if (match_push_refs(local_refs, &remote_refs, nr_refspecs, refspecs, flags)) return -1; + if (!is_empty_cas(&cas)) + apply_push_cas(&cas, remote, remote_refs); + set_ref_status_for_push(remote_refs, args.send_mirror, args.force_update); -- cgit v1.2.1 From 631b5ef219c41027c144218e25075062b91f9471 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 8 Jul 2013 14:42:40 -0700 Subject: push --force-with-lease: tie it all together This teaches the deepest part of the callchain for "git push" (and "git send-pack") to enforce "the old value of the ref must be this, otherwise fail this push" (aka "compare-and-swap" / "--lockref"). Signed-off-by: Junio C Hamano --- builtin/send-pack.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'builtin') diff --git a/builtin/send-pack.c b/builtin/send-pack.c index 6027ead5a9..41dc51221c 100644 --- a/builtin/send-pack.c +++ b/builtin/send-pack.c @@ -55,6 +55,11 @@ static void print_helper_status(struct ref *ref) msg = "needs force"; break; + case REF_STATUS_REJECT_STALE: + res = "error"; + msg = "stale info"; + break; + case REF_STATUS_REJECT_ALREADY_EXISTS: res = "error"; msg = "already exists"; -- cgit v1.2.1 From 77aa93481d1b12372a70959de58917ff815b3bc6 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 2 Aug 2013 16:06:29 -0700 Subject: send-pack: fix parsing of --force-with-lease option The last argument for parse_push_cas_option() is if it is "unset" (i.e. --no-force-with-lease), and we are parsing the option with an explicit value here, so it has to be 0. Signed-off-by: Junio C Hamano --- builtin/send-pack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'builtin') diff --git a/builtin/send-pack.c b/builtin/send-pack.c index 41dc51221c..4482f16efb 100644 --- a/builtin/send-pack.c +++ b/builtin/send-pack.c @@ -183,7 +183,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix) } if (!prefixcmp(arg, "--" CAS_OPT_NAME "=")) { if (parse_push_cas_option(&cas, - strchr(arg, '=') + 1, 1) < 0) + strchr(arg, '=') + 1, 0) < 0) exit(1); continue; } -- cgit v1.2.1