commit 38b0338bf913fd419054488e420e0aea644dcb62 from: Stefan Sperling date: Fri Nov 29 03:57:10 2019 UTC if there are no commits to rebase, just forward the rebased branch's reference Problem found by kn@ commit - cd95becd3d0ee4fb578daf570177c3550cb19e08 commit + 38b0338bf913fd419054488e420e0aea644dcb62 blob - 5541936d50a60c79cffb25e28117f4814c40512a blob + 9f403407a6f1173c7f605a66f2f04a512323bd71 --- got/got.c +++ 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; blob - 62a0455a66d4559f543efeddcfbe821bfa742d26 blob + e504cd7a19d54a0fb8ebb30ff394991576a092da --- regress/cmdline/rebase.sh +++ regress/cmdline/rebase.sh @@ -779,7 +779,97 @@ function test_rebase_no_commits_to_rebase { fi 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