Commit graph

176 commits

Author SHA1 Message Date
Junio C Hamano 4a2e91db65 Merge branch 'hv/receive-denycurrent-everywhere'
"git push" should stop from updating a branch that is checked out
when receive.denyCurrentBranch configuration is set, but it failed
to pay attention to checkouts in secondary worktrees.  This has
been corrected.

* hv/receive-denycurrent-everywhere:
  t2402: test worktree path when called in .git directory
  receive.denyCurrentBranch: respect all worktrees
  t5509: use a bare repository for test push target
  get_main_worktree(): allow it to be called in the Git directory
2020-03-05 10:43:03 -08:00
Hariom Verma 4ef346482d receive.denyCurrentBranch: respect all worktrees
The receive.denyCurrentBranch config option controls what happens if
you push to a branch that is checked out into a non-bare repository.
By default, it rejects it. It can be disabled via `ignore` or `warn`.
Another yet trickier option is `updateInstead`.

However, this setting was forgotten when the git worktree command was
introduced: only the main worktree's current branch is respected.

With this change, all worktrees are respected.

That change also leads to revealing another bug,
i.e. `receive.denyCurrentBranch = true` was ignored when pushing into a
non-bare repository's unborn current branch using ref namespaces. As
`is_ref_checked_out()` returns 0 which means `receive-pack` does not get
into conditional statement to switch `deny_current_branch` accordingly
(ignore, warn, refuse, unconfigured, updateInstead).

receive.denyCurrentBranch uses the function `refs_resolve_ref_unsafe()`
(called via `resolve_refdup()`) to resolve the symbolic ref HEAD, but
that function fails when HEAD does not point at a valid commit.
As we replace the call to `refs_resolve_ref_unsafe()` with
`find_shared_symref()`, which has no problem finding the worktree for a
given branch even if it is unborn yet, this bug is fixed at the same
time: receive.denyCurrentBranch now also handles worktrees with unborn
branches as intended even while using ref namespaces.

Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Hariom Verma <hariom18599@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-02-24 11:14:43 -08:00
Jonathan Nieder 8a1b0978ab test: request GIT_TEST_PROTOCOL_VERSION=0 when appropriate
Since 8cbeba0632 (tests: define GIT_TEST_PROTOCOL_VERSION,
2019-02-25), it has been possible to run tests with a newer protocol
version by setting the GIT_TEST_PROTOCOL_VERSION envvar to a version
number.  Tests that assume protocol v0 handle this by explicitly
setting

	GIT_TEST_PROTOCOL_VERSION=

or similar constructs like 'test -z "$GIT_TEST_PROTOCOL_VERSION" ||
return 0' to declare that they only handle the default (v0) protocol.

The emphasis there is a bit off: it would be clearer to specify
GIT_TEST_PROTOCOL_VERSION=0 to inform the reader that these tests are
specifically testing and relying on details of protocol v0.  Do so.

This way, a reader does not need to know what the default protocol
version is, and the tests can continue to work when the default
protocol version used by Git advances past v0.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-01-15 14:03:55 -08:00
Junio C Hamano 57a6b93236 Merge branch 'jk/fetch-reachability-error-fix'
Code clean-up and a fix for "git fetch" by an explicit object name
(as opposed to fetching refs by name).

* jk/fetch-reachability-error-fix:
  fetch: do not consider peeled tags as advertised tips
  remote.c: make singular free_ref() public
  fetch: use free_refs()
  pkt-line: prepare buffer before handling ERR packets
  upload-pack: send ERR packet for non-tip objects
  t5530: check protocol response for "not our ref"
  t5516: drop ok=sigpipe from unreachable-want tests
2019-04-25 16:41:23 +09:00
Junio C Hamano 39e4773daa Merge branch 'js/spell-out-options-in-tests'
The tests have been updated not to rely on the abbreviated option
names the parse-options API offers, to protect us from an
abbreviated form of an option that used to be unique within the
command getting non-unique when a new option that share the same
prefix is added.

* js/spell-out-options-in-tests:
  tests: disallow the use of abbreviated options (by default)
  tests (pack-objects): use the full, unabbreviated `--revs` option
  tests (status): spell out the `--find-renames` option in full
  tests (push): do not abbreviate the `--follow-tags` option
  t5531: avoid using an abbreviated option
  t7810: do not abbreviate `--no-exclude-standard` nor `--invert-match`
  tests (rebase): spell out the `--force-rebase` option
  tests (rebase): spell out the `--keep-empty` option
2019-04-22 11:14:47 +09:00
Jeff King 34066f0661 fetch: do not consider peeled tags as advertised tips
Our filter_refs() function accidentally considers the target of a peeled
tag to be advertised by the server, even though upload-pack on the
server side does not consider it so. This can result in the client
making a bogus fetch to the server, which will end with the server
complaining "not our ref". Whereas the correct behavior is for the
client to notice that the server will not allow the request and error
out immediately.

So as bugs go, this is not very serious (the outcome is the same either
way -- the fetch fails). But it's worth making the logic here correct
and consistent with other related cases (e.g., fetching an oid that the
server did not mention at all).

The crux of the issue comes from fdb69d33c4 (fetch-pack: always allow
fetching of literal SHA1s, 2017-05-15). After that, the strategy of
filter_refs() is basically:

  - for each advertised ref, try to match it with a "sought" ref
    provided by the user. Skip any malformed refs (which includes
    peeled values like "refs/tags/foo^{}"), and place any unmatched
    items onto the unmatched list.

  - if there are unmatched sought refs, then put all of the advertised
    tips into an oidset, including the unmatched ones.

  - for each sought ref, see if it's in the oidset, in which case it's
    legal for us to ask the server for it

The problem is in the second step. Our list of unmatched refs includes
the peeled refs, even though upload-pack does not allow them to be
directly fetched. So the simplest fix would be to exclude them during
that step.

However, we can observe that the unmatched list isn't used for anything
else, and is freed at the end. We can just free those malformed refs
immediately. That saves us having to check each ref a second time to see
if it's malformed.

Note that this code only kicks in when "strict" is in effect. I.e., if
we are using the v0 protocol and uploadpack.allowReachableSHA1InWant is
not in effect. With v2, all oids are allowed, and we do not bother
creating or consulting the oidset at all. To future-proof our test
against the upcoming GIT_TEST_PROTOCOL_VERSION flag, we'll manually mark
it as a v0-only test.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-04-15 14:00:52 +09:00
Jeff King 533ddba47e pkt-line: prepare buffer before handling ERR packets
Since 2d103c31c2 (pack-protocol.txt: accept error packets in any
context, 2018-12-29), the pktline code will detect an ERR packet and die
automatically, saving the caller from dealing with it. But we do so too
early in the function, before we have terminated the buffer with a NUL.

As a result, passing the ERR message to die() may result in us printing
random cruft from a previous packet. This doesn't trigger memory tools
like ASan because we reuse the same buffer over and over (so the
contents are valid and initialized; they're just stale).

We can see demonstrate this by tightening the regex we use to match the
error message in t5516; without this patch, git-fetch will accidentally
print the capabilities from the (much longer) initial packet we
received.

By moving the ERR code later in the function we get a few other
benefits, too:

  - we'll now chomp any newline sent by the other side (which is what we
    want, since die() will add its own newline)

  - we'll now mention the ERR packet with GIT_TRACE_PACKET

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-04-15 14:00:51 +09:00
Jeff King 014ade7484 upload-pack: send ERR packet for non-tip objects
Commit bdb31eada7 (upload-pack: report "not our ref" to client,
2017-02-23) catches the case where a client asks for an object we don't
have, and issues a message that the client can show to the user (in
addition to dying and writing to stderr).

There's a similar case (with the same message) when the client asks for
an object which we _do_ have, but which isn't a ref tip (or isn't
reachable, when uploadpack.allowReachableSHA1InWant is true). Let's give
that one the same treatment, for the same reason (namely that it's more
informative to the client than just hanging up, since they won't see our
stderr over some protocols).

There are two tests here. We cover it most directly in t5530 by invoking
upload-pack, which matches the existing "not our ref" test.

But a more end-to-end check is that "git fetch" actually shows the
message to the client. We're already checking in t5516 that this case
fails, so we can just check stderr there, too. Note that even after we
started ignoring SIGPIPE in 8bf4becf0c, this could in theory still be
racy as described in that commit (because we die() on write failures
before pumping the connection for any ERR packets).

In practice this should be OK for this case. The server will not
actually check reachability until it has received our whole group of
"want" lines. And since we have no objects in the repository, we won't
send any "have" lines, meaning we're always waiting to read the server
response.

Note also that this case cannot happen in the v2 protocol, since it
allows any available object to be requested. However, we don't have to
take any steps to protect against the upcoming GIT_TEST_PROTOCOL_VERSION
in our tests:

  - the tests in t5516 would already need to be skipped under v2, and
    that is covered by ab0c5f5096 (tests: always test fetch of
    unreachable with v0, 2019-02-25)

  - the tests in t5530 invoke upload-pack directly, which will continue
    to default to v0. Eventually we may have a test setting which uses
    v2 even for bare upload-pack calls, but we can't override it here
    until we know what the setting looks like.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-04-15 14:00:51 +09:00
Jeff King 98024d1cb6 t5516: drop ok=sigpipe from unreachable-want tests
We annotated our test_must_fail calls in 8bf4becf0c (add "ok=sigpipe" to
test_must_fail and use it to fix flaky tests, 2015-11-27) because the
abrupt hangup of the server meant that we'd sometimes fail on read() and
sometimes get SIGPIPE on write().

But since 143588949c (fetch: ignore SIGPIPE during network operation,
2019-03-03), we make sure that we end up with a real die(), and our
tests no longer need to work around the race.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-04-15 14:00:51 +09:00
Johannes Schindelin f6188dccb7 tests (push): do not abbreviate the --follow-tags option
We really want to spell out the option in the full form, to avoid any
ambiguity that might be introduced by future patches.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-04-02 09:55:00 +09:00
Jonathan Tan ab0c5f5096 tests: always test fetch of unreachable with v0
Some tests check that fetching an unreachable object fails, but protocol
v2 allows such fetches. Unset GIT_TEST_PROTOCOL_VERSION so that these
tests are always run using protocol v0.

Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-03-07 10:02:42 +09:00
SZEDER Gábor 165293af3c tests: send "bug in the test script" errors to the script's stderr
Some of the functions in our test library check that they were invoked
properly with conditions like this:

  test "$#" = 2 ||
  error "bug in the test script: not 2 parameters to test-expect-success"

If this particular condition is triggered, then 'error' will abort the
whole test script with a bold red error message [1] right away.

However, under certain circumstances the test script will be aborted
completely silently, namely if:

  - a similar condition in a test helper function like
    'test_line_count' is triggered,
  - which is invoked from the test script's "main" shell [2],
  - and the test script is run manually (i.e. './t1234-foo.sh' as
    opposed to 'make t1234-foo.sh' or 'make test') [3]
  - and without the '--verbose' option,

because the error message is printed from within 'test_eval_', where
standard output is redirected either to /dev/null or to a log file.
The only indication that something is wrong is that not all tests in
the script are executed and at the end of the test script's output
there is no "# passed all N tests" message, which are subtle and can
easily go unnoticed, as I had to experience myself.

Send these "bug in the test script" error messages directly to the
test scripts standard error and thus to the terminal, so those bugs
will be much harder to overlook.  Instead of updating all ~20 such
'error' calls with a redirection, let's add a BUG() function to
'test-lib.sh', wrapping an 'error' call with the proper redirection
and also including the common prefix of those error messages, and
convert all those call sites [4] to use this new BUG() function
instead.

[1] That particular error message from 'test_expect_success' is
    printed in color only when running with or without '--verbose';
    with '--tee' or '--verbose-log' the error is printed without
    color, but it is printed to the terminal nonetheless.

[2] If such a condition is triggered in a subshell of a test, then
    'error' won't be able to abort the whole test script, but only the
    subshell, which in turn causes the test to fail in the usual way,
    indicating loudly and clearly that something is wrong.

[3] Well, 'error' aborts the test script the same way when run
    manually or by 'make' or 'prove', but both 'make' and 'prove' pay
    attention to the test script's exit status, and even a silently
    aborted test script would then trigger those tools' usual
    noticable error messages.

[4] Strictly speaking, not all those 'error' calls need that
    redirection to send their output to the terminal, see e.g.
    'test_expect_success' in the opening example, but I think it's
    better to be consistent.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-11-20 12:16:35 +09:00
Junio C Hamano 4c7f544022 Merge branch 'jc/receive-deny-current-branch-fix'
The receive.denyCurrentBranch=updateInstead codepath kicked in even
when the push should have been rejected due to other reasons, such
as it does not fast-forward or the update-hook rejects it, which
has been corrected.

* jc/receive-deny-current-branch-fix:
  receive: denyCurrentBranch=updateinstead should not blindly update
2018-10-30 15:43:46 +09:00
Junio C Hamano b072a25fad receive: denyCurrentBranch=updateinstead should not blindly update
The handling of receive.denyCurrentBranch=updateInstead was added to
a switch statement that handles other values of the variable, but
all the other case arms only checked a condition to reject the
attempted push, or let later logic in the same function to still
intervene, so that a push that does not fast-forward (which is
checked after the switch statement in question) is still rejected.

But the handling of updateInstead incorrectly took immediate effect,
without giving other checks a chance to intervene.

Instead of calling update_worktree() that causes the side effect
immediately, just note the fact that we will need to call the
function later, and first give other checks a chance to reject the
request.  After the update-hook gets a chance to reject the push
(which happens as the last step in a series of checks), call
update_worktree() when we earlier detected the need to.

Reported-by: Rajesh Madamanchi
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-10-19 15:13:32 +09:00
Junio C Hamano d39cab3989 Merge branch 'ab/fetch-tags-noclobber'
The rules used by "git push" and "git fetch" to determine if a ref
can or cannot be updated were inconsistent; specifically, fetching
to update existing tags were allowed even though tags are supposed
to be unmoving anchoring points.  "git fetch" was taught to forbid
updates to existing tags without the "--force" option.

* ab/fetch-tags-noclobber:
  fetch: stop clobbering existing tags without --force
  fetch: document local ref updates with/without --force
  push doc: correct lies about how push refspecs work
  push doc: move mention of "tag <tag>" later in the prose
  push doc: remove confusing mention of remote merger
  fetch tests: add a test for clobbering tag behavior
  push tests: use spaces in interpolated string
  push tests: make use of unused $1 in test description
  fetch: change "branch" to "reference" in --force -h output
2018-09-17 13:54:00 -07:00
Ævar Arnfjörð Bjarmason 0bc8d71b99 fetch: stop clobbering existing tags without --force
Change "fetch" to treat "+" in refspecs (aka --force) to mean we
should clobber a local tag of the same name.

This changes the long-standing behavior of "fetch" added in
853a3697dc ("[PATCH] Multi-head fetch.", 2005-08-20). Before this
change, all tag fetches effectively had --force enabled. See the
git-fetch-script code in fast_forward_local() with the comment:

    > Tags need not be pointing at commits so there is no way to
    > guarantee "fast-forward" anyway.

That commit and the rest of the history of "fetch" shows that the
"+" (--force) part of refpecs was only conceived for branch updates,
while tags have accepted any changes from upstream unconditionally and
clobbered the local tag object. Changing this behavior has been
discussed as early as 2011[1].

The current behavior doesn't make sense to me, it easily results in
local tags accidentally being clobbered. We could namespace our tags
per-remote and not locally populate refs/tags/*, but as with my
97716d217c ("fetch: add a --prune-tags option and fetch.pruneTags
config", 2018-02-09) it's easier to work around the current
implementation than to fix the root cause.

So this change implements suggestion #1 from Jeff's 2011 E-Mail[1],
"fetch" now only clobbers the tag if either "+" is provided as part of
the refspec, or if "--force" is provided on the command-line.

This also makes it nicely symmetrical with how "tag" itself works when
creating tags. I.e. we refuse to clobber any existing tags unless
"--force" is supplied. Now we can refuse all such clobbering, whether
it would happen by clobbering a local tag with "tag", or by fetching
it from the remote with "fetch".

Ref updates outside refs/{tags,heads/* are still still not symmetrical
with how "git push" works, as discussed in the recently changed
pull-fetch-param.txt documentation. This change brings the two
divergent behaviors more into line with one another. I don't think
there's any reason "fetch" couldn't fully converge with the behavior
used by "push", but that's a topic for another change.

One of the tests added in 31b808a032 ("clone --single: limit the fetch
refspec to fetched branch", 2012-09-20) is being changed to use
--force where a clone would clobber a tag. This changes nothing about
the existing behavior of the test.

1. https://public-inbox.org/git/20111123221658.GA22313@sigill.intra.peff.net/

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-31 14:04:06 -07:00
Ævar Arnfjörð Bjarmason 6b0b0677f6 fetch tests: add a test for clobbering tag behavior
The test suite only incidentally (and unintentionally) tested for the
current behavior of eager tag clobbering on "fetch". This is a
followup to 380efb65df ("push tests: assert re-pushing annotated
tags", 2018-07-31) which tests for it explicitly.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-31 14:04:06 -07:00
Ævar Arnfjörð Bjarmason 253b3d4f57 push tests: use spaces in interpolated string
The quoted -m'msg' option would mean the same as -mmsg when passed
through the test_force_push_tag helper. Let's instead use a string
with spaces in it, to have a working example in case we need to pass
other whitespace-delimited arguments to git-tag.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-31 14:04:06 -07:00
Ævar Arnfjörð Bjarmason f08fb8dfea push tests: make use of unused $1 in test description
Fix up a logic error in 380efb65df ("push tests: assert re-pushing
annotated tags", 2018-07-31), where the $tag_type_description variable
was assigned to but never used, unlike in the subsequently added
companion test for fetches in 2d216a7ef6 ("fetch tests: add a test for
clobbering tag behavior", 2018-04-29).

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-31 14:04:05 -07:00
Junio C Hamano 42a6274b62 Merge branch 'ab/fetch-tags-noclobber'
Test and doc clean-ups.

* ab/fetch-tags-noclobber:
  pull doc: fix a long-standing grammar error
  fetch tests: correct a comment "remove it" -> "remove them"
  push tests: assert re-pushing annotated tags
  push tests: add more testing for forced tag pushing
  push tests: fix logic error in "push" test assertion
  push tests: remove redundant 'git push' invocation
  fetch tests: change "Tag" test tag to "testTag"
2018-08-20 11:33:52 -07:00
Ævar Arnfjörð Bjarmason 380efb65df push tests: assert re-pushing annotated tags
Change the test that asserts that lightweight tags can only be
clobbered by a force-push to check do the same tests for annotated
tags.

There used to be less exhaustive tests for this with the code added in
40eff17999 ("push: require force for annotated tags", 2012-11-29), but
Junio removed them in 256b9d70a4 ("push: fix "refs/tags/ hierarchy
cannot be updated without --force"", 2013-01-16) while fixing some of
the behavior around tag pushing.

That change left us without any coverage asserting that pushing and
clobbering annotated tags worked as intended.  There was no reason to
suspect that the receive machinery wouldn't behave the same way with
annotated tags, but now we know for sure.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-07-31 09:25:25 -07:00
Ævar Arnfjörð Bjarmason 941a7baa4d push tests: add more testing for forced tag pushing
Improve the tests added in dbfeddb12e ("push: require force for refs
under refs/tags/", 2012-11-29) to assert that the same behavior
applies various other combinations of command-line option and
refspecs.

Supplying either "+" in refspec or "--force" is sufficient to clobber
the reference. With --no-force we still pay attention to "+" in the
refspec, and vice-versa with clobbering kicking in if there's no "+"
in the refspec but "+" is given.

This is consistent with how refspecs work for branches, where either
"+" or "--force" will enable clobbering, with neither taking priority
over the other.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-07-31 09:25:25 -07:00
Ævar Arnfjörð Bjarmason 25f74f5234 push tests: fix logic error in "push" test assertion
Fix a logic error that's been here since this test was added in
dbfeddb12e ("push: require force for refs under refs/tags/",
2012-11-29).

The intent of this test is to force-create a new tag pointing to
HEAD~, and then assert that pushing it doesn't work without --force.

Instead, the code was not creating a new tag at all, and then failing
to push the previous tag for the unrelated reason of providing a
refspec that doesn't make any sense.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-07-31 09:25:25 -07:00
Ævar Arnfjörð Bjarmason 76bcde5956 push tests: remove redundant 'git push' invocation
Remove an invocation of 'git push' that's exactly the same as the one
on the preceding line. This was seemingly added by mistake in
dbfeddb12e ("push: require force for refs under refs/tags/",
2012-11-29) and doesn't affect the result of the test, the second
"push" was a no-op as there was nothing new to push.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-07-31 09:25:25 -07:00
Ævar Arnfjörð Bjarmason 54e934e66d fetch tests: change "Tag" test tag to "testTag"
Calling the test tag "Tag" will make for confusing reading later in
this series when making use of the "git push tag <name>"
feature. Let's call the tag testTag instead.

Changes code initially added in dbfeddb12e ("push: require force for
refs under refs/tags/", 2012-11-29).

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-07-31 09:25:25 -07:00
Eric Sunshine 51b85471af t5000-t5999: fix broken &&-chains
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-07-16 14:38:47 -07:00
Junio C Hamano 026b8ef9f7 Merge branch 'bw/ref-prefix-for-configured-refspec'
* bw/ref-prefix-for-configured-refspec:
  fetch: do not pass ref-prefixes for fetch by exact SHA1
2018-06-01 15:15:35 +09:00
Jonathan Nieder 6c301adb0a fetch: do not pass ref-prefixes for fetch by exact SHA1
When v2.18.0-rc0~10^2~1 (refspec: consolidate ref-prefix generation
logic, 2018-05-16) factored out the ref-prefix generation code for
reuse, it left out the 'if (!item->exact_sha1)' test in the original
ref-prefix generation code. As a result, fetches by SHA-1 generate
ref-prefixes as though the SHA-1 being fetched were an abbreviated ref
name:

 $ GIT_TRACE_PACKET=1 bin-wrappers/git -c protocol.version=2 \
	fetch origin 12039e008f
[...]
 packet:        fetch> ref-prefix 12039e008f
 packet:        fetch> ref-prefix refs/12039e008f9a4e3394f3f94f8ea897785cb09448
 packet:        fetch> ref-prefix refs/tags/12039e008f9a4e3394f3f94f8ea897785cb09448
 packet:        fetch> ref-prefix refs/heads/12039e008f9a4e3394f3f94f8ea897785cb09448
 packet:        fetch> ref-prefix refs/remotes/12039e008f9a4e3394f3f94f8ea897785cb09448
 packet:        fetch> ref-prefix refs/remotes/12039e008f9a4e3394f3f94f8ea897785cb09448/HEAD
 packet:        fetch> 0000

If there is another ref name on the command line or the object being
fetched is already available locally, then that's mostly harmless.
But otherwise, we error out with

 fatal: no matching remote head

since the server did not send any refs we are interested in.  Filter
out the exact_sha1 refspecs to avoid this.

This patch adds a test to check this behavior that notices another
behavior difference between protocol v0 and v2 in the process.  Add a
NEEDSWORK comment to clear it up.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-06-01 15:15:22 +09:00
Junio C Hamano 9472b13201 Merge branch 'bc/hash-independent-tests'
Many tests hardcode the raw object names, which would change once
we migrate away from SHA-1.  While some of them must test against
exact object names, most of them do not have to use hardcoded
constants in the test.  The latter kind of tests have been updated
to test the moral equivalent of the original without hardcoding the
actual object names.

* bc/hash-independent-tests: (28 commits)
  t5300: abstract away SHA-1-specific constants
  t4208: abstract away SHA-1-specific constants
  t4045: abstract away SHA-1-specific constants
  t4042: abstract away SHA-1-specific constants
  t4205: sort log output in a hash-independent way
  t/lib-diff-alternative: abstract away SHA-1-specific constants
  t4030: abstract away SHA-1-specific constants
  t4029: abstract away SHA-1-specific constants
  t4029: fix test indentation
  t4022: abstract away SHA-1-specific constants
  t4020: abstract away SHA-1-specific constants
  t4014: abstract away SHA-1-specific constants
  t4008: abstract away SHA-1-specific constants
  t4007: abstract away SHA-1-specific constants
  t3905: abstract away SHA-1-specific constants
  t3702: abstract away SHA-1-specific constants
  t3103: abstract away SHA-1-specific constants
  t2203: abstract away SHA-1-specific constants
  t: skip pack tests if not using SHA-1
  t4044: skip test if not using SHA-1
  ...
2018-05-30 21:51:28 +09:00
Junio C Hamano c8311980f9 Merge branch 'sg/t5516-fixes'
Test fixes.

* sg/t5516-fixes:
  t5516-fetch-push: fix broken &&-chain
  t5516-fetch-push: fix 'push with dry-run' test
2018-05-23 14:38:12 +09:00
brian m. carlson 8125a58b91 t: switch $_z40 to $ZERO_OID
Switch all uses of $_z40 to $ZERO_OID so that they work correctly with
larger hashes.  This commit was created by using the following sed
command to modify all files in the t directory except t/test-lib.sh:

  sed -i 's/\$_z40/$ZERO_OID/g'

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-05-14 11:02:00 +09:00
SZEDER Gábor f6b82970aa t5516-fetch-push: fix broken &&-chain
b2dc968e60 (t5516: refactor oddball tests, 2008-11-07) accidentaly
broke the &&-chain in the test 'push does not update local refs on
failure', but since it was in a subshell, chain-lint couldn't notice
it.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-05-11 12:32:53 +09:00
SZEDER Gábor cfb482b6c3 t5516-fetch-push: fix 'push with dry-run' test
In a while-at-it cleanup replacing a 'cd dir && <...> && cd ..' with a
subshell, commit 28391a80a9 (receive-pack: allow deletion of corrupt
refs, 2007-11-29) also moved the assignment of the $old_commit
variable to that subshell.  This variable, however, is used outside of
that subshell as a parameter of check_push_result(), to check that a
ref still points to the commit where it is supposed to.  With the
variable remaining unset outside the subshell check_push_result()
doesn't perform that check at all.

Use 'git -C <dir> cmd...', so we don't need to change directory, and
thus don't need the subshell either when setting $old_commit.

Furthermore, change check_push_result() to require at least three
parameters (the repo, the oid, and at least one ref), so it will catch
similar issues earlier should they ever arise.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-05-11 12:32:51 +09:00
Nguyễn Thái Ngọc Duy 0e496492d2 t/helper: merge test-chmtime into test-tool
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-03-27 08:45:47 -07:00
Junio C Hamano 07198afbd1 Merge branch 'mm/fetch-show-error-message-on-unadvertised-object'
"git fetch" that requests a commit by object name, when the other
side does not allow such an request, failed without much
explanation.

* mm/fetch-show-error-message-on-unadvertised-object:
  fetch-pack: add specific error for fetching an unadvertised object
  fetch_refs_via_pack: call report_unmatched_refs
  fetch-pack: move code to report unmatched refs to a function
2017-03-14 15:23:18 -07:00
Matt McCutchen d56583ded6 fetch-pack: add specific error for fetching an unadvertised object
Enhance filter_refs (which decides whether a request for an unadvertised
object should be sent to the server) to record a new match status on the
"struct ref" when a request is not allowed, and have
report_unmatched_refs check for this status and print a special error
message, "Server does not allow request for unadvertised object".

Signed-off-by: Matt McCutchen <matt@mattmccutchen.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-02 11:12:53 -08:00
Matt McCutchen e70a65c5d8 fetch_refs_via_pack: call report_unmatched_refs
"git fetch" currently doesn't bother to check that it got all refs it
sought, because the common case of requesting a nonexistent ref triggers
a die() in get_fetch_map.  However, there's at least one case that
slipped through: "git fetch REMOTE SHA1" if the server doesn't allow
requests for unadvertised objects.  Make fetch_refs_via_pack (which is
on the "git fetch" code path) call report_unmatched_refs so that we at
least get an error message in that case.

Signed-off-by: Matt McCutchen <matt@mattmccutchen.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-02 11:12:53 -08:00
Pranit Bauva c7cf956618 don't use test_must_fail with grep
test_must_fail should only be used for testing git commands. To test the
failure of other commands use `!`.

Reported-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Pranit Bauva <pranit.bauva@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-01-07 13:20:01 -08:00
Elia Pinto bf45242ba7 t/t5516-fetch-push.sh: use the $( ... ) construct for command substitution
The Git CodingGuidelines prefer the $(...) construct for command
substitution instead of using the backquotes `...`.

The backquoted form is the traditional method for command
substitution, and is supported by POSIX.  However, all but the
simplest uses become complicated quickly.  In particular, embedded
command substitutions and/or the use of double quotes require
careful escaping with the backslash character.

The patch was generated by:

for _f in $(find . -name "*.sh")
do
	perl -i -pe 'BEGIN{undef $/;} s/`(.+?)`/\$(\1)/smg'  "${_f}"
done

and then carefully proof-read.

Signed-off-by: Elia Pinto <gitter.spiros@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-12-28 13:37:04 -08:00
Lars Schneider 8bf4becf0c add "ok=sigpipe" to test_must_fail and use it to fix flaky tests
t5516 "75 - deny fetch unreachable SHA1, allowtipsha1inwant=true" is
flaky in the following case:
1. remote upload-pack finds out "not our ref"
2. remote sends a response and closes the pipe
3. fetch-pack still tries to write commands to the remote upload-pack
4. write call in wrapper.c dies with SIGPIPE

The test is flaky because the sending fetch-pack may or may
not have finished writing its output by step (3). If it did,
then we see a closed pipe on the next read() call. If it
didn't, then we get the SIGPIPE from step (4) above. Both
are fine, but the latter fools test_must_fail.

t5504 "9 - push with transfer.fsckobjects" is flaky, too, and returns
SIGPIPE once in a while. I had to remove the final "To dst..." output
check because there is no output if the process dies with SIGPIPE.

Accept such a death-with-sigpipe also as OK when we are expecting a
failure.

Signed-off-by: Lars Schneider <larsxschneider@gmail.com>
Signed-off-by: Jeff King <peff@peff.net>
2015-11-28 12:06:14 -05:00
Fredrik Medley 68ee628932 upload-pack: optionally allow fetching reachable sha1
With uploadpack.allowReachableSHA1InWant configuration option set on the
server side, "git fetch" can make a request with a "want" line that names
an object that has not been advertised (likely to have been obtained out
of band or from a submodule pointer). Only objects reachable from the
branch tips, i.e. the union of advertised branches and branches hidden by
transfer.hideRefs, will be processed. Note that there is an associated
cost of having to walk back the history to check the reachability.

This feature can be used when obtaining the content of a certain commit,
for which the sha1 is known, without the need of cloning the whole
repository, especially if a shallow fetch is used. Useful cases are e.g.
repositories containing large files in the history, fetching only the
needed data for a submodule checkout, when sharing a sha1 without telling
which exact branch it belongs to and in Gerrit, if you think in terms of
commits instead of change numbers. (The Gerrit case has already been
solved through allowTipSHA1InWant as every Gerrit change has a ref.)

Signed-off-by: Fredrik Medley <fredrik.medley@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-05-22 18:25:36 -07:00
Junio C Hamano fa9aaa8f10 Merge branch 'jc/update-instead-into-void'
A push into an unborn branch, with "receive.denyCurrentBranch" set
to "updateInstead", did not check out the working tree as expected.

* jc/update-instead-into-void:
  push-to-deploy: allow pushing into an unborn branch and updating it
2015-04-14 11:49:10 -07:00
Junio C Hamano 1a51b52422 push-to-deploy: allow pushing into an unborn branch and updating it
Setting receive.denycurrentbranch to updateinstead and pushing into
the current branch, when the working tree and the index is truly
clean, is supposed to reset the working tree and the index to match
the tree of the pushed commit.  This did not work when pushing into
an unborn branch.

The code that drives push-to-checkout hook needs no change, as the
interface is defined so that hook can decide what to do when the
push is coming to an unborn branch and take an appropriate action
since the beginning.

Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-04-01 22:40:10 -07:00
Junio C Hamano 2f6ef71387 Merge branch 'jk/fetch-pack'
"git fetch" that fetches a commit using the allow-tip-sha1-in-want
extension could have failed to fetch all the requested refs.

* jk/fetch-pack:
  fetch-pack: remove dead assignment to ref->new_sha1
  fetch_refs_via_pack: free extra copy of refs
  filter_ref: make a copy of extra "sought" entries
  filter_ref: avoid overwriting ref->old_sha1 with garbage
2015-03-25 12:54:25 -07:00
Jeff King c3c17bf107 filter_ref: make a copy of extra "sought" entries
If the server supports allow_tip_sha1_in_want, we add any
unmatched raw-sha1 entries in our "sought" list of refs to
the list of refs we will ask the other side for. We do so by
inserting the original "struct ref" directly into our list,
rather than making a copy. This has several problems.

The most minor problem is that one cannot ever free the
resulting list; it contains structs that are copies of the
remote refs (made earlier by fetch_pack) along with sought
refs that are referenced elsewhere.

But more importantly that we set the ref->next pointer to
NULL, chopping off the remainder of any existing list that
the ref was a part of. We get the set of "sought" refs in
an array rather than a linked list, but that array is often
in turn generated from a list.  The test modification in
t5516 demonstrates this. Rather than fetching just an exact
sha1, we fetch that sha1 plus another ref:

  - we build a linked list of refs to fetch when do_fetch
    calls get_ref_map; the exact sha1 is first, followed by
    the named ref ("refs/heads/extra" in this case).

  - we pass that linked list to transport_fetch_ref, which
    squashes it into an array of pointers

  - that array goes to fetch_pack, which calls filter_ref.
    There we generate the want list from a mix of what the
    remote side has advertised, and the "sought" entry for
    the exact sha1. We set the sought entry's "next" pointer
    to NULL.

  - after we return from transport_fetch_refs, we then try
    to update the refs by following the linked list. But our
    list is now truncated, and we do not update
    refs/heads/extra at all.

We can fix this by making a copy of the ref. There's nothing
that fetch_pack does to it that must be reflected in the
original "sought" list (and indeed, if that were the case we
would have a serious bug, because it is only exact-sha1
entries which are treated this way).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-03-19 14:11:11 -07:00
Junio C Hamano 36ab7680c0 Merge branch 'ak/t5516-typofix'
* ak/t5516-typofix:
  t5516: correct misspelled pushInsteadOf
2015-03-06 15:02:32 -08:00
Anders Kaseorg eb32c66e8d t5516: correct misspelled pushInsteadOf
A future breakage to "git push" to make it incorrectly pay attention
to pushInsteadOf when it should not will be left uncaught without
this change.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-03-03 12:07:18 -08:00
Junio C Hamano 0855331941 receive-pack: support push-to-checkout hook
When receive.denyCurrentBranch is set to updateInstead, a push that
tries to update the branch that is currently checked out is accepted
only when the index and the working tree exactly matches the
currently checked out commit, in which case the index and the
working tree are updated to match the pushed commit.  Otherwise the
push is refused.

This hook can be used to customize this "push-to-deploy" logic.  The
hook receives the commit with which the tip of the current branch is
going to be updated, and can decide what kind of local changes are
acceptable and how to update the index and the working tree to match
the updated tip of the current branch.

For example, the hook can simply run `git read-tree -u -m HEAD "$1"`
in order to emulate 'git fetch' that is run in the reverse direction
with `git push`, as the two-tree form of `read-tree -u -m` is
essentially the same as `git checkout` that switches branches while
keeping the local changes in the working tree that do not interfere
with the difference between the branches.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-01-08 14:28:43 -08:00
Junio C Hamano 4d7a5ceacc t5516: more tests for receive.denyCurrentBranch=updateInstead
The previous one tests only the case where a path to be updated by
the push-to-deploy has an incompatible change in the target's
working tree that has already been added to the index, but the
feature itself wants to require the working tree to be a lot cleaner
than what is tested.  Add a handful more tests to protect the
feature from future changes that mistakenly (from the viewpoint of
the inventor of the feature) loosens the cleanliness requirement,
namely:

 - A change only to the working tree but not to the index is still a
   change to be protected;

 - An untracked file in the working tree that would be overwritten
   by a push-to-deploy needs to be protected;

 - A change that happens to make a file identical to what is being
   pushed is still a change to be protected (i.e. the feature's
   cleanliness requirement is more strict than that of checkout).

Also, test that a stat-only change to the working tree is not a
reason to reject a push-to-deploy.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-30 17:54:30 -08:00
Johannes Schindelin 1404bcbb6b receive-pack: add another option for receive.denyCurrentBranch
When synchronizing between working directories, it can be handy to update
the current branch via 'push' rather than 'pull', e.g. when pushing a fix
from inside a VM, or when pushing a fix made on a user's machine (where
the developer is not at liberty to install an ssh daemon let alone know
the user's password).

The common workaround – pushing into a temporary branch and then merging
on the other machine – is no longer necessary with this patch.

The new option is:

'updateInstead':
	Update the working tree accordingly, but refuse to do so if there
	are any uncommitted changes.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-30 17:15:13 -08:00
Junio C Hamano a1671dd82b Merge branch 'jk/fetch-reflog-df-conflict'
Corner-case bugfixes for "git fetch" around reflog handling.

* jk/fetch-reflog-df-conflict:
  ignore stale directories when checking reflog existence
  fetch: load all default config at startup
2014-11-06 10:52:32 -08:00
Jeff King 72549dfd5d fetch: load all default config at startup
When we start the git-fetch program, we call git_config to
load all config, but our callback only processes the
fetch.prune option; we do not chain to git_default_config at
all.

This means that we may not load some core configuration
which will have an effect. For instance, we do not load
core.logAllRefUpdates, which impacts whether or not we
create reflogs in a bare repository.

Note that I said "may" above. It gets even more exciting. If
we have to transfer actual objects as part of the fetch,
then we call fetch_pack as part of the same process. That
function loads its own config, which does chain to
git_default_config, impacting global variables which are
used by the rest of fetch. But if the fetch is a pure ref
update (e.g., a new ref which is a copy of an old one), we
skip fetch_pack entirely. So we get inconsistent results
depending on whether or not we have actual objects to
transfer or not!

Let's just load the core config at the start of fetch, so we
know we have it (we may also load it again as part of
fetch_pack, but that's OK; it's designed to be idempotent).

Our tests check both cases (with and without a pack). We
also check similar behavior for push for good measure, but
it already works as expected.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-04 12:13:46 -08:00
Jeff King 458a7e508c t5516: test pushing a tag of an otherwise unreferenced blob
It's not unreasonable to have a tag that points to a blob
that is not part of the normal history. We do this in
git.git to distribute gpg keys. However, we never explicitly
checked in our test suite that this actually works (i.e.,
that pack-objects actually sends the blob because of the tag
mentioning it).

It does in fact work fine, but a recent patch under
discussion broke this, and the test suite didn't notice.
Let's make the test suite more complete.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-10-19 15:07:06 -07:00
Junio C Hamano d52571d5c1 Merge branch 'jk/remote-pushremote-config-reading'
"git push" did not pay attention to branch.*.pushremote if it is
defined earlier than remote.pushdefault; the order of these two
variables in the configuration file should not matter, but it did by
mistake.

* jk/remote-pushremote-config-reading:
  remote: handle pushremote config in any order
2014-03-14 14:26:05 -07:00
Jeff King 98b406f3ad remote: handle pushremote config in any order
The remote we push can be defined either by
remote.pushdefault or by branch.*.pushremote for the current
branch. The order in which they appear in the config file
should not matter to precedence (which should be to prefer
the branch-specific config).

The current code parses the config linearly and uses a
single string to store both values, overwriting any
previous value. Thus, config like:

  [branch "master"]
  pushremote = foo
  [remote]
  pushdefault = bar

erroneously ends up pushing to "bar" from the master branch.

We can fix this by storing both values and resolving the
correct value after all config is read.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-02-24 12:53:28 -08:00
Junio C Hamano fc9261ca61 push: also use "upstream" mapping when pushing a single ref
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>
2013-12-04 15:12:34 -08:00
Junio C Hamano ca02465b41 push: use remote.$name.push as a refmap
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>
2013-12-04 15:11:08 -08:00
Nguyễn Thái Ngọc Duy f7c815c3ee push: respect --no-thin
- 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>
2013-08-13 10:32:26 -07:00
Junio C Hamano 54a3c67375 Merge branch 'jc/push-2.0-default-to-simple' (early part)
Adjust our tests for upcoming migration of the default value for the
"push.default" configuration variable to "simple" from "mixed".

* 'jc/push-2.0-default-to-simple' (early part):
  t5570: do not assume the "matching" push is the default
  t5551: do not assume the "matching" push is the default
  t5550: do not assume the "matching" push is the default
  t9401: do not assume the "matching" push is the default
  t9400: do not assume the "matching" push is the default
  t7406: do not assume the "matching" push is the default
  t5531: do not assume the "matching" push is the default
  t5519: do not assume the "matching" push is the default
  t5517: do not assume the "matching" push is the default
  t5516: do not assume the "matching" push is the default
  t5505: do not assume the "matching" push is the default
  t5404: do not assume the "matching" push is the default
2013-04-18 11:47:59 -07:00
Junio C Hamano 4d35924e3a Merge branch 'rr/triangle'
Support "pull from one place, push to another place" workflow
better by introducing remote.pushdefault (overrides the "origin"
thing) and branch.*.pushremote (overrides the branch.*.remote).

* rr/triangle:
  remote.c: introduce branch.<name>.pushremote
  remote.c: introduce remote.pushdefault
  remote.c: introduce a way to have different remotes for fetch/push
  t5516 (fetch-push): drop implicit arguments from helper functions
  t5516 (fetch-push): update test description
  remote.c: simplify a bit of code using git_config_string()
2013-04-07 14:32:50 -07:00
Junio C Hamano 41ae34d136 Merge branch 'jc/t5516-pushInsteadOf-vs-pushURL'
Update a test to match the documented interaction between pushURL
and pushInsteadOf.

* jc/t5516-pushInsteadOf-vs-pushURL:
  t5516: test interaction between pushURL and pushInsteadOf correctly
2013-04-03 09:34:49 -07:00
Ramkumar Ramachandra 9f765ce62f remote.c: introduce branch.<name>.pushremote
This new configuration variable overrides `remote.pushdefault` and
`branch.<name>.remote` for pushes.  When you pull from one
place (e.g. your upstream) and push to another place (e.g. your own
publishing repository), you would want to set `remote.pushdefault` to
specify the remote to push to for all branches, and use this option to
override it for a specific branch.

Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
Reviewed-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-04-02 10:41:43 -07:00
Ramkumar Ramachandra 224c217163 remote.c: introduce remote.pushdefault
This new configuration variable defines the default remote to push to,
and overrides `branch.<name>.remote` for all branches.  It is useful
in the typical triangular-workflow setup, where the remote you're
fetching from is different from the remote you're pushing to.

Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
Reviewed-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-04-02 10:41:42 -07:00
Jeff King 2e433b7895 t5516 (fetch-push): drop implicit arguments from helper functions
Many of the tests in t5516 look like:

  mk_empty &&
  git push testrepo ... &&
  check_push_result $commit heads/master

It's reasonably easy to see what is being tested, with the
exception that "testrepo" is a magic global name (it is
implicitly used in the helpers, but we have to name it
explicitly when calling git directly). Let's make it
explicit when call the helpers, too. This is slightly more
typing, but makes the test snippets read more naturally.

It also makes it easy for future tests to use an alternate
or multiple repositories, without a proliferation of helper
functions.

[rr: fixed sloppy quoting]

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
Reviewed-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-04-02 10:41:42 -07:00
Ramkumar Ramachandra 2ead7a674d t5516 (fetch-push): update test description
The file was originally created in bcdb34f (Test wildcard push/fetch,
2007-06-08), and only contained tests that exercised wildcard
functionality at the time.  In subsequent commits, many other tests
unrelated to wildcards were added but the test description was never
updated.  Fix this.

Helped-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
Reviewed-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-04-02 10:41:42 -07:00
Junio C Hamano ca54e43cf2 Merge branch 'jn/push-tests'
Update t5516 with style fixes.

* jn/push-tests:
  push test: rely on &&-chaining instead of 'if bad; then echo Oops; fi'
  push test: simplify check of push result
  push test: use test_config when appropriate
2013-04-01 09:06:15 -07:00
Junio C Hamano c68c408a7a t5516: test interaction between pushURL and pushInsteadOf correctly
1c2eafb89b (Add url.<base>.pushInsteadOf: URL rewriting for push
only, 2009-09-07) wants to make sure that a push destination read
from URL is not rewritten by pushInsteadOf because an explicit
pushURL exists; for that, a pushInsteadOf rewrite rule for the value
of remote.r.URL is set to a non-existent is set up.

We would also want to make sure that pushInsteadOf rewrite rule is
not applied to the location read from pushURL.

This way, we will make sure that

 - "testrepo/" (pushURL) gets updated;

 - the push does not try to update "trash2/" (the result of applying
   pushInsteadOf to pushURL);

 - the push does not try to update "trash3/" (the result of applying
   pushInsteadOf to URL).

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-03-28 13:53:27 -07:00
Junio C Hamano 55f6fbef3d Merge branch 'jc/push-follow-tag'
The new "--follow-tags" option tells "git push" to push relevant
annotated tags when pushing branches out.

* jc/push-follow-tag:
  push: --follow-tags
  commit.c: use clear_commit_marks_many() in in_merge_bases_many()
  commit.c: add in_merge_bases_many()
  commit.c: add clear_commit_marks_many()
2013-03-25 14:00:41 -07:00
Junio C Hamano e4e1c54990 Merge branch 'jc/fetch-raw-sha1'
Allows requests to fetch objects at any tip of refs (including
hidden ones).  It seems that there may be use cases even outside
Gerrit (e.g. $gmane/215701).

* jc/fetch-raw-sha1:
  fetch: fetch objects by their exact SHA-1 object names
  upload-pack: optionally allow fetching from the tips of hidden refs
  fetch: use struct ref to represent refs to be fetched
  parse_fetch_refspec(): clarify the codeflow a bit
2013-03-21 14:02:27 -07:00
Jonathan Nieder 5bd81c7315 push test: rely on &&-chaining instead of 'if bad; then echo Oops; fi'
When it is unclear which command from a test has failed, usual
practice these days is to debug by running the test again with "sh -x"
instead of relying on debugging 'echo' statements.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-03-19 11:07:27 -07:00
Jonathan Nieder 848575d833 push test: simplify check of push result
This test checks each ref with code like the following:

	r=$(git show-ref -s --verify refs/$ref) &&
	test "z$r" = "z$the_first_commit"

Afterward it counts refs:

	test 1 = $(git for-each-ref refs/remotes/origin | wc -l)

Simpler to test the number and values of relevant refs in for-each-ref
output at the same time using test_cmp.  This makes the test more
readable and provides more helpful "./t5516-push-push.sh -v" output
when the test fails.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-03-19 11:07:26 -07:00
Jonathan Nieder 3c69552338 push test: use test_config when appropriate
Configuration from test_config does not last beyond the end of the
current test assertion, making each test easier to think about in
isolation.

This changes the meaning of some of the tests.  For example, currently
"push with insteadOf" passes even if the line setting
"url.$TRASH.pushInsteadOf" is dropped because an url.$TRASH.insteadOf
setting leaks in from a previous test.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-03-19 11:07:25 -07:00
Junio C Hamano c2aba155da push: --follow-tags
The new option "--follow-tags" tells "git push" to push annotated
tags that are missing from the other side and that can be reached by
the history that is otherwise pushed out.

For example, if you are using the "simple", "current", or "upstream"
push, you would ordinarily push the history leading to the commit at
your current HEAD and nothing else.  With this option, you would
also push all annotated tags that can be reached from that commit to
the other side.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-03-05 13:39:46 -08:00
Junio C Hamano ce735bf7fd Merge branch 'jc/hidden-refs'
Allow the server side to redact the refs/ namespace it shows to the
client.

Will merge to 'master'.

* jc/hidden-refs:
  upload/receive-pack: allow hiding ref hierarchies
  upload-pack: simplify request validation
  upload-pack: share more code
2013-02-17 15:25:57 -08:00
Junio C Hamano 6e7b66eebd fetch: fetch objects by their exact SHA-1 object names
Teach "git fetch" to accept an exact SHA-1 object name the user may
obtain out of band on the LHS of a pathspec, and send it on a "want"
message when the server side advertises the allow-tip-sha1-in-want
capability.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-02-07 14:07:53 -08:00
Junio C Hamano daebaa7813 upload/receive-pack: allow hiding ref hierarchies
A repository may have refs that are only used for its internal
bookkeeping purposes that should not be exposed to the others that
come over the network.

Teach upload-pack to omit some refs from its initial advertisement
by paying attention to the uploadpack.hiderefs multi-valued
configuration variable.  Do the same to receive-pack via the
receive.hiderefs variable.  As a convenient short-hand, allow using
transfer.hiderefs to set the value to both of these variables.

Any ref that is under the hierarchies listed on the value of these
variable is excluded from responses to requests made by "ls-remote",
"fetch", etc. (for upload-pack) and "push" (for receive-pack).

Because these hidden refs do not count as OUR_REF, an attempt to
fetch objects at the tip of them will be rejected, and because these
refs do not get advertised, "git push :" will not see local branches
that have the same name as them as "matching" ones to be sent.

An attempt to update/delete these hidden refs with an explicit
refspec, e.g. "git push origin :refs/hidden/22", is rejected.  This
is not a new restriction.  To the pusher, it would appear that there
is no such ref, so its push request will conclude with "Now that I
sent you all the data, it is time for you to update the refs.  I saw
that the ref did not exist when I started pushing, and I want the
result to point at this commit".  The receiving end will apply the
compare-and-swap rule to this request and rejects the push with
"Well, your update request conflicts with somebody else; I see there
is such a ref.", which is the right thing to do. Otherwise a push to
a hidden ref will always be "the last one wins", which is not a good
default.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-02-07 13:48:47 -08:00
Junio C Hamano 256b9d70a4 push: fix "refs/tags/ hierarchy cannot be updated without --force"
When pushing to update a branch with a commit that is not a
descendant of the commit at the tip, a wrong message "already
exists" was given, instead of the correct "non-fast-forward", if we
do not have the object sitting in the destination repository at the
tip of the ref we are updating.

The primary cause of the bug is that the check in a new helper
function is_forwardable() assumed both old and new objects are
available and can be checked, which is not always the case.

The way the caller uses the result of this function is also wrong.
If the helper says "we do not want to let this push go through", the
caller unconditionally translates it into "we blocked it because the
destination already exists", which is not true at all in this case.

Fix this by doing these three things:

 * Remove unnecessary not_forwardable from "struct ref"; it is only
   used inside set_ref_status_for_push();

 * Make "refs/tags/" the only hierarchy that cannot be replaced
   without --force;

 * Remove the misguided attempt to force that everything that
   updates an existing ref has to be a commit outside "refs/tags/"
   hierarchy.

The policy last one tried to implement may later be resurrected and
extended to ensure fast-forwardness (defined as "not losing
objects", extending from the traditional "not losing commits from
the resulting history") when objects that are not commit are
involved (e.g. an annotated tag in hierarchies outside refs/tags),
but such a logic belongs to "is this a fast-forward?" check that is
done by ref_newer(); is_forwardable(), which is now removed, was not
the right place to do so.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-01-16 13:03:57 -08:00
Junio C Hamano 0a42ac0331 t5516: do not assume the "matching" push is the default
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-01-04 22:28:41 -08:00
Chris Rorvick 40eff17999 push: require force for annotated tags
Do not allow fast-forwarding of references that point to a tag object.
Updating from a tag is potentially destructive since it would likely
leave the tag dangling.  Disallowing updates to a tag also makes sense
semantically and is consistent with the behavior of lightweight tags.

Signed-off-by: Chris Rorvick <chris@rorvick.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-12-02 01:44:49 -08:00
Chris Rorvick dbfeddb12e push: require force for refs under refs/tags/
References are allowed to update from one commit-ish to another if the
former is an ancestor of the latter.  This behavior is oriented to
branches which are expected to move with commits.  Tag references are
expected to be static in a repository, though, thus an update to
something under refs/tags/ should be rejected unless the update is
forced.

Signed-off-by: Chris Rorvick <chris@rorvick.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-12-02 01:44:34 -08:00
Felipe Contreras 6ddba5e241 push: add '--prune' option
When pushing groups of refs to a remote, there is no simple way to remove
old refs that still exist at the remote that is no longer updated from us.
This will allow us to remove such refs from the remote.

With this change, running this command

 $ git push --prune remote refs/heads/*:refs/remotes/laptop/*

removes refs/remotes/laptop/foo from the remote if we do not have branch
"foo" locally anymore.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-02-22 18:17:39 -08:00
Pang Yan Han 160b81ed81 receive-pack: don't pass non-existent refs to post-{receive,update} hooks
When a push specifies deletion of non-existent refs, the post post-receive and
post-update hooks receive them as input/arguments.

For instance, for the following push, where refs/heads/nonexistent is a ref
which does not exist on the remote side:

	git push origin :refs/heads/nonexistent

the post-receive hook receives from standard input:

	<null-sha1> SP <null-sha1> SP refs/heads/nonexistent

and the post-update hook receives as arguments:

	refs/heads/nonexistent

which does not make sense since it is a no-op.

Teach receive-pack not to pass non-existent refs to the post-receive and
post-update hooks. If the push only attempts to delete non-existent refs,
these hooks are not even called.

The update and pre-receive hooks are still notified about attempted
deletion of non-existent refs to give them a chance to inspect the
situation and act on it.

[jc: mild fix-ups to avoid introducing an extra list; also added fixes to
some tests]

Signed-off-by: Pang Yan Han <pangyanhan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-09-30 12:18:46 -07:00
Dmitry Ivankov 7be8b3baba Fix typo: existant->existent
refs.c had a error message "Trying to write ref with nonexistant object".
And no tests relied on the wrong spelling.
Also typo was present in some test scripts internals, these tests still pass.

Signed-off-by: Dmitry Ivankov <divanorama@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-06-16 10:33:50 -07:00
Jonathan Nieder a48fcd8369 tests: add missing &&
Breaks in a test assertion's && chain can potentially hide
failures from earlier commands in the chain.

Commands intended to fail should be marked with !, test_must_fail, or
test_might_fail.  The examples in this patch do not require that.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-11-09 11:59:49 -08:00
Junio C Hamano 9215f76fb6 Merge branch 'js/maint-receive-pack-symref-alias'
* js/maint-receive-pack-symref-alias:
  t5516-fetch-push.sh: style cleanup
  receive-pack: detect aliased updates which can occur with symrefs
  receive-pack: switch global variable 'commands' to a parameter

Conflicts:
	t/t5516-fetch-push.sh
2010-05-21 04:02:19 -07:00
bert Dvornik fc012c2810 start_command: close cmd->err descriptor when fork/spawn fails
Fix the problem where the cmd->err passed into start_command wasn't
being properly closed when certain types of errors occurr.  (Compare
the affected code with the clean shutdown code later in the function.)

On Windows, this problem would be triggered if mingw_spawnvpe()
failed, which would happen if the command to be executed was malformed
(e.g. a text file that didn't start with a #! line).  If cmd->err was
a pipe, the failure to close it could result in a hang while the other
side was waiting (forever) for either input or pipe close, e.g. while
trying to shove the output into the side band.  On msysGit, this
problem was causing a hang in t5516-fetch-push.

[J6t: With a slight adjustment of the test case, the hang is also
observed on Linux.]

Signed-off-by: bert Dvornik <dvornik+git@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-05-20 16:11:29 -07:00
Jay Soffian d4785cd11d t5516-fetch-push.sh: style cleanup
Cleanup t5516-fetch-push.sh to use prevailing test script style

Signed-off-by: Jay Soffian <jaysoffian@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-04-19 22:19:30 -07:00
Jay Soffian da3efdb17b receive-pack: detect aliased updates which can occur with symrefs
When pushing to a remote repo the sending side filters out aliased
updates (e.g., foo:baz bar:baz). However, it is not possible for the
sender to know if two refs are aliased on the receiving side via
symrefs. Here is one such scenario:

  $ git init origin
  $ (cd origin && touch file && git add file && git commit -a -m intial)
  $ git clone --bare origin origin.git
  $ rm -rf origin

  $ git clone origin.git client

  $ git clone --mirror client backup.git &&
  $ (cd backup.git && git remote set-head origin --auto)

  $ (cd client &&
	git remote add --mirror backup ../backup.git &&
	echo change1 > file && git commit -a -m change1 &&
	git push origin &&
	git push backup
	)

The push to backup fails with:

  Counting objects: 5, done.
  Writing objects: 100% (3/3), 244 bytes, done.
  Total 3 (delta 0), reused 0 (delta 0)
  Unpacking objects: 100% (3/3), done.
  error: Ref refs/remotes/origin/master is at ef3... but expected 262...
  remote: error: failed to lock refs/remotes/origin/master
  To ../backup.git
     262cd57..ef307ff  master -> master
     262cd57..ef307ff  origin/HEAD -> origin/HEAD
   ! [remote rejected] origin/master -> origin/master (failed to lock)
  error: failed to push some refs to '../backup.git'

The reason is that refs/remotes/origin/HEAD is a symref to
refs/remotes/origin/master, but it is not possible for the sending side
to unambiguously know this.

This commit fixes the issue by having receive-pack ignore any update to
a symref whose target is being identically updated. If a symref and its
target are being updated inconsistently, then the update for both fails
with an error message ("refusing inconsistent update...") to help
diagnose the situation.

Signed-off-by: Jay Soffian <jaysoffian@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-04-19 22:19:07 -07:00
Junio C Hamano c296134d03 t5516: Use test_cmp when appropriate
Consistently using test_cmp would make debugging test scripts far easier,
as output from them run under "-v" option becomes readable.

Besides, some platforms' "diff" implementations lack "-q" option.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-03-11 21:53:07 -08:00
Larry D'Anna fbe4f447ec git-push: add tests for git push --porcelain
Verify that the output format is correct for successful, rejected, and
flagrantly erroneous pushes.

Signed-off-by: Larry D'Anna <larry@elder-gods.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-02-28 10:39:31 -08:00
Junio C Hamano 84d52cabe7 Merge branch 'jk/push-to-delete'
* jk/push-to-delete:
  builtin-push: add --delete as syntactic sugar for :foo
2010-01-10 08:52:45 -08:00
Jan Krüger f517f1f2e9 builtin-push: add --delete as syntactic sugar for :foo
Refspecs without a source side have been reported as confusing by many.
As an alternative, this adds support for commands like:

    git push origin --delete somebranch
    git push origin --delete tag sometag

Specifically, --delete will prepend a colon to all colon-less refspecs
given on the command line, and will refuse to accept refspecs with
colons to prevent undue confusion.

Signed-off-by: Jan Krüger <jk@jk.gs>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-12-30 14:01:55 -08:00
Junio C Hamano 7ad9cec81d Merge branch 'jc/1.7.0-push-safety'
* jc/1.7.0-push-safety:
  Refuse deleting the current branch via push
  Refuse updating the current branch in a non-bare repository via push
2009-12-26 14:03:17 -08:00
Josh Triplett 1c2eafb89b Add url.<base>.pushInsteadOf: URL rewriting for push only
This configuration option allows systematically rewriting fetch-only URLs
to push-capable URLs when used with push.  For instance:

[url "ssh://example.org/"]
    pushInsteadOf = "git://example.org/"

This will allow clones of "git://example.org/path/to/repo" to subsequently
push to "ssh://example.org/path/to/repo", without manually configuring
pushurl for that remote.

Includes documentation for the new option, bash completion updates, and
test cases (both that pushInsteadOf applies to push, that it does not
apply to fetch, and that it is ignored when pushURL is already defined).

Signed-off-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-09-08 01:18:46 -07:00
Junio C Hamano acd2a45b83 Refuse updating the current branch in a non-bare repository via push
This makes git-push refuse pushing into a non-bare repository to update
the current branch by default.  To help people who are used to be able to
do this (and later "reset --hard" it in some other way), an error message
is issued when this refusal is triggered, instructing how to resurrect the
old behaviour.

Hosting sites that do not give the users direct access to customize their
repositories (e.g. repo.or.cz, gitorious, github etc.) may further want to
explicitly set the configuration variable to "refuse" for their customers'
repositories.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-07-29 10:15:00 -07:00
Michael J Gruber e1ca424112 t5516: Check pushurl config setting
Check whether the new remote.${remotename}.pushurl setting is obeyed
and whether it overrides remote.${remotename}.url.

Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-09 23:46:47 -07:00
Junio C Hamano 3d95d92b9a receive-pack: explain what to do when push updates the current branch
This makes "git push" issue a more detailed instruction when a user pushes
into the current branch of a non-bare repository without having an
explicit configuration set to receive.denycurrentbranch.  In such a case,
it will also tell the user that the default will change to refusal in a
future version of git.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-02-03 00:39:18 -08:00
Junio C Hamano 3fdd37fe15 Merge branch 'mk/maint-cg-push'
* mk/maint-cg-push:
  git push: Interpret $GIT_DIR/branches in a Cogito compatible way

Conflicts:
	t/t5516-fetch-push.sh
2008-11-12 22:26:24 -08:00
Martin Koegler 18afe101eb git push: Interpret $GIT_DIR/branches in a Cogito compatible way
Current git versions ignore everything after # (called <head> in the
following) when pushing. Older versions (before cf818348f1),
interpret #<head> as part of the URL, which make git bail out.

As branches origin from Cogito, it is the best to correct this by using
the behaviour of cg-push, that is to push HEAD to remote refs/heads/<head>.

Signed-off-by: Martin Koegler <mkoegler@auto.tuwien.ac.at>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-11-11 15:26:40 -08:00
Jeff King 986e82396a receive-pack: detect push to current branch of non-bare repo
Pushing into the currently checked out branch of a non-bare
repository can be dangerous; the HEAD then loses sync with
the index and working tree, and it looks in the receiving
repo as if the pushed changes have been reverted in the
index (since they were never there in the first place).

This patch adds a safety valve that checks for this
condition and either generates a warning or denies the
update. We trigger the check only on a non-bare repository,
since a bare repo does not have a working tree (and in fact,
pushing to the HEAD branch is a common workflow for
publishing repositories).

The behavior is configurable via receive.denyCurrentBranch,
defaulting to "warn" so as not to break existing setups
(though it may, after a deprecation period, switch to
"refuse" by default). For users who know what they are doing
and want to silence the warning (e.g., because they have a
post-receive hook that reconciles the HEAD and working
tree), they can turn off the warning by setting it to false
or "ignore".

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-11-09 10:16:50 -08:00