"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Stefan Sperling <stsp@stsp.name>
Subject:
implicit update after rebase/histedit
To:
gameoftrees@openbsd.org
Date:
Mon, 14 Dec 2020 14:44:56 +0100

Download raw body.

Thread
  • Stefan Sperling:

    implicit update after rebase/histedit

After using 'got rebase' or 'got histedit', the next time the user wants
to perform an action which requires a fully up-to-date work tree (such as
rebasing another branch) Got will ask the user to run 'got update' first.

To make this easier we can implicitly mark all files in the work tree
as up-to-date after a successful rebase or histedit operation.
This should always be correct, since both operations start out with a
clean and single-base-commit worktree, and end up committing all changes
across the entire work tree when they are successful.

ok?

diff f5a09613ce18eb49de0d07d7f7a1dbd5dcac25c8 /home/stsp/src/got
blob - 91a87ba60ac2ebc61140d6778df16fc1e2f39016
file + lib/worktree.c
--- lib/worktree.c
+++ lib/worktree.c
@@ -2437,6 +2437,24 @@ bump_base_commit_id(void *arg, struct got_fileindex_en
 }
 
 static const struct got_error *
+bump_base_commit_id_everywhere(struct got_worktree *worktree,
+     struct got_fileindex *fileindex,
+     got_worktree_checkout_cb progress_cb, void *progress_arg)
+{
+	struct bump_base_commit_id_arg bbc_arg;
+
+	bbc_arg.base_commit_id = worktree->base_commit_id;
+	bbc_arg.entry_name = NULL;
+	bbc_arg.path = "";
+	bbc_arg.path_len = 0;
+	bbc_arg.progress_cb = progress_cb;
+	bbc_arg.progress_arg = progress_arg;
+
+	return got_fileindex_for_each_entry_safe(fileindex,
+	    bump_base_commit_id, &bbc_arg);
+}
+
+static const struct got_error *
 sync_fileindex(struct got_fileindex *fileindex, const char *fileindex_path)
 {
 	const struct got_error *err = NULL;
@@ -6437,8 +6455,9 @@ got_worktree_rebase_complete(struct got_worktree *work
     struct got_reference *tmp_branch, struct got_reference *rebased_branch,
     struct got_repository *repo)
 {
-	const struct got_error *err, *unlockerr;
+	const struct got_error *err, *unlockerr, *sync_err;
 	struct got_object_id *new_head_commit_id = NULL;
+	char *fileindex_path = NULL;
 
 	err = got_ref_resolve(&new_head_commit_id, repo, tmp_branch);
 	if (err)
@@ -6457,9 +6476,19 @@ got_worktree_rebase_complete(struct got_worktree *work
 		goto done;
 
 	err = delete_rebase_refs(worktree, repo);
+	if (err)
+		goto done;
+
+	err = get_fileindex_path(&fileindex_path, worktree);
+	if (err)
+		goto done;
+	err = bump_base_commit_id_everywhere(worktree, fileindex, NULL, NULL);
+	sync_err = sync_fileindex(fileindex, fileindex_path);
+	if (sync_err && err == NULL)
+		err = sync_err;
 done:
-	if (fileindex)
-		got_fileindex_free(fileindex);
+	got_fileindex_free(fileindex);
+	free(fileindex_path);
 	free(new_head_commit_id);
 	unlockerr = lock_worktree(worktree, LOCK_SH);
 	if (unlockerr && err == NULL)
@@ -6906,9 +6935,10 @@ got_worktree_histedit_complete(struct got_worktree *wo
     struct got_fileindex *fileindex, struct got_reference *tmp_branch,
     struct got_reference *edited_branch, struct got_repository *repo)
 {
-	const struct got_error *err, *unlockerr;
+	const struct got_error *err, *unlockerr, *sync_err;
 	struct got_object_id *new_head_commit_id = NULL;
 	struct got_reference *resolved = NULL;
+	char *fileindex_path = NULL;
 
 	err = got_ref_resolve(&new_head_commit_id, repo, tmp_branch);
 	if (err)
@@ -6932,9 +6962,19 @@ got_worktree_histedit_complete(struct got_worktree *wo
 		goto done;
 
 	err = delete_histedit_refs(worktree, repo);
+	if (err)
+		goto done;
+
+	err = get_fileindex_path(&fileindex_path, worktree);
+	if (err)
+		goto done;
+	err = bump_base_commit_id_everywhere(worktree, fileindex, NULL, NULL);
+	sync_err = sync_fileindex(fileindex, fileindex_path);
+	if (sync_err && err == NULL)
+		err = sync_err;
 done:
-	if (fileindex)
-		got_fileindex_free(fileindex);
+	got_fileindex_free(fileindex);
+	free(fileindex_path);
 	free(new_head_commit_id);
 	unlockerr = lock_worktree(worktree, LOCK_SH);
 	if (unlockerr && err == NULL)
blob - 3ba776626d052edc2f5f9848a2ce3491cf2c5109
file + regress/cmdline/histedit.sh
--- regress/cmdline/histedit.sh
+++ regress/cmdline/histedit.sh
@@ -132,7 +132,18 @@ test_histedit_no_op() {
 	ret="$?"
 	if [ "$ret" != "0" ]; then
 		diff -u $testroot/diff.expected $testroot/diff
+		test_done "$testroot" "$ret"
+		return 1
 	fi
+
+	(cd $testroot/wt && got update > $testroot/stdout)
+
+	echo 'Already up-to-date' > $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"
 }
 
blob - 6d48e72761668deed003b1cc1aaa9aa08f37a772
file + regress/cmdline/rebase.sh
--- regress/cmdline/rebase.sh
+++ regress/cmdline/rebase.sh
@@ -132,7 +132,18 @@ test_rebase_basic() {
 	ret="$?"
 	if [ "$ret" != "0" ]; then
 		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		return 1
 	fi
+
+	(cd $testroot/wt && got update > $testroot/stdout)
+
+	echo 'Already up-to-date' > $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"
 }