if there are no commits to rebase, just forward the rebased branch's reference Problem found by kn@
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
diff --git a/got/got.c b/got/got.c
index 5541936..9f40340 100644
--- a/got/got.c
+++ b/got/got.c
@@ -5447,12 +5447,27 @@ cmd_rebase(int argc, char *argv[])
goto done;
if (SIMPLEQ_EMPTY(&commits)) {
- if (continue_rebase)
+ if (continue_rebase) {
error = rebase_complete(worktree, fileindex,
branch, new_base_branch, tmp_branch, repo);
- else
- error = got_error(GOT_ERR_EMPTY_REBASE);
- goto done;
+ goto done;
+ } else {
+ /* Fast-forward the reference of the branch. */
+ struct got_object_id *new_head_commit_id;
+ char *id_str;
+ error = got_ref_resolve(&new_head_commit_id, repo,
+ new_base_branch);
+ if (error)
+ goto done;
+ error = got_object_id_str(&id_str, new_head_commit_id);
+ printf("Forwarding %s to commit %s\n",
+ got_ref_get_name(branch), id_str);
+ free(id_str);
+ error = got_ref_change_ref(branch,
+ new_head_commit_id);
+ if (error)
+ goto done;
+ }
}
pid = NULL;
diff --git a/regress/cmdline/rebase.sh b/regress/cmdline/rebase.sh
index 62a0455..e504cd7 100755
--- a/regress/cmdline/rebase.sh
+++ b/regress/cmdline/rebase.sh
@@ -780,6 +780,96 @@ function test_rebase_no_commits_to_rebase {
test_done "$testroot" "$ret"
}
+function test_rebase_forward {
+ local testroot=`test_init rebase_forward`
+ local commit0=`git_show_head $testroot/repo`
+
+ got checkout $testroot/repo $testroot/wt > /dev/null
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ echo "change alpha 1" > $testroot/wt/alpha
+ (cd $testroot/wt && got commit -m 'test rebase_forward' \
+ > /dev/null)
+ local commit1=`git_show_head $testroot/repo`
+
+ echo "change alpha 2" > $testroot/wt/alpha
+ (cd $testroot/wt && got commit -m 'test rebase_forward' \
+ > /dev/null)
+ local commit2=`git_show_head $testroot/repo`
+
+ # Simulate a situation where fast-forward is required.
+ # We want to fast-forward master to origin/master:
+ # commit 3907e11dceaae2ca7f8db79c2af31794673945ad (origin/master)
+ # commit ffcffcd102cf1af6572fbdbb4cf07a0f1fd2d840 (master)
+ # commit 87a6a8a2263a15b61c016ff1720b24741d455eb5
+ (cd $testroot/repo && got ref -d master)
+ (cd $testroot/repo && got ref refs/heads/master $commit1)
+ (cd $testroot/repo && got ref refs/remotes/origin/master $commit2)
+
+
+ (cd $testroot/wt && got up -b origin/master > /dev/null)
+
+ (cd $testroot/wt && got rebase master \
+ > $testroot/stdout 2> $testroot/stderr)
+
+ echo "Forwarding refs/heads/master to commit $commit2" \
+ > $testroot/stdout.expected
+ echo "Switching work tree to refs/heads/master" \
+ >> $testroot/stdout.expected
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ # Ensure that rebase operation was completed correctly
+ (cd $testroot/wt && got rebase -a \
+ > $testroot/stdout 2> $testroot/stderr)
+ echo -n "" > $testroot/stdout.expected
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+ echo "got: rebase operation not in progress" > $testroot/stderr.expected
+ cmp -s $testroot/stderr.expected $testroot/stderr
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stderr.expected $testroot/stderr
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ (cd $testroot/wt && got branch > $testroot/stdout)
+ echo "master" > $testroot/stdout.expected
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ (cd $testroot/wt && got log -l3 | grep ^commit > $testroot/stdout)
+ echo "commit $commit2 (master, origin/master)" > $testroot/stdout.expected
+ echo "commit $commit1" >> $testroot/stdout.expected
+ echo "commit $commit0" >> $testroot/stdout.expected
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ fi
+ test_done "$testroot" "$ret"
+}
+
run_test test_rebase_basic
run_test test_rebase_ancestry_check
run_test test_rebase_continue
@@ -789,3 +879,4 @@ run_test test_rebase_in_progress
run_test test_rebase_path_prefix
run_test test_rebase_preserves_logmsg
run_test test_rebase_no_commits_to_rebase
+run_test test_rebase_forward