Download raw body.
reset committer name during rebase and histedit
This makes the rebase and histedit commands reset committer name in newly created commits, based on author info found in the usual way. Before this change, the committer field was simply copied from the meta-data of each rebased/edited commit. It makes sense to reset this field when commits get passed on via someone else (this was suggested to me by jrick during r2k22). Also, this behaviour change is required to support server-side checks which ensure that a committer's name matches authentication credentials used to send commits. Which is something our own future server should probably do. ok? diff refs/heads/main refs/heads/reset-committer commit - f26cc5f2126442207cd94f69d093f159445e8e20 commit + 2b6152e714dff8c212da28a1a2daffb00435263c blob - 9f183e571635bf216c5457b05b5b7a35c77fa034 blob + af59edb11f59ce50cc07c7c94d5fb05a9acc0f54 --- got/got.c +++ got/got.c @@ -9578,7 +9578,7 @@ rebase_complete(struct got_worktree *worktree, struct static const struct got_error * rebase_commit(struct got_pathlist_head *merged_paths, struct got_worktree *worktree, struct got_fileindex *fileindex, - struct got_reference *tmp_branch, + struct got_reference *tmp_branch, const char *committer, struct got_object_id *commit_id, struct got_repository *repo) { const struct got_error *error; @@ -9590,7 +9590,8 @@ rebase_commit(struct got_pathlist_head *merged_paths, return error; error = got_worktree_rebase_commit(&new_commit_id, merged_paths, - worktree, fileindex, tmp_branch, commit, commit_id, repo); + worktree, fileindex, tmp_branch, committer, commit, commit_id, + repo); if (error) { if (error->code != GOT_ERR_COMMIT_NO_CHANGES) goto done; @@ -10016,7 +10017,7 @@ cmd_rebase(int argc, char *argv[]) struct got_worktree *worktree = NULL; struct got_repository *repo = NULL; struct got_fileindex *fileindex = NULL; - char *cwd = NULL; + char *cwd = NULL, *committer = NULL; struct got_reference *branch = NULL; struct got_reference *new_base_branch = NULL, *tmp_branch = NULL; struct got_object_id *commit_id = NULL, *parent_id = NULL; @@ -10122,6 +10123,10 @@ cmd_rebase(int argc, char *argv[]) if (error != NULL) goto done; + error = get_author(&committer, repo, worktree); + if (error) + goto done; + error = apply_unveil(got_repo_get_path(repo), 0, worktree ? got_worktree_get_root_path(worktree) : NULL); if (error) @@ -10189,7 +10194,7 @@ cmd_rebase(int argc, char *argv[]) goto done; error = rebase_commit(NULL, worktree, fileindex, tmp_branch, - resume_commit_id, repo); + committer, resume_commit_id, repo); if (error) goto done; @@ -10352,7 +10357,7 @@ cmd_rebase(int argc, char *argv[]) } error = rebase_commit(&merged_paths, worktree, fileindex, - tmp_branch, commit_id, repo); + tmp_branch, committer, commit_id, repo); got_worktree_rebase_pathlist_free(&merged_paths); if (error) goto done; @@ -10387,6 +10392,7 @@ cmd_rebase(int argc, char *argv[]) new_base_branch, tmp_branch, repo, create_backup); done: free(cwd); + free(committer); got_object_id_queue_free(&commits); free(branch_head_commit_id); free(resume_commit_id); @@ -11157,7 +11163,7 @@ static const struct got_error * histedit_commit(struct got_pathlist_head *merged_paths, struct got_worktree *worktree, struct got_fileindex *fileindex, struct got_reference *tmp_branch, struct got_histedit_list_entry *hle, - struct got_repository *repo) + const char *committer, struct got_repository *repo) { const struct got_error *err; struct got_commit_object *commit; @@ -11175,7 +11181,7 @@ histedit_commit(struct got_pathlist_head *merged_paths return err; err = got_worktree_histedit_commit(&new_commit_id, merged_paths, - worktree, fileindex, tmp_branch, commit, hle->commit_id, + worktree, fileindex, tmp_branch, committer, commit, hle->commit_id, hle->logmsg, repo); if (err) { if (err->code != GOT_ERR_COMMIT_NO_CHANGES) @@ -11250,7 +11256,7 @@ cmd_histedit(int argc, char *argv[]) struct got_worktree *worktree = NULL; struct got_fileindex *fileindex = NULL; struct got_repository *repo = NULL; - char *cwd = NULL; + char *cwd = NULL, *committer = NULL; struct got_reference *branch = NULL; struct got_reference *tmp_branch = NULL; struct got_object_id *resume_commit_id = NULL; @@ -11494,6 +11500,10 @@ cmd_histedit(int argc, char *argv[]) goto done; } + error = get_author(&committer, repo, worktree); + if (error) + goto done; + if (continue_edit) { char *path; @@ -11668,7 +11678,8 @@ cmd_histedit(int argc, char *argv[]) } if (have_changes) { error = histedit_commit(NULL, worktree, - fileindex, tmp_branch, hle, repo); + fileindex, tmp_branch, hle, + committer, repo); if (error) goto done; } else { @@ -11744,7 +11755,7 @@ cmd_histedit(int argc, char *argv[]) } error = histedit_commit(&merged_paths, worktree, fileindex, - tmp_branch, hle, repo); + tmp_branch, hle, committer, repo); got_worktree_rebase_pathlist_free(&merged_paths); if (error) goto done; @@ -11779,6 +11790,7 @@ cmd_histedit(int argc, char *argv[]) branch, repo); done: free(cwd); + free(committer); got_object_id_queue_free(&commits); histedit_free_list(&histedit_cmds); free(head_commit_id); blob - 610e03aa8788afbfcdcdc782c96c1c1965707674 blob + b2b02753e786580598a72d4ccfa4aeb006309afe --- include/got_worktree.h +++ include/got_worktree.h @@ -301,7 +301,7 @@ const struct got_error *got_worktree_rebase_merge_file */ const struct got_error *got_worktree_rebase_commit(struct got_object_id **, struct got_pathlist_head *, struct got_worktree *, struct got_fileindex *, - struct got_reference *, struct got_commit_object *, + struct got_reference *, const char *, struct got_commit_object *, struct got_object_id *, struct got_repository *); /* Free a list of merged paths from got_worktree_merge_files. */ @@ -378,7 +378,7 @@ const struct got_error *got_worktree_histedit_merge_fi */ const struct got_error *got_worktree_histedit_commit(struct got_object_id **, struct got_pathlist_head *, struct got_worktree *, struct got_fileindex *, - struct got_reference *, struct got_commit_object *, + struct got_reference *, const char *, struct got_commit_object *, struct got_object_id *, const char *, struct got_repository *); /* blob - cc19332e99847eb9da2ce2e427552b4b000d5413 blob + 1aa74370d5f4ab8ad0df2976589a98d01b6e1657 --- lib/worktree.c +++ lib/worktree.c @@ -6450,8 +6450,9 @@ static const struct got_error * rebase_commit(struct got_object_id **new_commit_id, struct got_pathlist_head *merged_paths, struct got_reference *commit_ref, struct got_worktree *worktree, struct got_fileindex *fileindex, - struct got_reference *tmp_branch, struct got_commit_object *orig_commit, - const char *new_logmsg, struct got_repository *repo) + struct got_reference *tmp_branch, const char *committer, + struct got_commit_object *orig_commit, const char *new_logmsg, + struct got_repository *repo) { const struct got_error *err, *sync_err; struct got_pathlist_head commitable_paths; @@ -6533,8 +6534,8 @@ rebase_commit(struct got_object_id **new_commit_id, /* NB: commit_worktree will call free(logmsg) */ err = commit_worktree(new_commit_id, &commitable_paths, head_commit_id, NULL, worktree, got_object_commit_get_author(orig_commit), - got_object_commit_get_committer(orig_commit), - collect_rebase_commit_msg, logmsg, rebase_status, NULL, repo); + committer, collect_rebase_commit_msg, logmsg, rebase_status, NULL, + repo); if (err) goto done; @@ -6567,7 +6568,7 @@ const struct got_error * got_worktree_rebase_commit(struct got_object_id **new_commit_id, struct got_pathlist_head *merged_paths, struct got_worktree *worktree, struct got_fileindex *fileindex, struct got_reference *tmp_branch, - struct got_commit_object *orig_commit, + const char *committer, struct got_commit_object *orig_commit, struct got_object_id *orig_commit_id, struct got_repository *repo) { const struct got_error *err; @@ -6591,7 +6592,8 @@ got_worktree_rebase_commit(struct got_object_id **new_ } err = rebase_commit(new_commit_id, merged_paths, commit_ref, - worktree, fileindex, tmp_branch, orig_commit, NULL, repo); + worktree, fileindex, tmp_branch, committer, orig_commit, + NULL, repo); done: if (commit_ref) got_ref_close(commit_ref); @@ -6604,7 +6606,7 @@ const struct got_error * got_worktree_histedit_commit(struct got_object_id **new_commit_id, struct got_pathlist_head *merged_paths, struct got_worktree *worktree, struct got_fileindex *fileindex, struct got_reference *tmp_branch, - struct got_commit_object *orig_commit, + const char *committer, struct got_commit_object *orig_commit, struct got_object_id *orig_commit_id, const char *new_logmsg, struct got_repository *repo) { @@ -6621,7 +6623,8 @@ got_worktree_histedit_commit(struct got_object_id **ne goto done; err = rebase_commit(new_commit_id, merged_paths, commit_ref, - worktree, fileindex, tmp_branch, orig_commit, new_logmsg, repo); + worktree, fileindex, tmp_branch, committer, orig_commit, + new_logmsg, repo); done: if (commit_ref) got_ref_close(commit_ref); blob - 89e063ffccc47d6560386bc393c8e4351e66eb36 blob + 1264347441d2f3f6859d520ab1230f6161a9d666 --- regress/cmdline/histedit.sh +++ regress/cmdline/histedit.sh @@ -2092,6 +2092,71 @@ test_histedit_mesg_invalid() { test_done "$testroot" $ret } +test_histedit_resets_committer() { + local testroot=`test_init histedit_resets_committer` + local orig_commit=`git_show_head $testroot/repo` + local committer="Flan Luck <flan_luck@openbsd.org>" + + got checkout $testroot/repo $testroot/wt > /dev/null + + echo "modified alpha" > $testroot/wt/alpha + + (cd $testroot/wt/ && got commit -m 'modified alpha on master' \ + alpha > /dev/null) + ret=$? + if [ "$?" != 0 ]; then + echo "got commit failed unexpectedly" >&2 + test_done "$testroot" "$ret" + return 1 + fi + + local top_commit=`git_show_head $testroot/repo` + echo "pick $top_commit" > "$testroot/histedit-script" + + (cd $testroot/wt/ && got update -c $orig_commit > /dev/null) + ret=$? + if [ "$?" != 0 ]; then + echo "got update failed unexpectedly" >&2 + test_done "$testroot" "$ret" + return 1 + fi + + (cd $testroot/wt && env GOT_AUTHOR="$committer" \ + got histedit -F "$testroot/histedit-script" > /dev/null) + ret=$? + if [ "$?" != 0 ]; then + echo "got histedit failed unexpectedly" >&2 + test_done "$testroot" "$ret" + return 1 + fi + local edited_commit=`git_show_head $testroot/repo` + + # Original commit only had one author + (cd $testroot/repo && got log -l1 -c $top_commit | \ + egrep '^(from|via):' > $testroot/stdout) + echo "from: $GOT_AUTHOR" > $testroot/stdout.expected + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + + # Edited commit should have new committer name added + (cd $testroot/repo && got log -l1 -c $edited_commit | \ + egrep '^(from|via):' > $testroot/stdout) + echo "from: $GOT_AUTHOR" > $testroot/stdout.expected + echo "via: $committer" >> $testroot/stdout.expected + + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + fi + test_done "$testroot" "$ret" +} + test_parseargs "$@" run_test test_histedit_no_op run_test test_histedit_swap @@ -2113,3 +2178,4 @@ run_test test_histedit_fold_only_empty_logmsg run_test test_histedit_edit_only run_test test_histedit_prepend_line run_test test_histedit_mesg_invalid +run_test test_histedit_resets_committer blob - 350e19ca9e343605f4497444e665c380a5212b8a blob + 2bdfc42c631a9bad8763528b9082b0deacbed9d9 --- regress/cmdline/rebase.sh +++ regress/cmdline/rebase.sh @@ -1480,6 +1480,94 @@ test_rebase_rm_add_rm_file() { test_done "$testroot" "$ret" } +test_rebase_resets_committer() { + local testroot=`test_init rebase_resets_committer` + local commit0=`git_show_head $testroot/repo` + local commit0_author_time=`git_show_author_time $testroot/repo` + local committer="Flan Luck <flan_luck@openbsd.org>" + + (cd $testroot/repo && git checkout -q -b newbranch) + echo "modified delta on branch" > $testroot/repo/gamma/delta + git_commit $testroot/repo -m "committing to delta on newbranch" + + echo "modified alpha on branch" > $testroot/repo/alpha + git_commit $testroot/repo -m "committing more changes on newbranch" + + local orig_commit1=`git_show_parent_commit $testroot/repo` + local orig_commit2=`git_show_head $testroot/repo` + local orig_author_time2=`git_show_author_time $testroot/repo` + + (cd $testroot/repo && git checkout -q master) + echo "modified zeta on master" > $testroot/repo/epsilon/zeta + git_commit $testroot/repo -m "committing to zeta on master" + local master_commit=`git_show_head $testroot/repo` + + got checkout $testroot/repo $testroot/wt > /dev/null + ret=$? + if [ $ret -ne 0 ]; then + test_done "$testroot" "$ret" + return 1 + fi + + (cd $testroot/wt && env GOT_AUTHOR="$committer" \ + got rebase newbranch > $testroot/stdout) + + (cd $testroot/repo && git checkout -q newbranch) + local new_commit1=`git_show_parent_commit $testroot/repo` + local new_commit2=`git_show_head $testroot/repo` + local new_author_time2=`git_show_author_time $testroot/repo` + + local short_orig_commit1=`trim_obj_id 28 $orig_commit1` + local short_orig_commit2=`trim_obj_id 28 $orig_commit2` + local short_new_commit1=`trim_obj_id 28 $new_commit1` + local short_new_commit2=`trim_obj_id 28 $new_commit2` + + echo "G gamma/delta" >> $testroot/stdout.expected + echo -n "$short_orig_commit1 -> $short_new_commit1" \ + >> $testroot/stdout.expected + echo ": committing to delta on newbranch" >> $testroot/stdout.expected + echo "G alpha" >> $testroot/stdout.expected + echo -n "$short_orig_commit2 -> $short_new_commit2" \ + >> $testroot/stdout.expected + echo ": committing more changes on newbranch" \ + >> $testroot/stdout.expected + echo "Switching work tree to refs/heads/newbranch" \ + >> $testroot/stdout.expected + + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + + # Original commit only had one author + (cd $testroot/repo && got log -l1 -c $orig_commit2 | \ + egrep '^(from|via):' > $testroot/stdout) + echo "from: $GOT_AUTHOR" > $testroot/stdout.expected + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + + # Rebased commit should have new committer name added + (cd $testroot/repo && got log -l1 -c $new_commit2 | \ + egrep '^(from|via):' > $testroot/stdout) + echo "from: $GOT_AUTHOR" > $testroot/stdout.expected + echo "via: $committer" >> $testroot/stdout.expected + + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + fi + test_done "$testroot" "$ret" +} + test_parseargs "$@" run_test test_rebase_basic run_test test_rebase_ancestry_check @@ -1495,3 +1583,4 @@ run_test test_rebase_out_of_date run_test test_rebase_trims_empty_dir run_test test_rebase_delete_missing_file run_test test_rebase_rm_add_rm_file +run_test test_rebase_resets_committer
reset committer name during rebase and histedit