From: "Santi Béjar" <sbejar@gmail.com>
To: Git Mailing List <git@vger.kernel.org>
Subject: [PATCH/RFC 2/3] git-fetch: Split fetch and merge logic
Date: Fri, 16 Feb 2007 09:09:30 +0100 [thread overview]
Message-ID: <87vei2o75x.fsf@gmail.com> (raw)
In-Reply-To: <874ppmplw7.fsf@gmail.com> (Santi Béjar's message of "Fri, 16 Feb 2007 09:06:00 +0100")
git-fetch fetches the branches from the remote and saves this
information in .git/FETCH_FETCHED, and at the end it generates
the file .git/FETCH_HEAD.
There are two cases where the behaviour is changed:
1) branch.*.merge no longer must exactly match the remote part
of the branch fetched. Both are expanded in full (as refs/heads/...)
and matched afterwards.
2) When the remote is specified with $GIT_DIR/branches/... and there is
a branch.*.merge, the remote branch name must match to get them merged.
Before the branch in $GIT_DIR/branches/... was always merged.
In the documentation the $GIT_DIR/branches/ is documented as a
short-hand for a corresponding file in $GIT_DIR/remotes/, so I think
this makes the new behaviour consistent.
Signed-off-by: Santi Béjar <sbejar@gmail.com>
---
Documentation/config.txt | 2 +-
git-fetch.sh | 74 ++++++++++++++++++++++++++-------------------
git-parse-remote.sh | 60 +++++++++----------------------------
t/t5510-fetch.sh | 16 ++++++++++
4 files changed, 75 insertions(+), 77 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 9620126..e695de5 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -238,7 +238,7 @@ branch.<name>.remote::
branch.<name>.merge::
When in branch <name>, it tells `git fetch` the default refspec to
- be marked for merging in FETCH_HEAD. The value has exactly to match
+ be marked for merging in FETCH_HEAD. The value has to match
a remote part of one of the refspecs which are fetched from the remote
given by "branch.<name>.remote".
The merge information is used by `git pull` (which at first calls
diff --git a/git-fetch.sh b/git-fetch.sh
index ca984e7..727538d 100755
--- a/git-fetch.sh
+++ b/git-fetch.sh
@@ -77,9 +77,9 @@ do
shift
done
+origin=$(get_default_remote)
case "$#" in
0)
- origin=$(get_default_remote)
test -n "$(get_remote_url ${origin})" ||
die "Where do you want to fetch from today?"
set x $origin ; shift ;;
@@ -101,6 +101,7 @@ if test "" = "$append"
then
: >"$GIT_DIR/FETCH_HEAD"
fi
+: >"$GIT_DIR/FETCH_FETCHED"
# Global that is reused later
ls_remote_result=$(git ls-remote $exec "$remote") ||
@@ -112,10 +113,6 @@ append_fetch_head () {
remote_name_="$3"
remote_nick_="$4"
local_name_="$5"
- case "$6" in
- t) not_for_merge_='not-for-merge' ;;
- '') not_for_merge_= ;;
- esac
# remote-nick is the URL given on the command line (or a shorthand)
# remote-name is the $GIT_DIR relative refs/ path we computed
@@ -146,9 +143,7 @@ append_fetch_head () {
if git-cat-file commit "$head_" >/dev/null 2>&1
then
headc_=$(git-rev-parse --verify "$head_^0") || exit
- echo "$headc_ $not_for_merge_ $note_" >>"$GIT_DIR/FETCH_HEAD"
- else
- echo "$head_ not-for-merge $note_" >>"$GIT_DIR/FETCH_HEAD"
+ echo "$headc_ $remote_name_:$local_name_ $note_" >>"$GIT_DIR/FETCH_FETCHED"
fi
update_local_ref "$local_name_" "$head_" "$note_"
@@ -256,7 +251,7 @@ then
git-show-ref --exclude-existing=refs/tags/ |
while read sha1 name
do
- echo ".${name}:${name}"
+ echo "${name}:${name}"
done` || exit
if test "$#" -gt 1
then
@@ -279,13 +274,6 @@ fetch_main () {
# These are relative path from $GIT_DIR, typically starting at refs/
# but may be HEAD
- if expr "z$ref" : 'z\.' >/dev/null
- then
- not_for_merge=t
- ref=$(expr "z$ref" : 'z\.\(.*\)')
- else
- not_for_merge=
- fi
if expr "z$ref" : 'z+' >/dev/null
then
single_force=t
@@ -366,7 +354,7 @@ fetch_main () {
esac
append_fetch_head "$head" "$remote" \
- "$remote_name" "$remote_nick" "$local_name" "$not_for_merge" || exit
+ "$remote_name" "$remote_nick" "$local_name" || exit
done
@@ -409,28 +397,16 @@ fetch_main () {
case "$ref" in
+$remote_name:*)
single_force=t
- not_for_merge=
- found="$ref"
- break ;;
- .+$remote_name:*)
- single_force=t
- not_for_merge=t
- found="$ref"
- break ;;
- .$remote_name:*)
- not_for_merge=t
found="$ref"
break ;;
$remote_name:*)
- not_for_merge=
found="$ref"
break ;;
esac
done
local_name=$(expr "z$found" : 'z[^:]*:\(.*\)')
append_fetch_head "$sha1" "$remote" \
- "$remote_name" "$remote_nick" "$local_name" \
- "$not_for_merge" || exit
+ "$remote_name" "$remote_nick" "$local_name" || exit
done
)
) || exit ;;
@@ -454,7 +430,7 @@ case "$no_tags$tags" in
do
git-cat-file -t "$sha1" >/dev/null 2>&1 || continue
echo >&2 "Auto-following $name"
- echo ".${name}:${name}"
+ echo "${name}:${name}"
done)
esac
case "$taglist" in
@@ -482,3 +458,39 @@ case "$orig_head" in
fi
;;
esac
+
+# Generate $GIT_DIR/FETCH_HEAD
+case ",$#,$remote_nick," in
+,1,$origin,)
+ curr_branch=$(git-symbolic-ref -q HEAD | sed -e 's|^refs/heads/||')
+ merge_branches=$(git-repo-config \
+ --get-all "branch.${curr_branch}.merge")
+ [ -z "$merge_branches" ] && merge_first=yes;;
+,1,$remote,) merge_branches=HEAD;;
+,1,*)merge_first=yes ;;
+*)
+ shift
+ merge_branches=$(for ref; do
+ expr "z$ref" : 'z.*:' >/dev/null || ref="${ref}:"
+ echo "$(expr "z$ref" : 'z\([^:]*\):')"; done);;
+esac
+
+test "$merge_first" == "yes" &&
+test "$(get_remote_default_refs_for_fetch -t $remote_nick)" != "explicit" &&
+merge_branches= && merge_first=
+
+merge_branches=$(canon_refs_list_for_fetch $merge_branches | sed 's/:.*$//g')
+
+cat "$GIT_DIR"/FETCH_FETCHED | while IFS=' ' read sha1 ref note ; do
+ remote_branch=$(expr "z$ref" : 'z\([^:]*\):')
+ for merge_branch in $merge_branches ; do
+ [ "$merge_branch" == "$remote_branch" ] &&
+ echo "$sha1 $note" && continue 2
+ done
+ if ! test "$merge_first" || test "$merge_first" == "done" ; then
+ echo "$sha1 not-for-merge $note"
+ else
+ echo "$sha1 $note"
+ merge_first=done
+ fi
+done >> "$GIT_DIR/FETCH_HEAD"
diff --git a/git-parse-remote.sh b/git-parse-remote.sh
index 5208ee6..212b3bc 100755
--- a/git-parse-remote.sh
+++ b/git-parse-remote.sh
@@ -70,8 +70,7 @@ get_remote_default_refs_for_push () {
esac
}
-# Called from canon_refs_list_for_fetch -d "$remote", which
-# is called from get_remote_default_refs_for_fetch to grok
+# Called from get_remote_default_refs_for_fetch to grok
# refspecs that are retrieved from the configuration, but not
# from get_remote_refs_for_fetch when it deals with refspecs
# supplied on the command line. $ls_remote_result has the list
@@ -130,30 +129,6 @@ expand_refs_wildcard () {
# Subroutine to canonicalize remote:local notation.
canon_refs_list_for_fetch () {
- # If called from get_remote_default_refs_for_fetch
- # leave the branches in branch.${curr_branch}.merge alone,
- # or the first one otherwise; add prefix . to the rest
- # to prevent the secondary branches to be merged by default.
- merge_branches=
- curr_branch=
- if test "$1" = "-d"
- then
- shift ; remote="$1" ; shift
- set $(expand_refs_wildcard "$remote" "$@")
- is_explicit="$1"
- shift
- if test "$remote" = "$(get_default_remote)"
- then
- curr_branch=$(git-symbolic-ref -q HEAD | \
- sed -e 's|^refs/heads/||')
- merge_branches=$(git-config \
- --get-all "branch.${curr_branch}.merge")
- fi
- if test -z "$merge_branches" && test $is_explicit != explicit
- then
- merge_branches=..this.will.never.match.any.ref..
- fi
- fi
for ref
do
force=
@@ -166,18 +141,6 @@ canon_refs_list_for_fetch () {
expr "z$ref" : 'z.*:' >/dev/null || ref="${ref}:"
remote=$(expr "z$ref" : 'z\([^:]*\):')
local=$(expr "z$ref" : 'z[^:]*:\(.*\)')
- dot_prefix=.
- if test -z "$merge_branches"
- then
- merge_branches=$remote
- dot_prefix=
- else
- for merge_branch in $merge_branches
- do
- [ "$remote" = "$merge_branch" ] &&
- dot_prefix= && break
- done
- fi
case "$remote" in
'' | HEAD ) remote=HEAD ;;
refs/heads/* | refs/tags/* | refs/remotes/*) ;;
@@ -196,32 +159,39 @@ canon_refs_list_for_fetch () {
git-check-ref-format "$local_ref_name" ||
die "* refusing to create funny ref '$local_ref_name' locally"
fi
- echo "${dot_prefix}${force}${remote}:${local}"
+ echo "${force}${remote}:${local}"
done
}
# Returns list of src: (no store), or src:dst (store)
get_remote_default_refs_for_fetch () {
+ test "$1" == -t && type=yes && shift
data_source=$(get_data_source "$1")
case "$data_source" in
'')
- echo "HEAD:" ;;
+ set explicit "HEAD:" ;;
config)
- canon_refs_list_for_fetch -d "$1" \
- $(git-config --get-all "remote.$1.fetch") ;;
+ set $(expand_refs_wildcard "$1" \
+ $(git-repo-config --get-all "remote.$1.fetch")) ;;
branches)
remote_branch=$(sed -ne '/#/s/.*#//p' "$GIT_DIR/branches/$1")
case "$remote_branch" in '') remote_branch=master ;; esac
- echo "refs/heads/${remote_branch}:refs/heads/$1"
+ set explicit "refs/heads/${remote_branch}:refs/heads/$1"
;;
remotes)
- canon_refs_list_for_fetch -d "$1" $(sed -ne '/^Pull: */{
+ set $(expand_refs_wildcard "$1" $(sed -ne '/^Pull: */{
s///p
- }' "$GIT_DIR/remotes/$1")
+ }' "$GIT_DIR/remotes/$1"))
;;
*)
die "internal error: get-remote-default-ref-for-push $1" ;;
esac
+ if [ "$type" ] ; then
+ echo $1
+ else
+ shift
+ canon_refs_list_for_fetch "$@"
+ fi
}
get_remote_refs_for_push () {
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index 50c6485..0a19a7d 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -50,6 +50,22 @@ test_expect_success "fetch test" '
test "z$mine" = "z$his"
'
+test_expect_success "fetch test fetched" '
+ cd "$D" &&
+ cd three &&
+ git fetch &&
+ test -f .git/refs/heads/two &&
+ test -f .git/refs/heads/one &&
+ master_in_two=`cd ../two && git rev-parse master` &&
+ one_in_two=`cd ../two && git rev-parse one` &&
+ {
+ echo "$master_in_two refs/heads/master:refs/heads/two"
+ echo "$one_in_two refs/heads/one:refs/heads/one"
+ } >expected &&
+ cut -f -2 .git/FETCH_FETCHED >actual &&
+ diff expected actual'
+
+
test_expect_success "fetch test for-merge" '
cd "$D" &&
cd three &&
--
1.5.0.35.gaaba
next prev parent reply other threads:[~2007-02-16 8:09 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-02-16 8:06 [PATCH/RFC 0/3] Split fetch and merge logic Santi Béjar
2007-02-16 8:09 ` Santi Béjar [this message]
2007-02-19 20:44 ` [PATCH/RFC 2/3] git-fetch: " Junio C Hamano
2007-02-19 22:13 ` Santi Béjar
2007-02-19 23:27 ` Junio C Hamano
2007-02-20 11:21 ` Santi Béjar
2007-02-16 8:10 ` [PATCH/RFC 3/3] t/t5515: fixes for the separate " Santi Béjar
2007-02-16 8:22 ` [PATCH/RFC 0/3] Split " Junio C Hamano
2007-02-16 8:40 ` Santi Béjar
2007-02-16 20:10 ` Junio C Hamano
2007-02-16 20:30 ` Santi Béjar
2007-02-16 21:14 ` Junio C Hamano
2007-02-19 9:47 ` Santi Béjar
[not found] ` <87zm7eo78x.fsf@gmail.com>
2007-02-16 8:23 ` [PATCH/RFC 1/3] t/t5515-fetch-merge-logic.sh: Added tests for the merge login in git-fetch Santi Béjar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87vei2o75x.fsf@gmail.com \
--to=sbejar@gmail.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).