summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/git-pull.txt6
-rwxr-xr-xgit-pull.sh12
-rwxr-xr-xt/t5520-pull.sh17
3 files changed, 33 insertions, 2 deletions
diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt
index f9f1e0d..4cc633a 100644
--- a/Documentation/git-pull.txt
+++ b/Documentation/git-pull.txt
@@ -35,7 +35,11 @@ include::urls-remotes.txt[]
include::merge-strategies.txt[]
\--rebase::
- Instead of a merge, perform a rebase after fetching.
+ Instead of a merge, perform a rebase after fetching. If
+ there is a remote ref for the upstream branch, and this branch
+ was rebased since last fetched, the rebase uses that information
+ to avoid rebasing non-local changes.
+
*NOTE:* This is a potentially _dangerous_ mode of operation.
It rewrites history, which does not bode well when you
published that history already. Do *not* use this option
diff --git a/git-pull.sh b/git-pull.sh
index fa97b0f..46da0f4 100755
--- a/git-pull.sh
+++ b/git-pull.sh
@@ -106,6 +106,15 @@ error_on_no_merge_candidates () {
exit 1
}
+test true = "$rebase" && {
+ . git-parse-remote &&
+ origin="$1"
+ test -z "$origin" && origin=$(get_default_remote)
+ reflist="$(get_remote_refs_for_fetch "$@" 2>/dev/null |
+ sed "s|refs/heads/\(.*\):|\1|")" &&
+ oldremoteref="$(git rev-parse --verify \
+ "refs/remotes/$origin/$reflist" 2>/dev/null)"
+}
orig_head=$(git rev-parse --verify HEAD 2>/dev/null)
git-fetch --update-head-ok "$@" || exit 1
@@ -164,6 +173,7 @@ then
fi
merge_name=$(git fmt-merge-msg <"$GIT_DIR/FETCH_HEAD") || exit
-test true = "$rebase" && exec git-rebase $merge_head
+test true = "$rebase" &&
+ exec git-rebase --onto $merge_head ${oldremoteref:-$merge_head}
exec git-merge $no_summary $no_commit $squash $no_ff $strategy_args \
"$merge_name" HEAD $merge_head
diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh
index 52b3a0c..9484129 100755
--- a/t/t5520-pull.sh
+++ b/t/t5520-pull.sh
@@ -71,8 +71,25 @@ test_expect_success 'branch.to-rebase.rebase' '
git reset --hard before-rebase &&
git config branch.to-rebase.rebase 1 &&
git pull . copy &&
+ git config branch.to-rebase.rebase 0 &&
test $(git rev-parse HEAD^) = $(git rev-parse copy) &&
test new = $(git show HEAD:file2)
'
+test_expect_success '--rebase with rebased upstream' '
+
+ git remote add -f me . &&
+ git checkout copy &&
+ git reset --hard HEAD^ &&
+ echo conflicting modification > file &&
+ git commit -m conflict file &&
+ git checkout to-rebase &&
+ echo file > file2 &&
+ git commit -m to-rebase file2 &&
+ git pull --rebase me copy &&
+ test "conflicting modification" = "$(cat file)" &&
+ test file = $(cat file2)
+
+'
+
test_done