The auto-tag-following code in "git fetch" tries to reuse the same
transport twice when the serving end does not cooperate and does
not give tags that point to commits that are asked for as part of
the primary transfer. Unfortunately, Git-aware transport helper
interface is not designed to be used more than once, hence this
does not work over smart-http transfer.
* jc/transport-do-not-use-connect-twice-in-fetch:
builtin/fetch.c: Fix a sparse warning
fetch: work around "transport-take-over" hack
fetch: refactor code that fetches leftover tags
fetch: refactor code that prepares a transport
fetch: rename file-scope global "transport" to "gtransport"
t5802: add test for connect helper
A Git-aware "connect" transport allows the "transport_take_over" to
redirect generic transport requests like fetch(), push_refs() and
get_refs_list() to the native Git transport handling methods. The
take-over process replaces transport->data with a fake data that
these method implementations understand.
While this hack works OK for a single request, it breaks when the
transport needs to make more than one requests. transport->data
that used to hold necessary information for the specific helper to
work correctly is destroyed during the take-over process.
One codepath that this matters is "git fetch" in auto-follow mode;
when it does not get all the tags that ought to point at the history
it got (which can be determined by looking at the peeled tags in the
initial advertisement) from the primary transfer, it internally
makes a second request to complete the fetch. Because "take-over"
hack has already destroyed the data necessary to talk to the
transport helper by the time this happens, the second request cannot
make a request to the helper to make another connection to fetch
these additional tags.
Mark such a transport as "cannot_reuse", and use a separate
transport to perform the backfill fetch in order to work around
this breakage.
Note that this problem does not manifest itself when running t5802,
because our upload-pack gives you all the necessary auto-followed
tags during the primary transfer. You would need to step through
"git fetch" in a debugger, stop immediately after the primary
transfer finishes and writes these auto-followed tags, remove the
tag references and repack/prune the repository to convince the
"find-non-local-tags" procedure that the primary transfer failed to
give us all the necessary tags, and then let it continue, in order
to trigger the bug in the secondary transfer this patch fixes.
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>
The definition of "struct ref" in "cache.h", a header file so
central to the system, always confused me. This structure is not
about the local ref used by sha1-name API to name local objects.
It is what refspecs are expanded into, after finding out what refs
the other side has, to define what refs are updated after object
transfer succeeds to what values. It belongs to "remote.h" together
with "struct refspec".
While we are at it, also move the types and functions related to the
Git transport connection to a new header file connect.h
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation and some comments still refer to files in builtin/
as 'builtin-*.[cho]'. Update these to show the correct location.
Signed-off-by: Phil Hord <hordp@cisco.com>
Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
Assisted-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
In order to make sure the cloned repository is good, we run "rev-list
--objects --not --all $new_refs" on the repository. This is expensive
on large repositories. This patch attempts to mitigate the impact in
this special case.
In the "good" clone case, we only have one pack. If all of the
following are met, we can be sure that all objects reachable from the
new refs exist, which is the intention of running "rev-list ...":
- all refs point to an object in the pack
- there are no dangling pointers in any object in the pack
- no objects in the pack point to objects outside the pack
The second and third checks can be done with the help of index-pack as
a slight variation of --strict check (which introduces a new condition
for the shortcut: pack transfer must be used and the number of objects
large enough to call index-pack). The first is checked in
check_everything_connected after we get an "ok" from index-pack.
"index-pack + new checks" is still faster than the current "index-pack
+ rev-list", which is the whole point of this patch. If any of the
conditions fail, we fall back to the good old but expensive "rev-list
..". In that case it's even more expensive because we have to pay for
the new checks in index-pack. But that should only happen when the
other side is either buggy or malicious.
Cloning linux-2.6 over file://
before after
real 3m25.693s 2m53.050s
user 5m2.037s 4m42.396s
sys 0m13.750s 0m16.574s
A more realistic test with ssh:// over wireless
before after
real 11m26.629s 10m4.213s
user 5m43.196s 5m19.444s
sys 0m35.812s 0m37.630s
This shortcut is not applied to shallow clones, partly because shallow
clones should have no more objects than a usual fetch and the cost of
rev-list is acceptable, partly to avoid dealing with corner cases when
grafting is involved.
This shortcut does not apply to unpack-objects code path either
because the number of objects must be small in order to trigger that
code path.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
* maint:
Correct common spelling mistakes in comments and tests
kwset: fix spelling in comments
precompose-utf8: fix spelling of "want" in error message
compat/nedmalloc: fix spelling in comments
compat/regex: fix spelling and grammar in comments
obstack: fix spelling of similar
contrib/subtree: fix spelling of accidentally
git-remote-mediawiki: spelling fixes
doc: various spelling fixes
fast-export: fix argument name in error messages
Documentation: distinguish between ref and offset deltas in pack-format
i18n: make the translation of -u advice in one go
Most of these were found using Lucas De Marchi's codespell tool.
Signed-off-by: Stefano Lattarini <stefano.lattarini@gmail.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Acked-by: Matthieu Moy <Matthieu.Moy@imag.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
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>
Improve error and advice messages given locally when "git push"
refuses when it cannot compute fast-forwardness by separating these
cases from the normal "not a fast-forward; merge first and push
again" case.
* jc/push-reject-reasons:
push: finishing touches to explain REJECT_ALREADY_EXISTS better
push: introduce REJECT_FETCH_FIRST and REJECT_NEEDS_FORCE
push: further simplify the logic to assign rejection reason
push: further clean up fields of "struct ref"
When we push to update an existing ref, if:
* the object at the tip of the remote is not a commit; or
* the object we are pushing is not a commit,
it won't be correct to suggest to fetch, integrate and push again,
as the old and new objects will not "merge". We should explain that
the push must be forced when there is a non-committish object is
involved in such a case.
If we do not have the current object at the tip of the remote, we do
not even know that object, when fetched, is something that can be
merged. In such a case, suggesting to pull first just like
non-fast-forward case may not be technically correct, but in
practice, most such failures are seen when you try to push your work
to a branch without knowing that somebody else already pushed to
update the same branch since you forked, so "pull first" would work
as a suggestion most of the time. And if the object at the tip is
not a commit, "pull first" will fail, without making any permanent
damage. As a side effect, it also makes the error message the user
will get during the next "push" attempt easier to understand, now
the user is aware that a non-commit object is involved.
In these cases, the current code already rejects such a push on the
client end, but we used the same error and advice messages as the
ones used when rejecting a non-fast-forward push, i.e. pull from
there and integrate before pushing again.
Introduce new rejection reasons and reword the messages
appropriately.
[jc: with help by Peff on message details]
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Add support for a pre-push hook which can be used to determine if the
set of refs to be pushed is suitable for the target repository. The
hook is run with two arguments specifying the name and location of the
destination repository.
Information about what is to be pushed is provided by sending lines of
the following form to the hook's standard input:
<local ref> SP <local sha1> SP <remote ref> SP <remote sha1> LF
If the hook exits with a non-zero status, the push will be aborted.
This will allow the script to determine if the push is acceptable based
on the target repository and branch(es), the commits which are to be
pushed, and even the source branches in some cases.
Signed-off-by: Aaron Schrab <aaron@schrab.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Advising the user to fetch and merge only makes sense if the rejected
reference is a branch. If none of the rejections are for branches, just
tell the user the reference already exists.
Signed-off-by: Chris Rorvick <chris@rorvick.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Pass all rejection reasons back from transport_push(). The logic is
simpler and more flexible with regard to providing useful feedback.
Signed-off-by: Chris Rorvick <chris@rorvick.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
send_pack() is used by transport.c, part of libgit.a while it stays in
builtin/send-pack.c. Move it to send-pack.c so that we won't get
undefined reference if a program that uses libgit.a happens to pull it
in.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Jeff King <peff@peff.net>
fetch does printf("%-*s", width, "foo") where "foo" can be a utf-8
string, but width is in bytes, not columns. For ASCII it's fine as one
byte takes one column. For utf-8, this may result in misaligned ref
summary table.
Introduce gettext_width() function that returns the string length in
columns (currently only supports utf-8 locales). Make the code use
TRANSPORT_SUMMARY(x) where the length is compensated properly in
non-English locales.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
"git push --recurse-submodules" learns to optionally look into the
histories of submodules bound to the superproject and push them out.
By Heiko Voigt
* hv/submodule-recurse-push:
push: teach --recurse-submodules the on-demand option
Refactor submodule push check to use string list instead of integer
Teach revision walking machinery to walk multiple times sequencially
When using this option git will search for all submodules that
have changed in the revisions to be send. It will then try to
push the currently checked out branch of each submodule.
This helps when a user has finished working on a change which
involves submodules and just wants to push everything in one go.
Signed-off-by: Fredrik Gustafsson <iveqy@iveqy.com>
Mentored-by: Jens Lehmann <Jens.Lehmann@web.de>
Mentored-by: Heiko Voigt <hvoigt@hvoigt.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Each ref structure contains a "nonfastforward" field which
is set during push to show whether the ref rewound history.
Originally this was a single bit, but it was changed in
f25950f (push: Provide situational hints for non-fast-forward
errors) to an enum differentiating a non-ff of the current
branch versus another branch.
However, we never actually set the member according to the
enum values, nor did we ever read it expecting anything but
a boolean value. But we did use the side effect of declaring
the enum constants to store those values in a totally
different integer variable. The code as-is isn't buggy, but
the enum declaration inside "struct ref" is somewhat
misleading.
Let's convert nonfastforward back into a single bit, and
then define the NON_FF_* constants closer to where they
would be used (they are returned via the "int *nonfastforward"
parameter to transport_push, so we can define them there).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
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>
When working with submodules it is easy to forget to push a
submodule to the server but pushing a super-project that
contains a commit for that submodule. The result is that the
superproject points at a submodule commit that is not available
on the server.
This adds the option --recurse-submodules=check to push. When
using this option git will check that all submodule commits that
are about to be pushed are present on a remote of the submodule.
To be able to use a combined diff, disabling a diff callback has
been removed from combined-diff.c.
Signed-off-by: Fredrik Gustafsson <iveqy@iveqy.com>
Mentored-by: Jens Lehmann <Jens.Lehmann@web.de>
Mentored-by: Heiko Voigt <hvoigt@hvoigt.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The foreach_alt_odb function triggers a callback for each
alternate object db we have, with room for a single void
pointer as data. Currently, we always call refs_from_alternate_cb
as the callback function, and then pass another callback (to
receive each ref individually) as the void pointer.
This has two problems:
1. C technically forbids stuffing a function pointer into
a "void *". In practice, this probably doesn't matter
on any architectures git runs on, but it never hurts to
follow the letter of the law.
2. There is no room for an extra data pointer. Indeed, the
alternate_ref_fn that refs_from_alternate_cb calls
takes a void* for data, but we always pass it NULL.
Instead, let's properly stuff our function pointer into a
data struct, which also leaves room for an extra
caller-supplied data pointer. And to keep things simple for
existing callers, let's make a for_each_alternate_ref
function that takes care of creating the extra struct.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The receiving end of "git push" advertises the objects that the repository
itself does not use, but are at the tips of refs in other repositories
whose object databases are used as alternates for it. This helps it avoid
having to receive (and the pusher having to send) objects that are already
available to the receiving repository via the alternates mechanism.
Tweak the helper function that implements this feature, and move it to
transport.[ch] for future reuse by other programs.
The additional test demonstrates how this optimization is helping "git push",
and "git fetch" is ignorant about it.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Acked-by: Shawn O. Pearce <spearce@spearce.org>
This helper function copies bidirectional stream of data between
stdin/stdout and specified file descriptors.
Signed-off-by: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
* tc/transport-verbosity:
transport: update flags to be in running order
fetch and pull: learn --progress
push: learn --progress
transport->progress: use flag authoritatively
clone: support multiple levels of verbosity
push: support multiple levels of verbosity
fetch: refactor verbosity option handling into transport.[ch]
Documentation/git-push: put --quiet before --verbose
Documentation/git-pull: put verbosity options before merge/fetch ones
Documentation/git-clone: mention progress in -v
Conflicts:
transport.h
Set transport->progress in transport.c::transport_set_verbosity() after
checking for the appropriate conditions (eg. --progress, isatty(2)),
and thereafter use it without having to check again.
The rules used are as follows (processing aborts when a rule is
satisfied):
1. Report progress, if force_progress is 1 (ie. --progress).
2. Don't report progress, if verbosity < 0 (ie. -q/--quiet).
3. Report progress if isatty(2) is 1.
This changes progress reporting behaviour such that if both --progress
and --quiet are specified, progress is reported.
In two areas, the logic to determine whether to *not* show progress is
changed to simply use the negation of transport->progress. This changes
behaviour in some ways (see previous paragraph for details).
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Remove the flags TRANSPORT_PUSH_QUIET and TRANSPORT_PUSH_VERBOSE; use
transport->verbose instead to determine verbosity for pushing.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
transport_set_verbosity() is now provided to transport users.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The following functions are (almost) identical:
verify_remote_names
update_tracking_ref
refs_pushed
print_push_status
Move common versions of these functions to transport.c and rename
them, as suggested by Jeff King and Junio C Hamano.
These functions have been removed entirely from builtin-send-pack.c,
since they are only used internally by print_push_status():
print_ref_status
status_abbrev
print_ok_ref_status
print_one_push_status
Also, move #define SUMMARY_WIDTH to transport.h and rename it
TRANSPORT_SUMMARY_WIDTH as it is used in builtin-fetch.c and
transport.c
Signed-off-by: Michael Lukashov <michael.lukashov@gmail.com>
Acked-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
transport_get_remote_refs() in tranport.c checks transport->remote_refs
to determine whether transport->get_refs_list() should be invoked. The
logic is "if it is NULL, we haven't run ls-remote to find out yet".
However, transport->remote_refs could still be NULL while cloning from
an empty repository. This causes get_refs_list() to be run unnecessarily.
Introduce a flag, transport->got_remote_refs, to more explicitly record
if we have run transport->get_refs_list() already.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
* tc/clone-v-progress:
clone: use --progress to force progress reporting
clone: set transport->verbose when -v/--verbose is used
git-clone.txt: reword description of progress behaviour
check stderr with isatty() instead of stdout when deciding to show progress
Conflicts:
transport.c
Frequent complaint is lack of easy way to set up upstream (tracking)
references for git pull to work as part of push command. So add switch
--set-upstream (-u) to do just that.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Make transport code (viz. transport.c::fetch_refs_via_pack() and
transport-helper.c::standard_options()) that decides to show progress
check if stderr is a terminal, instead of stdout. After all, progress
reports (via the API in progress.[ch]) are sent to stderr.
Update the documentation for git-clone to say "standard error" as well.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Previously, remote archive required internal (non remote-helper)
smart transport. Extend the remote archive to also support smart
transports implemented by remote helpers.
Signed-off-by: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Add support for taking over transports that turn out to be smart.
Signed-off-by: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Refactor the transport options parsing so that protocols that aren't
directly smart transports (file://, git://, ssh:// & co) can record
the smart transport options for the case if it turns that transport
can actually be smart.
Signed-off-by: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
* master: (334 commits)
bash: update 'git commit' completion
Git 1.6.5.5
Fix diff -B/--dirstat miscounting of newly added contents
reset: improve worktree safety valves
Documentation: Avoid use of xmlto --stringparam
archive: clarify description of path parameter
rerere: don't segfault on failure to open rr-cache
Prepare for 1.6.5.5
gitweb: Describe (possible) gitweb.js minification in gitweb/README
Documentation: xmlto 0.0.18 does not know --stringparam
Fix crasher on encountering SHA1-like non-note in notes tree
t9001: use older Getopt::Long boolean prefix '--no' rather than '--no-'
t4201: use ISO8859-1 rather than ISO-8859-1
Git 1.6.5.4
Unconditionally set man.base.url.for.relative.links
Documentation/Makefile: allow man.base.url.for.relative.link to be set from Make
Git 1.6.6-rc1
git-pull.sh: Fix call to git-merge for new command format
Prepare for 1.6.5.4
merge: do not add standard message when message is given with -m option
...
Conflicts:
Documentation/git-remote-helpers.txt
Makefile
builtin-ls-remote.c
builtin-push.c
transport-helper.c
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This allows the transport to use the null sha1 for a ref reported to
be present in the remote repository to indicate that a ref exists but
its actual value is presently unknown and will be set if the objects
are fetched.
Also adds documentation to the API to specify exactly what the methods
should do and how they should interpret arguments.
Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Sverre Rabbelier <srabbelier@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Helpers might want a higher level of verbosity than just +1 (the
porcelain default setting) and +2 (-v -v). Expand the field to
allow verbosity in the range -1..3.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
CC: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
* db/vcs-helper:
Makefile: remove remnant of separate http/https/ftp helpers
Use a clearer style to issue commands to remote helpers
Make the "traditionally-supported" URLs a special case
Makefile: install hardlinks for git-remote-<scheme> supported by libcurl if possible
Makefile: do not link three copies of git-remote-* programs
Makefile: git-http-fetch does not need expat
http-fetch: Fix Makefile dependancies
Add transport native helper executables to .gitignore
git-http-fetch: not a builtin
Use an external program to implement fetching with curl
Add support for external programs for handling native fetches
Instead of trying to make http://, https://, and ftp:// URLs
indicative of some sort of pattern of transport helper usage, make
them a special case which runs the "curl" helper, and leave the
mechanism by which arbitrary helpers will be chosen entirely to future
work.
Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
* maint:
push: point to 'git pull' and 'git push --force' in case of non-fast forward
Documentation: add: <filepattern>... is optional
Change mentions of "git programs" to "git commands"
Documentation: merge: one <remote> is required
help.c: give correct structure's size to memset()
'git push' failing because of non-fast forward is a very common situation,
and a beginner does not necessarily understand "fast forward" immediately.
Add a new section to the git-push documentation and refer them to it.
Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Nanako Shiraishi <nanako3@lavabit.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Some transports produce output even without "--verbose"
turned on. This provides a way to tell them to be more
quiet (whereas simply redirecting might lose error
messages).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>