path: root/builtin/push.c
AgeCommit message (Collapse)Author
2017-06-24Merge branch 'bw/config-h'Junio C Hamano
Fix configuration codepath to pay proper attention to commondir that is used in multi-worktree situation, and isolate config API into its own header file. * bw/config-h: config: don't implicitly use gitdir or commondir config: respect commondir setup: teach discover_git_directory to respect the commondir config: don't include config.h by default config: remove git_config_iter config: create config.h
2017-06-15config: don't include config.h by defaultBrandon Williams
Stop including config.h by default in cache.h. Instead only include config.h in those files which require use of the config system. Signed-off-by: Brandon Williams <> Signed-off-by: Junio C Hamano <>
2017-06-01builtin/push.c: respect 'submodule.recurse' optionStefan Beller
The closest mapping from the boolean 'submodule.recurse' set to "yes" to the variety of submodule push modes is "on-demand", so implement that. Signed-off-by: Stefan Beller <> Signed-off-by: Junio C Hamano <>
2017-04-02push: unmark a local variable as staticBrandon Williams
There isn't any obvious reason for the 'struct string_list push_options' and 'struct string_list_item *item' to be marked as static, so unmark them as being static. Also, clear the push_options string_list to prevent memory leaking. Signed-off-by: Brandon Williams <> Reviewed-by: Jonathan Nieder <> Signed-off-by: Junio C Hamano <>
2017-01-31Merge branch 'bw/push-submodule-only'Junio C Hamano
"git submodule push" learned "--recurse-submodules=only option to push submodules out without pushing the top-level superproject. * bw/push-submodule-only: push: add option to push only submodules submodules: add RECURSE_SUBMODULES_ONLY value transport: reformat flag #defines to be more readable
2016-12-27Merge branch 'jc/push-default-explicit'Junio C Hamano
A lazy "git push" without refspec did not internally use a fully specified refspec to perform 'current', 'simple', or 'upstream' push, causing unnecessary "ambiguous ref" errors. * jc/push-default-explicit: push: test pushing ambiguously named branches push: do not use potentially ambiguous default refspec
2016-12-20push: add option to push only submodulesBrandon Williams
Teach push the --recurse-submodules=only option. This enables push to recursively push all unpushed submodules while leaving the superproject unpushed. This is a desirable feature in a scenario where updates to the superproject are handled automatically by some other means, perhaps a tool like Gerrit code review. In this scenario, a developer could make a change which spans multiple submodules and then push their commits for code review. Upon completion of the code review, their commits can be accepted and applied to their respective submodules while the code review tool can then automatically update the superproject to the most recent SHA1 of each submodule. This would reduce the merge conflicts in the superproject that could occur if multiple people are contributing to the same submodule. Signed-off-by: Brandon Williams <> Signed-off-by: Junio C Hamano <>
2016-10-29push: do not use potentially ambiguous default refspecJunio C Hamano
When the user does the lazy "git push" with no parameters with push.default set to either "upstream", "simple" or "current", we internally generated a refspec that has the current branch name on the source side and used it to push. However, the branch name (say "test") may be an ambiguous refname in the context of the source repository---there may be a tag with the same name, for example. This would trigger an unnecessary error without any fault on the end-user's side. Be explicit and give a full refname as the source side to avoid the ambiguity. The destination side when pushing with the "current" sent only the name of the branch and forcing the receiving end to guess, which is the same issue. Be explicit there as well. Reported-by: Kannan Goundan <> Signed-off-by: Junio C Hamano <>
2016-07-14push: accept push optionsStefan Beller
This implements everything that is required on the client side to make use of push options from the porcelain push command. Signed-off-by: Stefan Beller <> Signed-off-by: Junio C Hamano <>
2016-02-26Merge branch 'mm/push-default-warning'Junio C Hamano
Across the transition at around Git version 2.0, the user used to get a pretty loud warning when running "git push" without setting push.default configuration variable. We no longer warn, given that the transition is over long time ago. * mm/push-default-warning: push: remove "push.default is unset" warning message
2016-02-25push: remove "push.default is unset" warning messageMatthieu Moy
The warning was important before the 2.0 transition, and remained important for a while after, so that new users get push.default explicitly in their configuration and do not experience inconsistent behavior if they ever used an older version of Git. The warning has been there since version 1.8.0 (Oct 2012), hence we can expect the vast majority of current Git users to have been exposed to it, and most of them have already set push.default explicitly. The switch from 'matching' to 'simple' was planned for 2.0 (May 2014), but actually happened only for 2.3 (Feb 2015). Today, the warning is mostly seen by beginners, who have not set their push.default configuration (yet). For many of them, the warning is confusing because it talks about concepts that they have not learned and asks them a choice that they are not able to make yet. See for example (1260 votes for the question, 1824 for the answer as of writing) Remove the warning completely to avoid disturbing beginners. People who still occasionally use an older version of Git will be exposed to the warning through this old version. Eventually, versions of Git without the warning will be deployed enough and tutorials will not need to advise setting push.default anymore. Signed-off-by: Matthieu Moy <> Signed-off-by: Junio C Hamano <>
2016-02-24Merge branch 'ew/force-ipv4'Junio C Hamano
"git fetch" and friends that make network connections can now be told to only use ipv4 (or ipv6). * ew/force-ipv4: connect & http: support -4 and -6 switches for remote operations
2016-02-12connect & http: support -4 and -6 switches for remote operationsEric Wong
Sometimes it is necessary to force IPv4-only or IPv6-only operation on networks where name lookups may return a non-routable address and stall remote operations. The ssh(1) command has an equivalent switches which we may pass when we run them. There may be old ssh(1) implementations out there which do not support these switches; they should report the appropriate error in that case. rsync support is untouched for now since it is deprecated and scheduled to be removed. Signed-off-by: Eric Wong <> Reviewed-by: Torsten Bögershausen <> Signed-off-by: Junio C Hamano <>
2016-01-12Merge branch 'ps/push-delete-option'Junio C Hamano
"branch --delete" has "branch -d" but "push --delete" does not. * ps/push-delete-option: push: add '-d' as shorthand for '--delete' push: add '--delete' flag to synopsis
2015-12-22push: don't mark options of recurse-submodules for translationRalf Thielow
Signed-off-by: Ralf Thielow <> Signed-off-by: Junio C Hamano <>
2015-12-16push: add '-d' as shorthand for '--delete'Patrick Steinhardt
"git push" takes "--delete" but does not take a short form "-d", unlike "git branch" which does take both. Bring consistency between them. Signed-off-by: Patrick Steinhardt <> Signed-off-by: Junio C Hamano <>
2015-12-04push: follow the "last one wins" convention for --recurse-submodulesMike Crowe
Use the "last one wins" convention for --recurse-submodules rather than treating conflicting options as an error. Also, fix the declaration of the file-scope recurse_submodules global variable to put it on a separate line. Signed-off-by: Mike Crowe <> Signed-off-by: Junio C Hamano <>
2015-11-20push: add recurseSubmodules config optionMike Crowe
The --recurse-submodules command line parameter has existed for some time but it has no config file equivalent. Following the style of the corresponding parameter for git fetch, let's invent push.recurseSubmodules to provide a default for this parameter. This also requires the addition of --recurse-submodules=no to allow the configuration to be overridden on the command line when required. The most straightforward way to implement this appears to be to make push use code in submodule-config in a similar way to fetch. Signed-off-by: Mike Crowe <> Signed-off-by: Jeff King <>
2015-08-19push: add a config option push.gpgSign for default signed pushesDave Borowitz
Signed-off-by: Dave Borowitz <> Signed-off-by: Junio C Hamano <>
2015-08-19push: support signing pushes iff the server supports itDave Borowitz
Add a new flag --sign=true (or --sign=false), which means the same thing as the original --signed (or --no-signed). Give it a third value --sign=if-asked to tell push and send-pack to send a push certificate if and only if the server advertised a push cert nonce. If not, warn the user that their push may not be as secure as they thought. Signed-off-by: Dave Borowitz <> Signed-off-by: Junio C Hamano <>
2015-03-14push: allow --follow-tags to be set by config push.followTagsDave Olszewski
Signed-off-by: Dave Olszewski <> Helped-by: Jeff King <> Signed-off-by: Junio C Hamano <>
2015-02-17cmd_push: pass "flags" pointer to config callbackJeff King
This will let us manipulate any transport flags which have matching config options (there are none yet, but we will add one in the next patch). We could also just make "flags" a static file-scope global, but the result is a little confusing. We end up passing it along through do_push and push_with_options, each of which further munge it. Having slightly-differing versions of the flags variable available to those functions would probably cause more confusion than it is worth. Let's just keep the original local to cmd_push, and it can continue to pass it through the call-stack. Signed-off-by: Jeff King <> Signed-off-by: Junio C Hamano <>
2015-02-17cmd_push: set "atomic" bit directlyJeff King
This makes the code shorter and more obvious by removing an unnecessary interim variable. Signed-off-by: Jeff King <> Signed-off-by: Junio C Hamano <>
2015-02-16git_push_config: drop cargo-culted wt_status pointerJeff King
The push config callback does not expect any incoming data via the void pointer. And if it did, it would certainly not be a "struct wt_status". This probably got picked up accidentally in b945901 (push: heed user.signingkey for signed pushes, 2014-10-22), which copied the template for the config callback from builtin/commit.c. Signed-off-by: Jeff King <> Signed-off-by: Junio C Hamano <>
2015-02-11Merge branch 'sb/atomic-push'Junio C Hamano
"git push" has been taught a "--atomic" option that makes push to update more than one ref an "all-or-none" affair. * sb/atomic-push: Document receive.advertiseatomic add basic tests for atomic pushes push.c: add an --atomic argument send-pack.c: add --atomic command line argument send-pack: rename ref_update_to_be_sent to check_to_send_update receive-pack.c: negotiate atomic push support receive-pack.c: add execute_commands_atomic function receive-pack.c: move transaction handling in a central place receive-pack.c: move iterating over all commands outside execute_commands receive-pack.c: die instead of error in case of possible future bug receive-pack.c: shorten the execute_commands loop over all commands
2015-01-08push.c: add an --atomic argumentRonnie Sahlberg
Add a command line argument to the git push command to request atomic pushes. Signed-off-by: Ronnie Sahlberg <> Signed-off-by: Stefan Beller <> Signed-off-by: Junio C Hamano <>
2014-12-12Merge branch 'jk/push-simple'Junio C Hamano
Git 2.0 was supposed to make the "simple" mode for the default of "git push", but it didn't. * jk/push-simple: push: truly use "simple" as default, not "upstream"
2014-12-12Merge branch 'rt/push-recurse-submodule-usage-string'Junio C Hamano
* rt/push-recurse-submodule-usage-string: builtin/push.c: fix description of --recurse-submodules option
2014-12-01push: truly use "simple" as default, not "upstream"Jeff King
The plan for the push.default transition had all along been to use the "simple" method rather than "upstream" as a default if the user did not specify their own push.default value. Commit 11037ee (push: switch default from "matching" to "simple", 2013-01-04) tried to implement that by moving PUSH_DEFAULT_UNSPECIFIED in our switch statement to fall-through to the PUSH_DEFAULT_SIMPLE case. When the commit that became 11037ee was originally written, that would have been enough. We would fall through to calling setup_push_upstream() with the "simple" parameter set to 1. However, it was delayed for a while until we were ready to make the transition in Git 2.0. And in the meantime, commit ed2b182 (push: change `simple` to accommodate triangular workflows, 2013-06-19) threw a monkey wrench into the works. That commit drops the "simple" parameter to setup_push_upstream, and instead checks whether the global "push_default" is PUSH_DEFAULT_SIMPLE. This is right when the user has explicitly configured push.default to simple, but wrong when we are a fall-through for the "unspecified" case. We never noticed because our push.default tests do not cover the case of the variable being totally unset; they only check the "simple" behavior itself. Signed-off-by: Jeff King <> Signed-off-by: Junio C Hamano <>
2014-11-18builtin/push.c: fix description of --recurse-submodules optionRalf Thielow
The description of the option for argument "recurse-submodules" is marked for translation even if it expects the untranslated string and it's missing the option "on-demand" which was introduced in eb21c73 (2014-03-29, push: teach --recurse-submodules the on-demand option). Fix this by unmark the string for translation and add the missing option. Signed-off-by: Ralf Thielow <> Signed-off-by: Junio C Hamano <>
2014-10-24push: heed user.signingkey for signed pushesMichael J Gruber
push --signed promises to take user.signingkey as the signing key but fails to read the config. Make it do so. Signed-off-by: Michael J Gruber <> Signed-off-by: Junio C Hamano <>
2014-09-15push: the beginning of "git push --signed"Junio C Hamano
While signed tags and commits assert that the objects thusly signed came from you, who signed these objects, there is not a good way to assert that you wanted to have a particular object at the tip of a particular branch. My signing v2.0.1 tag only means I want to call the version v2.0.1, and it does not mean I want to push it out to my 'master' branch---it is likely that I only want it in 'maint', so the signature on the object alone is insufficient. The only assurance to you that 'maint' points at what I wanted to place there comes from your trust on the hosting site and my authentication with it, which cannot easily audited later. Introduce a mechanism that allows you to sign a "push certificate" (for the lack of better name) every time you push, asserting that what object you are pushing to update which ref that used to point at what other object. Think of it as a cryptographic protection for ref updates, similar to signed tags/commits but working on an orthogonal axis. The basic flow based on this mechanism goes like this: 1. You push out your work with "git push --signed". 2. The sending side learns where the remote refs are as usual, together with what protocol extension the receiving end supports. If the receiving end does not advertise the protocol extension "push-cert", an attempt to "git push --signed" fails. Otherwise, a text file, that looks like the following, is prepared in core: certificate version 0.1 pusher Junio C Hamano <> 1315427886 -0700 7339ca65... 21580ecb... refs/heads/master 3793ac56... 12850bec... refs/heads/next The file begins with a few header lines, which may grow as we gain more experience. The 'pusher' header records the name of the signer (the value of user.signingkey configuration variable, falling back to GIT_COMMITTER_{NAME|EMAIL}) and the time of the certificate generation. After the header, a blank line follows, followed by a copy of the protocol message lines. Each line shows the old and the new object name at the tip of the ref this push tries to update, in the way identical to how the underlying "git push" protocol exchange tells the ref updates to the receiving end (by recording the "old" object name, the push certificate also protects against replaying). It is expected that new command packet types other than the old-new-refname kind will be included in push certificate in the same way as would appear in the plain vanilla command packets in unsigned pushes. The user then is asked to sign this push certificate using GPG, formatted in a way similar to how signed tag objects are signed, and the result is sent to the other side (i.e. receive-pack). In the protocol exchange, this step comes immediately before the sender tells what the result of the push should be, which in turn comes before it sends the pack data. 3. When the receiving end sees a push certificate, the certificate is written out as a blob. The pre-receive hook can learn about the certificate by checking GIT_PUSH_CERT environment variable, which, if present, tells the object name of this blob, and make the decision to allow or reject this push. Additionally, the post-receive hook can also look at the certificate, which may be a good place to log all the received certificates for later audits. Because a push certificate carry the same information as the usual command packets in the protocol exchange, we can omit the latter when a push certificate is in use and reduce the protocol overhead. This however is not included in this patch to make it easier to review (in other words, the series at this step should never be released without the remainder of the series, as it implements an interim protocol that will be incompatible with the final one). As such, the documentation update for the protocol is left out of this step. Signed-off-by: Junio C Hamano <>
2014-06-20refactor skip_prefix to return a booleanJeff King
The skip_prefix() function returns a pointer to the content past the prefix, or NULL if the prefix was not found. While this is nice and simple, in practice it makes it hard to use for two reasons: 1. When you want to conditionally skip or keep the string as-is, you have to introduce a temporary variable. For example: tmp = skip_prefix(buf, "foo"); if (tmp) buf = tmp; 2. It is verbose to check the outcome in a conditional, as you need extra parentheses to silence compiler warnings. For example: if ((cp = skip_prefix(buf, "foo")) /* do something with cp */ Both of these make it harder to use for long if-chains, and we tend to use starts_with() instead. However, the first line of "do something" is often to then skip forward in buf past the prefix, either using a magic constant or with an extra strlen(3) (which is generally computed at compile time, but means we are repeating ourselves). This patch refactors skip_prefix() to return a simple boolean, and to provide the pointer value as an out-parameter. If the prefix is not found, the out-parameter is untouched. This lets you write: if (skip_prefix(arg, "foo ", &arg)) do_foo(arg); else if (skip_prefix(arg, "bar ", &arg)) do_bar(arg); Signed-off-by: Jeff King <> Signed-off-by: Junio C Hamano <>
2014-03-07Merge branch 'cc/starts-n-ends-with-endgame'Junio C Hamano
prefixcmp/suffixcmp are gone.
2014-03-07Merge branch 'gj/push-more-verbose-advice'Junio C Hamano
2014-03-07Merge branch 'jc/push-2.0-default-to-simple'Junio C Hamano
Finally update the "git push" default behaviour to "simple".
2013-12-27Merge branch 'jc/push-refmap'Junio C Hamano
Make "git push origin master" update the same ref that would be updated by our 'master' when "git push origin" (no refspecs) is run while the 'master' branch is checked out, which makes "git push" more symmetric to "git fetch" and more usable for the triangular workflow. * jc/push-refmap: push: also use "upstream" mapping when pushing a single ref push: use remote.$name.push as a refmap builtin/push.c: use strbuf instead of manual allocation
2013-12-04push: also use "upstream" mapping when pushing a single refJunio C Hamano
When the user is using the 'upstream' mode, these commands: $ git push $ git push origin would find the 'upstream' branch for the current branch, and then push the current branch to update it. However, pushing a single branch explicitly, i.e. $ git push origin $(git symbolic-ref --short HEAD) would not go through the same ref mapping process, and ends up updating the branch at 'origin' of the same name, which may not necessarily be the upstream of the branch being pushed. In the spirit similar to the previous one, map a colon-less refspec using the upstream mapping logic. Signed-off-by: Junio C Hamano <>
2013-12-04push: use remote.$name.push as a refmapJunio C Hamano
Since f2690487 (fetch: opportunistically update tracking refs, 2013-05-11), we stopped taking a non-storing refspec given on the command line of "git fetch" literally, and instead started mapping it via remote.$name.fetch refspecs. This allows $ git fetch origin master from the 'origin' repository, which is configured with [remote "origin"] fetch = +refs/heads/*:refs/remotes/origin/* to update refs/remotes/origin/master with the result, as if the command line were $ git fetch origin +master:refs/remotes/origin/master to reduce surprises and improve usability. Before that change, a refspec on the command line without a colon was only to fetch the history and leave the result in FETCH_HEAD, without updating the remote-tracking branches. When you are simulating a fetch from you by your mothership with a push by you into your mothership, instead of having: [remote "satellite"] fetch = +refs/heads/*:refs/remotes/satellite/* on the mothership repository and running: mothership$ git fetch satellite you would have: [remote "mothership"] push = +refs/heads/*:refs/remotes/satellite/* on your satellite machine, and run: satellite$ git push mothership Because we so far did not make the corresponding change to the push side, this command: satellite$ git push mothership master does _not_ allow you on the satellite to only push 'master' out but still to the usual destination (i.e. refs/remotes/satellite/master). Implement the logic to map an unqualified refspec given on the command line via the remote.$name.push refspec. This will bring a bit more symmetry between "fetch" and "push". Signed-off-by: Junio C Hamano <>
2013-12-03builtin/push.c: use strbuf instead of manual allocationJunio C Hamano
The command line arguments given to "git push" are massaged into a list of refspecs in set_refspecs() function. This was implemented using xmalloc, strcpy and friends, but it is much easier to read if done using strbuf. Signed-off-by: Junio C Hamano <>
2013-11-13push: switch default from "matching" to "simple"Junio C Hamano
We promised to change the behaviour of lazy "git push [there]" that does not say what to push on the command line from "matching" to "simple" in Git 2.0. This finally flips that bit. Helped-by: Matthieu Moy <> Signed-off-by: Junio C Hamano <>
2013-11-13push: enhance unspecified push default warningGreg Jacobson
When the unset push.default warning message is displayed this may be the first time many users encounter push.default. Explain in the warning message in a compact manner what push.default is and what the change means to the end-user to help the users decide. Signed-off-by: Greg Jacobson <> Helped-by: Jonathan Nieder <> Helped-by: Matthieu Moy <> Helped-by: Marc Branchaud <> Signed-off-by: Junio C Hamano <>
2013-09-11Merge branch 'nd/push-no-thin'Junio C Hamano
"git push --no-thin" was a no-op by mistake. * nd/push-no-thin: push: respect --no-thin
2013-09-09Merge branch 'jc/push-cas'Junio C Hamano
Allow a safer "rewind of the remote tip" push than blind "--force", by requiring that the overwritten remote ref to be unchanged since the new history to replace it was prepared. The machinery is more or less ready. The "--force" option is again the big red button to override any safety, thanks to J6t's sanity (the original round allowed --lockref to defeat --force). The logic to choose the default implemented here is fragile (e.g. "git fetch" after seeing a failure will update the remote-tracking branch and will make the next "push" pass, defeating the safety pretty easily). It is suitable only for the simplest workflows, and it may hurt users more than it helps them. * jc/push-cas: push: teach --force-with-lease to smart-http transport send-pack: fix parsing of --force-with-lease option t5540/5541: smart-http does not support "--force-with-lease" t5533: test "push --force-with-lease" push --force-with-lease: tie it all together push --force-with-lease: implement logic to populate old_sha1_expect[] remote.c: add command line option parser for "--force-with-lease" builtin/push.c: use OPT_BOOL, not OPT_BOOLEAN cache.h: move remote/connect API out of it
2013-09-04Merge branch 'sb/parseopt-boolean-removal'Junio C Hamano
Convert most uses of OPT_BOOLEAN/OPTION_BOOLEAN that can use OPT_BOOL/OPTION_BOOLEAN which have much saner semantics, and turn remaining ones into OPT_SET_INT, OPT_COUNTUP, etc. as necessary. * sb/parseopt-boolean-removal: revert: use the OPT_CMDMODE for parsing, reducing code checkout-index: fix negations of even numbers of -n config parsing options: allow one flag multiple times hash-object: replace stdin parsing OPT_BOOLEAN by OPT_COUNTUP branch, commit, name-rev: ease up boolean conditions checkout: remove superfluous local variable log, format-patch: parsing uses OPT__QUIET Replace deprecated OPT_BOOLEAN by OPT_BOOL Remove deprecated OPTION_BOOLEAN for parsing arguments
2013-08-13push: respect --no-thinNguyễn Thái Ngọc Duy
- From the beginning of push.c in 755225d, 2006-04-29, "thin" option was enabled by default but could be turned off with --no-thin. - Then Shawn changed the default to 0 in favor of saving server resources in a4503a1, 2007-09-09. --no-thin worked great. - One day later, in 9b28851 Daniel extracted some code from push.c to create transport.c. He (probably accidentally) flipped the default value from 0 to 1 in transport_get(). From then on --no-thin is effectively no-op because git-push still expects the default value to be false and only calls transport_set_option() when "thin" variable in push.c is true (which is unnecessary). Correct the code to respect --no-thin by calling transport_set_option() in both cases. receive-pack learns about --reject-thin-pack-for-testing option, which only is for testing purposes, hence no document update. Signed-off-by: Nguyễn Thái Ngọc Duy <> Signed-off-by: Junio C Hamano <>
2013-08-05Replace deprecated OPT_BOOLEAN by OPT_BOOLStefan Beller
This task emerged from b04ba2bb (parse-options: deprecate OPT_BOOLEAN, 2011-09-27). All occurrences of the respective variables have been reviewed and none of them relied on the counting up mechanism, but all of them were using the variable as a true boolean. This patch does not change semantics of any command intentionally. Signed-off-by: Stefan Beller <> Signed-off-by: Junio C Hamano <>
2013-07-29many small typofixesOndřej Bílka
Signed-off-by: Ondřej Bílka <> Reviewed-by: Marc Branchaud <> Signed-off-by: Junio C Hamano <>
2013-07-23push --force-with-lease: implement logic to populate old_sha1_expect[]Junio C Hamano
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 <>
2013-07-23remote.c: add command line option parser for "--force-with-lease"Junio C Hamano
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 <>