mirror of
https://github.com/git/git
synced 2024-08-25 02:35:46 +00:00
Fix pulling into the same branch.
When the "git pull" command updates the branch head you are currently on, before doing anything else, first update your index file and the working tree contents to that of the new branch head. Otherwise, the later resolving steps would think your index file is attempting to revert the change between the original head commit and the updated head commit. It uses two-tree fast-forward form of "read-tree -m -u" to prevent losing whatever local changes you may have in the working tree to do this update. I think this would at least make things safer (a lot safer), and prevent mistakes. Also "git fetch" command is forbidden from fetching and fast forwarding the current branch head unless --update-head-ok flag is given. "git pull" passes the flag when it internally calls "git fetch". Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
parent
90bc118fc5
commit
b10ac50f1e
|
@ -7,28 +7,33 @@ _x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
|
||||||
|
|
||||||
append=
|
append=
|
||||||
force=
|
force=
|
||||||
|
update_head_ok=
|
||||||
while case "$#" in 0) break ;; esac
|
while case "$#" in 0) break ;; esac
|
||||||
do
|
do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
-a|--a|--ap|--app|--appe|--appen|--append)
|
-a|--a|--ap|--app|--appe|--appen|--append)
|
||||||
append=t
|
append=t
|
||||||
shift
|
|
||||||
;;
|
;;
|
||||||
-f|--f|--fo|--for|--forc|--force)
|
-f|--f|--fo|--for|--forc|--force)
|
||||||
force=t
|
force=t
|
||||||
shift
|
;;
|
||||||
|
-u|--u|--up|--upd|--upda|--updat|--update|--update-|--update-h|\
|
||||||
|
--update-he|--update-hea|--update-head|--update-head-|\
|
||||||
|
--update-head-o|--update-head-ok)
|
||||||
|
update_head_ok=t
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
break
|
break
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
shift
|
||||||
done
|
done
|
||||||
|
|
||||||
case "$#" in
|
case "$#" in
|
||||||
0)
|
0)
|
||||||
test -f "$GIT_DIR/branches/origin" ||
|
test -f "$GIT_DIR/branches/origin" ||
|
||||||
test -f "$GIT_DIR/remotes/origin" ||
|
test -f "$GIT_DIR/remotes/origin" ||
|
||||||
die "Where do you want to fetch from?"
|
die "Where do you want to fetch from today?"
|
||||||
set origin ;;
|
set origin ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
@ -124,6 +129,12 @@ fast_forward_local () {
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "$update_head_ok" in
|
||||||
|
'')
|
||||||
|
orig_head=$(cat "$GIT_DIR/HEAD" 2>/dev/null)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
for ref in $(get_remote_refs_for_fetch "$@")
|
for ref in $(get_remote_refs_for_fetch "$@")
|
||||||
do
|
do
|
||||||
refs="$refs $ref"
|
refs="$refs $ref"
|
||||||
|
@ -150,7 +161,7 @@ do
|
||||||
fi
|
fi
|
||||||
head=$(curl -nsf $curl_extra_args "$remote/$remote_name") &&
|
head=$(curl -nsf $curl_extra_args "$remote/$remote_name") &&
|
||||||
expr "$head" : "$_x40\$" >/dev/null ||
|
expr "$head" : "$_x40\$" >/dev/null ||
|
||||||
die "Failed to fetch $remote_name from $remote"
|
die "Failed to fetch $remote_name from $remote"
|
||||||
echo Fetching "$remote_name from $remote" using http
|
echo Fetching "$remote_name from $remote" using http
|
||||||
git-http-pull -v -a "$head" "$remote/" || exit
|
git-http-pull -v -a "$head" "$remote/" || exit
|
||||||
;;
|
;;
|
||||||
|
@ -201,3 +212,18 @@ http://* | https://* | rsync://* )
|
||||||
done
|
done
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
# If the original head was empty (i.e. no "master" yet), or
|
||||||
|
# if we were told not to worry, we do not have to check.
|
||||||
|
case ",$update_head_ok,$orig_head," in
|
||||||
|
*,, | t,* )
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
curr_head=$(cat "$GIT_DIR/HEAD" 2>/dev/null)
|
||||||
|
if test "$curr_head" != "$orig_head"
|
||||||
|
then
|
||||||
|
echo "$orig_head" >$GIT_DIR/HEAD
|
||||||
|
die "Cannot fetch into the current branch."
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
|
@ -5,7 +5,25 @@
|
||||||
# Fetch one or more remote refs and merge it/them into the current HEAD.
|
# Fetch one or more remote refs and merge it/them into the current HEAD.
|
||||||
|
|
||||||
. git-sh-setup-script || die "Not a git archive"
|
. git-sh-setup-script || die "Not a git archive"
|
||||||
git-fetch-script "$@" || exit 1
|
|
||||||
|
orig_head=$(cat "$GIT_DIR/HEAD") || die "Pulling into a black hole?"
|
||||||
|
git-fetch-script --update-head-ok "$@" || exit 1
|
||||||
|
|
||||||
|
curr_head=$(cat "$GIT_DIR/HEAD")
|
||||||
|
if test "$curr_head" != "$orig_head"
|
||||||
|
then
|
||||||
|
# The fetch involved updating the current branch.
|
||||||
|
|
||||||
|
# The working tree and the index file is still based on the
|
||||||
|
# $orig_head commit, but we are merging into $curr_head.
|
||||||
|
# First update the working tree to match $curr_head.
|
||||||
|
|
||||||
|
echo >&2 "Warning: fetch updated the current branch head."
|
||||||
|
echo >&2 "Warning: fast forwarding your working tree."
|
||||||
|
git-read-tree -u -m "$orig_head" "$curr_head" ||
|
||||||
|
die "You need to first update your working tree."
|
||||||
|
fi
|
||||||
|
|
||||||
merge_head=$(sed -e 's/ .*//' "$GIT_DIR"/FETCH_HEAD | tr '\012' ' ')
|
merge_head=$(sed -e 's/ .*//' "$GIT_DIR"/FETCH_HEAD | tr '\012' ' ')
|
||||||
merge_name=$(sed -e 's/^[0-9a-f]* //' "$GIT_DIR"/FETCH_HEAD |
|
merge_name=$(sed -e 's/^[0-9a-f]* //' "$GIT_DIR"/FETCH_HEAD |
|
||||||
tr '\012' ' ')
|
tr '\012' ' ')
|
||||||
|
|
Loading…
Reference in a new issue