Gentoo Archives: gentoo-dev

From: "Michał Górny" <mgorny@g.o>
To: gentoo-dev@l.g.o
Cc: "Michał Górny" <mgorny@g.o>
Subject: [gentoo-dev] [PATCH git-r3 03/10] Properly support non-master default branch.
Date: Wed, 26 Feb 2014 12:00:48
Message-Id: 1393415954-19313-3-git-send-email-mgorny@gentoo.org
In Reply to: [gentoo-dev] [PATCHES git-r3] Clean up and different clone type support by "Michał Górny"
1 Long story short, our HEAD was set by 'git init' and left at the default
2 'master'. So whenever we hit a repository that used a different default
3 branch, we either fetched the wrong branch or failed completely.
4
5 Using 'git clone' would fix the issue only temporarily since it does not
6 provide a way to follow changes of the 'HEAD' branch. git has some code
7 to obtain symbolic 'HEAD' using some of the transports but it seems not
8 to be part of the command-line API.
9
10 So instead, we do pretty much the same as 'git clone' does when it is
11 unable to get the symbolic HEAD from remote. We find the branch that is
12 on the same commit as HEAD, preferably 'master'.
13
14 As a note: we need to fetch into a custom ref since git does not allow
15 fetching to 'HEAD' directly. In fact, 'git fetch HEAD:HEAD' only creates
16 a branch named 'HEAD', and 'git fetch --prune HEAD:HEAD' creates and
17 removes it ;).
18 ---
19 eclass/git-r3.eclass | 42 ++++++++++++++++++++++++++++++++++++++++++
20 1 file changed, 42 insertions(+)
21
22 diff --git a/eclass/git-r3.eclass b/eclass/git-r3.eclass
23 index 892ed07..7c78b66 100644
24 --- a/eclass/git-r3.eclass
25 +++ b/eclass/git-r3.eclass
26 @@ -270,6 +270,42 @@ _git-r3_is_local_repo() {
27 [[ ${uri} == file://* || ${uri} == /* ]]
28 }
29
30 +# @FUNCTION: _git-r3_update_head
31 +# @USAGE: <remote-head-ref>
32 +# @INTERNAL
33 +# @DESCRIPTION:
34 +# Given a ref to which remote HEAD was fetched, try to match
35 +# a local branch and update symbolic HEAD appropriately.
36 +_git-r3_update_head()
37 +{
38 + debug-print-function ${FUNCNAME} "$@"
39 +
40 + local head_ref=${1}
41 + local head_hash=$(git rev-parse --verify ${1} || die)
42 + local matching_ref
43 +
44 + # TODO: some transports support peeking at symbolic remote refs
45 + # find a way to use that rather than guessing
46 +
47 + # (based on guess_remote_head() in git-1.9.0/remote.c)
48 + local h ref
49 + while read h ref; do
50 + # look for matching head
51 + if [[ ${h} == ${head_hash} ]]; then
52 + # either take the first matching ref, or master if it is there
53 + if [[ ! ${matching_ref} || ${ref} == refs/heads/master ]]; then
54 + matching_ref=${ref}
55 + fi
56 + fi
57 + done < <(git show-ref --heads || die)
58 +
59 + if [[ ! ${matching_ref} ]]; then
60 + die "Unable to find a matching branch for remote HEAD (${head_hash})"
61 + fi
62 +
63 + git symbolic-ref HEAD "${matching_ref}" || die
64 +}
65 +
66 # @FUNCTION: git-r3_fetch
67 # @USAGE: [<repo-uri> [<remote-ref> [<local-id>]]]
68 # @DESCRIPTION:
69 @@ -335,11 +371,17 @@ git-r3_fetch() {
70 "refs/tags/*:refs/tags/*"
71 # notes in case something needs them
72 "refs/notes/*:refs/notes/*"
73 + # and HEAD in case we need the default branch
74 + # (we keep it in refs/git-r3 since otherwise --prune interferes)
75 + HEAD:refs/git-r3/HEAD
76 )
77
78 set -- "${fetch_command[@]}"
79 echo "${@}" >&2
80 if "${@}"; then
81 + # find remote HEAD and update our HEAD properly
82 + _git-r3_update_head refs/git-r3/HEAD
83 +
84 # now let's see what the user wants from us
85 local full_remote_ref=$(
86 git rev-parse --verify --symbolic-full-name "${remote_ref}"
87 --
88 1.8.3.2

Replies