commit 75bbb53178bc07949826c81f52ea9f5f042b43e4 from: Stefan Sperling date: Mon May 06 08:45:14 2024 UTC show hint about update -b if the user attempts to rebase a branch onto itself Specifically, when 'gut send' suggests 'fetch and rebase required', new users might try to use 'got fetch' directly followed by 'got rebase' without first updating the work tree to newly fetched commits. Got would then say "main is already based on main" without any hint for a way out. Hopefully, pointing users at the update -b command will make them search the manual for details. commit - ef4f8ddaffcf814c74e3e3d806e430aeea45d7e8 commit + 75bbb53178bc07949826c81f52ea9f5f042b43e4 blob - e00dd735e29a8c982aa31faed0b6cb120e11839e blob + b32ea7c37a6e4abe3ed85220602e1e8e24af6dc0 --- got/got.c +++ got/got.c @@ -11654,9 +11654,19 @@ cmd_rebase(int argc, char *argv[]) if (got_object_id_cmp(base_commit_id, yca_id) == 0) { struct got_pathlist_head paths; - printf("%s is already based on %s\n", - got_ref_get_name(branch), - got_worktree_get_head_ref_name(worktree)); + const char *branch_name = got_ref_get_name(branch); + const char *base = + got_worktree_get_head_ref_name(worktree); + + if (strcmp(branch_name, base) == 0) { + error = got_error_fmt(GOT_ERR_WRONG_BRANCH, + "cannot rebase %s onto itself", + branch_name); + goto done; + } else { + printf("%s is already based on %s\n", + branch_name, base); + } error = switch_head_ref(branch, branch_head_commit_id, worktree, repo); if (error) blob - 591ee66b8e3d659624ea402adc5cac155bfd6e21 blob + 43420d51963fb8796ed7148130020e3b879a4c8a --- include/got_error.h +++ include/got_error.h @@ -100,7 +100,7 @@ #define GOT_ERR_BRANCH_EXISTS 83 #define GOT_ERR_MODIFIED 84 #define GOT_ERR_NOT_REBASING 85 -/* 86 is currently unused */ +#define GOT_ERR_WRONG_BRANCH 86 #define GOT_ERR_REBASE_COMMITID 87 #define GOT_ERR_REBASING 88 #define GOT_ERR_REBASE_PATH 89 blob - 711d2054736f85896487ec6f2e7ed54fa6a56048 blob + 3e65ec158b7f496672f8134c31836cb0f31eb628 --- lib/error.c +++ lib/error.c @@ -131,6 +131,7 @@ static const struct got_error got_errors[] = { "changes must be committed or reverted first" }, { GOT_ERR_NOT_REBASING, "rebase operation not in progress" }, { GOT_ERR_REBASE_COMMITID,"rebase commit ID mismatch" }, + { GOT_ERR_WRONG_BRANCH, "update -b required" }, { GOT_ERR_REBASING, "a rebase operation is in progress in this " "work tree and must be continued or aborted first" }, { GOT_ERR_REBASE_PATH, "cannot rebase branch which contains " blob - fae088133932111b4944a156b5ea1ac14d52df37 blob + fdc97d042d96cc880bf32dab15045285d6a80e27 --- regress/cmdline/rebase.sh +++ regress/cmdline/rebase.sh @@ -47,6 +47,19 @@ test_rebase_basic() { return 1 fi + (cd $testroot/wt && got rebase master > $testroot/stdout \ + 2> $testroot/stderr) + echo -n "got: cannot rebase refs/heads/master onto itself: " \ + > $testroot/stderr.expected + echo "update -b required" >> $testroot/stderr.expected + cmp -s $testroot/stderr.expected $testroot/stderr + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stderr.expected $testroot/stderr + test_done "$testroot" "$ret" + return 1 + fi + (cd $testroot/wt && got rebase newbranch > $testroot/stdout) git -C $testroot/repo checkout -q newbranch