Commit graph

144 commits

Author SHA1 Message Date
Samuel Tardieu 944163a4bd Honor "tagopt = --tags" configuration option
If the "tagopt = --tags" option of a remote is set, all tags
will be fetched as in "git fetch --tags".

Signed-off-by: Samuel Tardieu <sam@rfc1149.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-04-19 16:34:49 -07:00
Tay Ray Chuan 20e8b465a5 refactor ref status logic for pushing
Move the logic that detects up-to-date and non-fast-forward refs to a
new function in remote.[ch], set_ref_status_for_push().

Make transport_push() invoke set_ref_status_for_push() before invoking
the push_refs() implementation. (As a side-effect, the push_refs()
implementation in transport-helper.c now knows of non-fast-forward
pushes.)

Removed logic for detecting up-to-date refs from the push_refs()
implementation in transport-helper.c, as transport_push() has already
done so for it.

Make cmd_send_pack() invoke set_ref_status_for_push() before invoking
send_pack(), as transport_push() can't do it for send_pack() here.

Mark the test on the return status of non-fast-forward push to fail.
Git now exits with success, as transport.c::transport_push() does not
check for refs with status REF_STATUS_REJECT_NONFASTFORWARD nor does it
indicate rejected pushes with its return value.

Mark the test for ref status to succeed. As mentioned earlier, refs
might be marked as non-fast-forwards, triggering the push status
printing mechanism in transport.c.

Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-09 23:34:10 -08:00
Junio C Hamano e74f43f9b7 Merge branch 'sr/vcs-helper'
* sr/vcs-helper:
  tests: handle NO_PYTHON setting
  builtin-push: don't access freed transport->url
  Add Python support library for remote helpers
  Basic build infrastructure for Python scripts
  Allow helpers to report in "list" command that the ref is unchanged
  Fix various memory leaks in transport-helper.c
  Allow helper to map private ref names into normal names
  Add support for "import" helper command
  Allow specifying the remote helper in the url
  Add a config option for remotes to specify a foreign vcs
  Allow fetch to modify refs
  Use a function to determine whether a remote is valid
  Allow programs to not depend on remotes having urls
  Fix memory leak in helper method for disconnect

Conflicts:
	Documentation/git-remote-helpers.txt
	Makefile
	builtin-ls-remote.c
	builtin-push.c
	transport-helper.c
2009-12-26 14:03:16 -08:00
Junio C Hamano 65c042d44d Merge branch 'bg/fetch-multi'
* bg/fetch-multi:
  Re-implement 'git remote update' using 'git fetch'
  builtin-fetch: add --dry-run option
  builtin-fetch: add --prune option
  teach warn_dangling_symref to take a FILE argument
  remote: refactor some logic into get_stale_heads()
  Add missing test for 'git remote update --prune'
  Add the configuration option skipFetchAll
  Teach the --multiple option to 'git fetch'
  Teach the --all option to 'git fetch'
2009-11-23 00:03:15 -08:00
Daniel Barkalow 72ff894308 Allow helper to map private ref names into normal names
This allows a helper to say that, when it handles "import
refs/heads/topic", the script it outputs will actually write to
refs/svn/origin/branches/topic; therefore, transport-helper should
read it from the latter location after git-fast-import completes.

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-11-17 21:45:44 -08:00
Daniel Barkalow c578f51d52 Add a config option for remotes to specify a foreign vcs
If this is set, the url is not required, and the transport always uses
a helper named "git-remote-<value>".

It is a separate configuration option in order to allow a sensible
configuration for foreign systems which either have no meaningful urls
for repositories or which require urls that do not specify the system
used by the repository at that location. However, this only affects
how the name of the helper is determined, not anything about the
interaction with the helper, and the contruction is such that, if the
foreign scm does happen to use a co-named url method, a url with that
method may be used directly.

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>
2009-11-17 21:45:44 -08:00
Daniel Barkalow 0a4da29dd8 Use a function to determine whether a remote is valid
Currently, it only checks url, but it will allow other things in the future.

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-11-17 21:45:44 -08:00
Julian Phillips 95c96d48e6 remote: fix use-after-free error detected by glibc in ref_remove_duplicates
In ref_remove_duplicates, when we encounter a duplicate and remove it
from the list we need to make sure that the prev pointer stays
pointing at the last entry and also skip over adding the just freed
entry to the string_list.

Previously fetch could crash with:
*** glibc detected *** git: corrupted double-linked list: ...

Also add a test to try and catch problems with duplicate removal in
the future.

Acked-by: Nicolas Pitre <nico@fluxnic.net>
Signed-off-by: Julian Phillips <julian@quantumfyre.co.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-11-14 16:03:06 -08:00
Jay Soffian f2ef6075c9 remote: refactor some logic into get_stale_heads()
Move the logic in builtin-remote.c which determines which local heads are stale
to remote.c so it can be used by other builtins.

Signed-off-by: Jay Soffian <jaysoffian@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-11-10 01:01:22 -08:00
Björn Gustavsson 7cc91a2f71 Add the configuration option skipFetchAll
Implement the configuration skipFetchAll option to allow
certain remotes to be skipped when doing 'git fetch --all' and
'git remote update'. The existing skipDefaultUpdate variable
is still honored (by 'git fetch --all' and 'git remote update').
(If both are set in the configuration file with different values,
the value of the last occurrence will be used.)

Signed-off-by: Björn Gustavsson <bgustavsson@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-11-10 01:01:07 -08:00
Julian Phillips 73cf0822b2 remote: Make ref_remove_duplicates faster for large numbers of refs
The ref_remove_duplicates function was very slow at dealing with very
large numbers of refs.  This is because it was using a linear search
through all remaining refs to find any duplicates of the current ref.

Rewriting it to use a string list to keep track of which refs have
already been seen and removing duplicates when they are found is much
more efficient.

Signed-off-by: Julian Phillips <julian@quantumfyre.co.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-10-27 23:38:43 -07: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
Josh Triplett d071d94296 Wrap rewrite globals in a struct in preparation for adding another set
remote.c has a global set of URL rewrites, accessed by alias_url and
make_rewrite.  Wrap them in a new "struct rewrites", passed to alias_url
and make_rewrite.  This allows adding other sets of rewrites.

Signed-off-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-09-07 12:58:45 -07:00
Brian Gianforcaro eeefa7c90e Style fixes, add a space after if/for/while.
The majority of code in core git appears to use a single
space after if/for/while. This is an attempt to bring more
code to this standard. These are entirely cosmetic changes.

Signed-off-by: Brian Gianforcaro <b.gianfo@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-08-31 23:26:28 -07:00
Junio C Hamano 864cd94917 Merge branch 'cb/maint-fetch-refspec-wo-dst'
* cb/maint-fetch-refspec-wo-dst:
  fetch: do not create ref from empty name
2009-07-06 09:39:38 -07:00
Linus Torvalds 2af202be3d Fix various sparse warnings in the git source code
There are a few remaining ones, but this fixes the trivial ones. It boils
down to two main issues that sparse complains about:

 - warning: Using plain integer as NULL pointer

   Sparse doesn't like you using '0' instead of 'NULL'. For various good
   reasons, not the least of which is just the visual confusion. A NULL
   pointer is not an integer, and that whole "0 works as NULL" is a
   historical accident and not very pretty.

   A few of these remain: zlib is a total mess, and Z_NULL is just a 0.
   I didn't touch those.

 - warning: symbol 'xyz' was not declared. Should it be static?

   Sparse wants to see declarations for any functions you export. A lack
   of a declaration tends to mean that you should either add one, or you
   should mark the function 'static' to show that it's in file scope.

   A few of these remain: I only did the ones that should obviously just
   be made static.

That 'wt_status_submodule_summary' one is debatable. It has a few related
flags (like 'wt_status_use_color') which _are_ declared, and are used by
builtin-commit.c. So maybe we'd like to export it at some point, but it's
not declared now, and not used outside of that file, so 'static' it is in
this patch.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-20 21:52:55 -07:00
Junio C Hamano deded16d15 Merge branch 'mg/pushurl'
* mg/pushurl:
  avoid NULL dereference on failed malloc
  builtin-remote: Make "remote -v" display push urls
  builtin-remote: Show push urls as well
  technical/api-remote: Describe new struct remote member pushurl
  t5516: Check pushurl config setting
  Allow push and fetch urls to be different
2009-06-20 21:47:27 -07:00
Clemens Buchacher 3eb9699733 fetch: do not create ref from empty name
Previously, the refspec "<src>:" would be expanded to
"<src>:refs/heads/". Instead, treat an empty <dst> just like refspecs
without a colon.

Signed-off-by: Clemens Buchacher <drizzd@aon.at>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-18 09:55:34 -07:00
Junio C Hamano 57c57a97e1 Merge branch 'cb/match_refs_internal_tail'
* cb/match_refs_internal_tail:
  match_refs: search ref list tail internally
2009-06-13 12:47:52 -07:00
Michael J Gruber 203462347f Allow push and fetch urls to be different
This introduces a config setting remote.$remotename.pushurl which is
used for pushes only. If absent remote.$remotename.url is used for
pushes and fetches as before.
This is useful, for example, in order to do passwordless fetches
(remote update) over the git transport but pushes over ssh.

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
Clemens Buchacher 6d2bf96e55 match_refs: search ref list tail internally
Avoid code duplication by moving list tail search to match_refs().

This does not change the semantics, except for http-push, which now inserts
to the front of the ref list in order to get rid of the global remote_tail.

Signed-off-by: Clemens Buchacher <drizzd@aon.at>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-01 19:41:24 -07:00
Junio C Hamano c9a88deede Merge branch 'mg/track'
* mg/track:
  Fix behavior with non-commit upstream references
  Test tracking of non-commit upstreams
2009-05-23 01:44:00 -07:00
Michael J Gruber 57ffc5f85a Fix behavior with non-commit upstream references
stat_tracking_info() assumes that upstream references (as specified by
--track or set up automatically) are commits. By calling lookup_commit()
on them, create_objects() creates objects for them with type commit no
matter what their real type is; this disturbs lookup_tag() later on in the
call sequence, leading to git status, git branch -v  and git checkout
erroring out.

Fix this by using lookup_commit_reference() instead so that (annotated)
tags can be used as upstream references.

Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-05-14 09:43:54 -07:00
Johannes Sixt cd294bc3f3 remote.c: do not trigger remote.<name>.<var> codepath for two-level names
If the config file contains a section like this:

    [remote]
            default = foo

(it should be '[remotes]') then commands like

    git status
    git checkout
    git branch -v

fail even though they are not obviously related to remotes. (These
commands write "ahead, behind" information and, therefore, access the
per-remote information).

Unknown configuration keys should be ignored, not trigger errors.

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-24 01:29:28 -07:00
Junio C Hamano 8fbf879ed7 Revert "stat_tracking_info(): only count real commits"
This reverts commit 19de5d6913.
It produces a misleading output to decide if a merge can fast-forward.
2009-04-21 16:33:20 -07:00
Junio C Hamano a9b772a011 Merge branch 'bw/short-ref-strict'
* bw/short-ref-strict:
  remote.c: use shorten_unambiguous_ref
  rev-parse: --abbrev-ref option to shorten ref name
  for-each-ref: utilize core.warnAmbiguousRefs for :short-format
  shorten_unambiguous_ref(): add strict mode
2009-04-17 21:42:12 -07:00
Michael J Gruber 45972ffbed remote.c: use shorten_unambiguous_ref
Use the new shorten_unambiguous_ref() for simplifying the output of
upstream branch names. This affects status and checkout.

Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-17 20:53:19 -07:00
Nguyễn Thái Ngọc Duy 55f0566f6d get_local_heads(): do not return random pointer if there is no head
it's silly to do this:

mkdir foo && cd foo && git init && git push somewhere.git

but segfault should not happen even in that case.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-17 20:48:32 -07:00
Junio C Hamano c276857ee2 Merge branch 'fg/remote-prune'
* fg/remote-prune:
  add tests for remote groups
  git remote update: Fallback to remote if group does not exist
  remote: New function remote_is_configured()
  git remote update: Report error for non-existing groups
  git remote update: New option --prune
  builtin-remote.c: Split out prune_remote as a separate function.
2009-04-12 16:46:41 -07:00
Finn Arne Gangstad 9a23ba3375 remote: New function remote_is_configured()
Previously, there was no easy way to check for the existence of a
configured remote. remote_get for example would always create the remote
"on demand".

This new function returns 1 if the remote is configured, 0 otherwise.

Signed-off-by: Finn Arne Gangstad <finnag@pvv.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-07 21:51:59 -07:00
Junio C Hamano ccc852c377 Merge branch 'mg/tracked-local-branches'
* mg/tracked-local-branches:
  Make local branches behave like remote branches when --tracked
  Test for local branches being followed with --track
2009-04-06 00:42:31 -07:00
Junio C Hamano 988d9fd8a4 Merge branch 'kb/tracking-count-no-merges'
* kb/tracking-count-no-merges:
  stat_tracking_info(): only count real commits
2009-04-01 22:27:43 -07:00
Michael J Gruber 5e6e2b487e Make local branches behave like remote branches when --tracked
This makes sure that local branches, when followed using --track, behave
the same as remote ones (e.g. differences being reported by git status
and git checkout). This fixes 1 known failure.

The fix is done within branch_get(): The first natural candidate,
namely remote_find_tracking(), does not have all the necessary info
because in general there is no remote struct for '.', and we don't want
one because it would show up in other places as well.

branch_get(), on the other hand, has access to merge_names[] (in
addition to merge[]) and therefore can set up the followed branch
easily.

Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-01 15:48:30 -07:00
Junio C Hamano 8e50ada553 Merge branch 'xx/db-refspec-vs-js-remote'
* xx/db-refspec-vs-js-remote:
  Support '*' in the middle of a refspec
  Keep '*' in pattern refspecs
  Use the matching function to generate the match results
  Use a single function to match names against patterns
  Make clone parse the default refspec with the normal code
2009-03-20 14:30:00 -07:00
Junio C Hamano 9d5b05c6d5 Merge branch 'db/maint-missing-origin'
* db/maint-missing-origin:
  Remove total confusion from git-fetch and git-push
  Give error when no remote is configured
2009-03-17 18:58:41 -07:00
Junio C Hamano ca8a36e6e0 Merge branch 'js/remote-improvements'
* js/remote-improvements: (23 commits)
  builtin-remote.c: no "commented out" code, please
  builtin-remote: new show output style for push refspecs
  builtin-remote: new show output style
  remote: make guess_remote_head() use exact HEAD lookup if it is available
  builtin-remote: add set-head subcommand
  builtin-remote: teach show to display remote HEAD
  builtin-remote: fix two inconsistencies in the output of "show <remote>"
  builtin-remote: make get_remote_ref_states() always populate states.tracked
  builtin-remote: rename variables and eliminate redundant function call
  builtin-remote: remove unused code in get_ref_states
  builtin-remote: refactor duplicated cleanup code
  string-list: new for_each_string_list() function
  remote: make match_refs() not short-circuit
  remote: make match_refs() copy src ref before assigning to peer_ref
  remote: let guess_remote_head() optionally return all matches
  remote: make copy_ref() perform a deep copy
  remote: simplify guess_remote_head()
  move locate_head() to remote.c
  move duplicated ref_newer() to remote.c
  move duplicated get_local_heads() to remote.c
  ...

Conflicts:
	builtin-clone.c
2009-03-17 18:55:06 -07:00
Junio C Hamano 9326d49412 Remove total confusion from git-fetch and git-push
The config file is not the only place remotes are defined, and without
consulting .git/remotes and .git/branches, you won't know if "origin" is
configured by the user.  Don't give up too early and insult the user with
a wisecrack "Where do you want to fetch from today?"

The only thing the previous patch seems to want to prevent from happening
is a lazy "git fetch/push" that does not say where-from/to to produce an
error message 'origin not found', and we can do that by not letting
add_url_alias() to turn a nickname "origin" literally into a pathname
"origin" without changing the rest of the logic.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-03-16 00:35:09 -07:00
Benjamin Kramer 8e76bf3fc9 Remove unused assignments
These variables were always overwritten or the assigned
value was unused:

  builtin-diff-tree.c::cmd_diff_tree(): nr_sha1
  builtin-for-each-ref.c::opt_parse_sort(): sort_tail
  builtin-mailinfo.c::decode_header_bq(): in
  builtin-shortlog.c::insert_one_record(): len
  connect.c::git_connect(): path
  imap-send.c::v_issue_imap_cmd(): n
  pretty.c::pp_user_info(): filler
  remote::parse_refspec_internal(): llen

Signed-off-by: Benjamin Kramer <benny.kra@googlemail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-03-14 13:36:34 -07:00
Daniel Barkalow fa685bdf45 Give error when no remote is configured
When there's no explicitly-named remote, we use the remote specified
for the current branch, which in turn defaults to "origin". But it
this case should require the remote to actually be configured, and not
fall back to the path "origin".

Possibly, the config file's "remote = something" should require the
something to be a configured remote instead of a bare repository URL,
but we actually test with a bare repository URL.

In fetch, we were giving the sensible error message when coming up
with a URL failed, but this wasn't actually reachable, so move that
error up and use it when appropriate.

In push, we need a new error message, because the old one (formerly
unreachable without a lot of help) used the repo name, which was NULL.

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-03-10 23:14:20 -07:00
Junio C Hamano 5ad6b0252b Adjust js/remote-improvements and db/refspec-wildcard-in-the-middle
The latter topic changes the definition of how refspec's src and dst side
is stored in-core; it used to be that the asterisk for pattern was
omitted, but now it is included.  The former topic handcrafts an old style
refspec to feed the refspec matching machinery that lacks the asterisk and
triggers an error.

This resolves the semantic clash between the two topics early before they
need to be merged to integration branches.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-03-08 00:24:21 -08:00
Daniel Barkalow abd2bde78b Support '*' in the middle of a refspec
In order to keep the requirements strict, each * has to be a full path
component, and there may only be one * per side. This requirement is
enforced entirely by check_ref_format(); the matching implementation
will substitute the whatever matches the * in the lhs for the * in the
rhs.

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-03-07 12:19:28 -08:00
Daniel Barkalow 08fbdb3043 Keep '*' in pattern refspecs
In order to do anything more capable with refspecs, the first step is
to keep the entire input. Additionally, validate patterns by checking
for the ref matching the rules for a pattern as given by
check_ref_format(). This requires a slight change to
check_ref_format() to make it enforce the requirement that the '*'
immediately follow a '/'.

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-03-07 12:19:24 -08:00
Daniel Barkalow e928213fb4 Use the matching function to generate the match results
This puts all of the interpretation of the pattern representation in a
single function for easy manipulation.

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-03-07 12:19:21 -08:00
Daniel Barkalow a3c8423901 Use a single function to match names against patterns
This will help when the matching changes.

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-03-07 12:19:19 -08:00
Kjetil Barvik 19de5d6913 stat_tracking_info(): only count real commits
stat_tracking_info() in remote.c is used to collect the statistics to
be able to say (for instance) from the output of "git checkout':

  Your branch and 'foo' have diverged,
  and have X and Y different commit(s) each, respectively.

Currently X and Y also includes the count of merges.  This patch
excludes the merges from being counted.

Signed-off-by: Kjetil Barvik <barvik@broadpark.no>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-03-04 20:36:24 -08:00
Jeff King fbb074c253 remote: make guess_remote_head() use exact HEAD lookup if it is available
Our usual method for determining the ref pointed to by HEAD
is to compare HEAD's sha1 to the sha1 of all refs, trying to
find a unique match.

However, some transports actually get to look at HEAD
directly; we should make use of that information when it is
available.  Currently, only http remotes support this
feature.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Jay Soffian <jaysoffian@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-02-27 15:19:23 -08:00
Jay Soffian 5f48cb95aa remote: make match_refs() not short-circuit
match_refs() returns non-zero if there is an error in
match_explicit_refs(), without handling any remaining pattern ref specs.

Its existing callers exit upon receiving non-zero, so a partial result
is of no consequence to them; however a new caller, builtin-remote, is
interested in the complete result even if there are errors in
match_explicit_refs().

Signed-off-by: Jay Soffian <jaysoffian@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-02-27 15:19:08 -08:00
Jay Soffian cdf690e53b remote: make match_refs() copy src ref before assigning to peer_ref
In some instances, match_refs() sets the peer_ref field of refs in the
dst list such that it points to a ref in the src list. This prevents
callers from freeing both the src and dst lists, as doing so would cause
a double-free since free_refs() frees the peer_ref.

As well, the following configuration causes two refs in the dst list to
have the same peer_ref, which can also lead to a double-free:

  push = refs/heads/master:refs/heads/backup
  push = refs/heads/master:refs/heads/master

Existing callers of match_heads() call it only once and then terminate,
w/o ever bothering to free the src or dst lists, so this is not
currently a problem.

This patch modifies match_refs() to first copy any refs it plucks from
the src list before assigning them as a peer_ref. This allows
builtin-remote, a future caller, to free the src and dst lists.

Signed-off-by: Jay Soffian <jaysoffian@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-02-27 15:19:08 -08:00
Jay Soffian 4229f1fa32 remote: let guess_remote_head() optionally return all matches
Determining HEAD is ambiguous since it is done by comparing SHA1s.

In the case of multiple matches we return refs/heads/master if it
matches, else we return the first match we encounter. builtin-remote
needs all matches returned to it, so add a flag for it to request such.

To be simple and consistent, the return value is now a copy (including
peer_ref) of the matching refs.

Originally contributed by Jeff King along with the prior commit as a
single patch.

Signed-off-by: Jay Soffian <jaysoffian@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-02-27 15:08:17 -08:00
Jay Soffian 7b3db095d5 remote: make copy_ref() perform a deep copy
To ensure that copied refs can always be freed w/o causing a
double-free, make copy_ref() perform a deep copy.

Also have copy_ref() return NULL if asked to copy NULL to simplify
things for the caller.

Background: currently copy_ref() performs a shallow copy. This is fine
for current callers who never free the result and/or only copy refs
which contain NULL pointers. But copy_ref() is about to gain a new
caller (guess_remote_head()) which copies refs where peer_ref is not
NULL and the caller of guess_remote_head() will want to free the result.

Signed-off-by: Jay Soffian <jaysoffian@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-02-27 15:08:08 -08:00