commit - 7ccf82596168ce763ab082e181aae83836ebdc23
commit + a1fb16d88f6904f90545c864be8d12c6ea9753b0
blob - ebb4bbf8fb93d5fdded2331a037f242e4bb76119
blob + f18db31b991c8c0ff10fc8f0d7545aa15e6ce2d2
--- got/got.1
+++ got/got.1
.Dl $ git checkout unified-buffer-cache
.Dl $ git rebase master
.Dl $ git push -f
-.Pp
-Create a new branch reference for a work tree which has lost
-linear ancestry with its recorded branch reference and thus
-can no longer be updated:
-.Pp
-.Dl $ got ref refs/heads/old-branch $(cat .got/base-commit)
-.Dl $ got update -b old-branch
.Pp
Update the work tree to the newly rebased
.Dq unified-buffer-cache
branch:
.Pp
.Dl $ got update -b unified-buffer-cache
-.Pp
-Delete a reference which is no longer needed:
-.Pp
-.Dl $ got ref -d refs/heads/old-branch
-.Pp
.Sh SEE ALSO
.Xr git-repository 5
.Xr got-worktree 5
blob - 4d034c8af70fd54a7de2623002e97255dca49eaf
blob + 16eef0039dc6d2261b9556a71753ea90319564b7
--- got/got.c
+++ got/got.c
}
static const struct got_error *
+switch_head_ref(struct got_reference *head_ref,
+ struct got_object_id *commit_id, struct got_worktree *worktree,
+ struct got_repository *repo)
+{
+ const struct got_error *err = NULL;
+ char *base_id_str;
+ int ref_has_moved = 0;
+
+ /* Trivial case: switching between two different references. */
+ if (strcmp(got_ref_get_name(head_ref),
+ got_worktree_get_head_ref_name(worktree)) != 0) {
+ printf("Switching work tree from %s to %s\n",
+ got_worktree_get_head_ref_name(worktree),
+ got_ref_get_name(head_ref));
+ return got_worktree_set_head_ref(worktree, head_ref);
+ }
+
+ err = check_linear_ancestry(commit_id,
+ got_worktree_get_base_commit_id(worktree), repo);
+ if (err) {
+ if (err->code != GOT_ERR_ANCESTRY)
+ return err;
+ ref_has_moved = 1;
+ }
+ if (!ref_has_moved)
+ return NULL;
+
+ /* Switching to a rebased branch with the same reference name. */
+ err = got_object_id_str(&base_id_str,
+ got_worktree_get_base_commit_id(worktree));
+ if (err)
+ return err;
+ printf("Reference %s now points at a different branch\n",
+ got_worktree_get_head_ref_name(worktree));
+ printf("Switching work tree from %s to %s\n", base_id_str,
+ got_worktree_get_head_ref_name(worktree));
+ return NULL;
+}
+
+static const struct got_error *
cmd_update(int argc, char *argv[])
{
const struct got_error *error = NULL;
if (error)
goto done;
- if (branch_name == NULL)
- branch_name = got_worktree_get_head_ref_name(worktree);
- error = got_ref_open(&head_ref, repo, branch_name, 0);
+ error = got_ref_open(&head_ref, repo, branch_name ? branch_name :
+ got_worktree_get_head_ref_name(worktree), 0);
if (error != NULL)
goto done;
if (commit_id_str == NULL) {
goto done;
}
- if (strcmp(got_ref_get_name(head_ref),
- got_worktree_get_head_ref_name(worktree)) != 0) {
+ if (branch_name) {
struct got_object_id *head_commit_id;
if (strlen(path) != 0) {
- fprintf(stderr, "%s: switching to a different "
- "branch requires that the entire work tree "
+ fprintf(stderr, "%s: switching between branches "
+ "requires that the entire work tree "
"gets updated, not just '%s'\n",
getprogname(), path);
error = got_error(GOT_ERR_BAD_PATH);
error = check_same_branch(commit_id, head_ref, repo);
if (error)
goto done;
- printf("Switching work tree from %s to %s\n",
- got_worktree_get_head_ref_name(worktree),
- got_ref_get_name(head_ref));
- error = got_worktree_set_head_ref(worktree, head_ref);
+ error = switch_head_ref(head_ref, commit_id, worktree, repo);
if (error)
goto done;
} else {
blob - 21b84dec550e11df0837e1b7f9dc20217e2463d3
blob + b5d808017aca17881058fa3c0276cc3ec7ed3381
--- include/got_error.h
+++ include/got_error.h
{ GOT_ERR_COMMIT_MSG_EMPTY, "commit message cannot be empty" },
{ GOT_ERR_DIR_NOT_EMPTY, "directory exists and is not empty" },
{ GOT_ERR_COMMIT_NO_CHANGES, "no changes to commit" },
- { GOT_ERR_BRANCH_MOVED, "work tree's branch reference has moved; "
- "new branch reference or rebase required" },
+ { GOT_ERR_BRANCH_MOVED, "work tree's head reference now points to a "
+ "different branch; new head reference and/or update -b required" },
{ GOT_ERR_OBJ_TOO_LARGE, "object too large" },
};
blob - 1e92b37d93b14ff994cbfaf3cf87b14e5ff846c5
blob + ab518679ea7cb4197f1beebbdeb2d17ff873976f
--- regress/cmdline/update.sh
+++ regress/cmdline/update.sh
(cd $testroot/repo2 && git fetch -q --all)
echo -n > $testroot/stdout.expected
- echo -n "got: work tree's branch reference has moved; " \
+ echo -n "got: work tree's head reference now points to a different " \
> $testroot/stderr.expected
- echo "new branch reference or rebase required" >> $testroot/stderr.expected
+ echo "branch; new head reference and/or update -b required" \
+ >> $testroot/stderr.expected
(cd $testroot/wt && got update > $testroot/stdout 2> $testroot/stderr)