Commit Diff


commit - 4cb8f8f3e6cc4a795c92823235070dd921c2b42e
commit + de05890fef951240ac68a3ea9a577a6f82be6194
blob - cd15a3ad1b8e6561f202dd4fef0869c1efdc5629
blob + 80f9b0ed32b5cf77045b2016ae220f3802661f48
--- include/got_error.h
+++ include/got_error.h
@@ -108,7 +108,7 @@
 #define GOT_ERR_NO_HISTEDIT_CMD	92
 #define GOT_ERR_HISTEDIT_SYNTAX	93
 #define GOT_ERR_HISTEDIT_CANCEL	94
-#define GOT_ERR_HISTEDIT_COMMITID 95
+/* 95 is currently unused */
 #define GOT_ERR_HISTEDIT_BUSY	96
 #define GOT_ERR_HISTEDIT_CMD	97
 #define GOT_ERR_HISTEDIT_PATH	98
@@ -238,7 +238,7 @@ static const struct got_error {
 	{ GOT_ERR_NO_HISTEDIT_CMD,"no histedit commands provided" },
 	{ GOT_ERR_HISTEDIT_SYNTAX,"syntax error in histedit command list" },
 	{ GOT_ERR_HISTEDIT_CANCEL,"histedit operation cancelled" },
-	{ GOT_ERR_HISTEDIT_COMMITID,"histedit commit ID mismatch" },
+	{ 95, "unused error code" },
 	{ GOT_ERR_HISTEDIT_BUSY,"histedit operation is in progress in this "
 	    "work tree and must be continued or aborted first" },
 	{ GOT_ERR_HISTEDIT_CMD, "bad histedit command" },
blob - 0e0bef70fa58ed856ec28833fae027d8744acaae
blob + c9da5df6a4a5a861d6cae4274f1237a6f0bc599f
--- lib/worktree.c
+++ lib/worktree.c
@@ -4980,7 +4980,7 @@ got_worktree_rebase_pathlist_free(struct got_pathlist_
 
 static const struct got_error *
 store_commit_id(const char *commit_ref_name, struct got_object_id *commit_id,
-    struct got_repository *repo)
+    int is_rebase, struct got_repository *repo)
 {
 	const struct got_error *err;
 	struct got_reference *commit_ref = NULL;
@@ -4995,7 +4995,7 @@ store_commit_id(const char *commit_ref_name, struct go
 		err = got_ref_write(commit_ref, repo);
 		if (err)
 			goto done;
-	} else {
+	} else if (is_rebase) {
 		struct got_object_id *stored_id;
 		int cmp;
 
@@ -5060,7 +5060,7 @@ got_worktree_rebase_merge_files(struct got_pathlist_he
 	if (err)
 		return err;
 
-	err = store_commit_id(commit_ref_name, commit_id, repo);
+	err = store_commit_id(commit_ref_name, commit_id, 1, repo);
 	if (err)
 		goto done;
 
@@ -5087,7 +5087,7 @@ got_worktree_histedit_merge_files(struct got_pathlist_
 	if (err)
 		return err;
 
-	err = store_commit_id(commit_ref_name, commit_id, repo);
+	err = store_commit_id(commit_ref_name, commit_id, 0, repo);
 	if (err)
 		goto done;
 
@@ -5263,7 +5263,6 @@ got_worktree_histedit_commit(struct got_object_id **ne
 	const struct got_error *err;
 	char *commit_ref_name;
 	struct got_reference *commit_ref = NULL;
-	struct got_object_id *commit_id = NULL;
 
 	err = get_histedit_commit_ref_name(&commit_ref_name, worktree);
 	if (err)
@@ -5272,13 +5271,6 @@ got_worktree_histedit_commit(struct got_object_id **ne
 	err = got_ref_open(&commit_ref, repo, commit_ref_name, 0);
 	if (err)
 		goto done;
-	err = got_ref_resolve(&commit_id, repo, commit_ref);
-	if (err)
-		goto done;
-	if (got_object_id_cmp(commit_id, orig_commit_id) != 0) {
-		err = got_error(GOT_ERR_HISTEDIT_COMMITID);
-		goto done;
-	}
 
 	err = rebase_commit(new_commit_id, merged_paths, commit_ref,
 	    worktree, fileindex, tmp_branch, orig_commit, new_logmsg, repo);
@@ -5286,7 +5278,6 @@ done:
 	if (commit_ref)
 		got_ref_close(commit_ref);
 	free(commit_ref_name);
-	free(commit_id);
 	return err;
 }
 
@@ -5882,7 +5873,7 @@ got_worktree_histedit_skip_commit(struct got_worktree 
 	if (err)
 		return err;
 
-	err = store_commit_id(commit_ref_name, commit_id, repo);
+	err = store_commit_id(commit_ref_name, commit_id, 0, repo);
 	if (err)
 		goto done;
 
blob - 30628b7335d56d07f5f457ffd0a6b1150e635785 (mode 755)
blob + 11f94a58d35bcb17bf7b8b76dbac1f166171cc58 (mode 744)
--- regress/cmdline/histedit.sh
+++ regress/cmdline/histedit.sh
@@ -1182,7 +1182,113 @@ function test_histedit_fold_last_commit_swap {
 	fi
 	test_done "$testroot" "$ret"
 }
+
+function test_histedit_split_commit {
+	local testroot=`test_init histedit_split_commit`
+
+	local orig_commit=`git_show_head $testroot/repo`
+
+	echo "modified alpha on master" > $testroot/repo/alpha
+	(cd $testroot/repo && git rm -q beta)
+	echo "new file on master" > $testroot/repo/epsilon/new
+	(cd $testroot/repo && git add epsilon/new)
+	git_commit $testroot/repo -m "committing changes 1"
+	local old_commit1=`git_show_head $testroot/repo`
+	local short_old_commit1=`trim_obj_id 28 $old_commit1`
+
+	echo "modified zeta on master" > $testroot/repo/epsilon/zeta
+	git_commit $testroot/repo -m "committing changes 2"
+	local old_commit2=`git_show_head $testroot/repo`
+	local short_old_commit2=`trim_obj_id 28 $old_commit2`
 
+	got checkout -c $orig_commit $testroot/repo $testroot/wt > /dev/null
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	# split commit1 into commitA and commitB and commitC
+	echo "e $old_commit1" > $testroot/histedit-script
+	echo "p $old_commit2" >> $testroot/histedit-script
+
+	(cd $testroot/wt && got histedit -F $testroot/histedit-script \
+		> $testroot/stdout 2> $testroot/stderr)
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		echo "histedit failed unexpectedly:" >&2
+		cat $testroot/stderr >&2
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	echo "G  alpha" > $testroot/stdout.expected
+	echo "D  beta" >> $testroot/stdout.expected
+	echo "A  epsilon/new" >> $testroot/stdout.expected
+	echo "Stopping histedit for amending commit $old_commit1" \
+		>> $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 ci -m "commitA" alpha >/dev/null)
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		echo "commit failed unexpectedly" >&2
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	(cd $testroot/wt && got ci -m "commitB" beta >/dev/null)
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		echo "commit failed unexpectedly" >&2
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	(cd $testroot/wt && got ci -m "commitC" epsilon/new >/dev/null)
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		echo "commit failed unexpectedly" >&2
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	(cd $testroot/wt && got histedit -c \
+		> $testroot/stdout 2> $testroot/stderr)
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		echo "histedit failed unexpectedly:" >&2
+		cat $testroot/stderr >&2
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+	local new_commit2=`git_show_head $testroot/repo`
+	local short_new_commit2=`trim_obj_id 28 $new_commit2`
+
+	echo "$short_old_commit1 -> no-op change: committing changes 1" \
+		> $testroot/stdout.expected
+	echo "G  epsilon/zeta" >> $testroot/stdout.expected
+	echo "$short_old_commit2 -> $short_new_commit2: committing changes 2" \
+		>> $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
+	fi
+	test_done "$testroot" "$ret"
+
+}
+
 run_test test_histedit_no_op
 run_test test_histedit_swap
 run_test test_histedit_drop
@@ -1195,3 +1301,4 @@ run_test test_histedit_path_prefix_drop
 run_test test_histedit_path_prefix_edit
 run_test test_histedit_outside_refs_heads
 run_test test_histedit_fold_last_commit_swap
+run_test test_histedit_split_commit