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 <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
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 <bmwill@google.com>
Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
"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
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
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 <bmwill@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
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 <kannan@cakoose.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
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 <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
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
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
http://stackoverflow.com/questions/13148066/warning-push-default-is-unset-its-implicit-value-is-changing-in-git-2-0
(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 <Matthieu.Moy@imag.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
"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
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 <normalperson@yhbt.net>
Reviewed-by: Torsten Bögershausen <tboegi@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
"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
"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 <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
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 <mac@mcrowe.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
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 <mac@mcrowe.com>
Signed-off-by: Jeff King <peff@peff.net>
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 <dborowitz@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
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 <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This makes the code shorter and more obvious by removing an
unnecessary interim variable.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
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 <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
"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
t5543-atomic-push.sh: 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
Add a command line argument to the git push command to request atomic
pushes.
Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
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"
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 <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
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 <ralf.thielow@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
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 <git@drmicha.warpmail.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
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 <gitster@pobox.com> 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 <gitster@pobox.com>
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 <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
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
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 <gitster@pobox.com>
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 <gitster@pobox.com>
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 <gitster@pobox.com>
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 <Matthieu.Moy@imag.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
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 <coder5000@gmail.com>
Helped-by: Jonathan Nieder <jrnieder@gmail.com>
Helped-by: Matthieu Moy <Matthieu.Moy@imag.fr>
Helped-by: Marc Branchaud <marcnarc@xiplink.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
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
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
- 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 <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
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 <stefanbeller@googlemail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
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 <gitster@pobox.com>
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 <gitster@pobox.com>
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 <gitster@pobox.com>