Download raw body.
[PATCH] got histedit: make mesg behave like pick
i realize now that this has a bug:
```
mesg <commit>
edit <commit>
```
it will open the editor at least twice to edit the same commit message
(for the `mesg` command). this is because we now parse the histedit
script two times:
- when intially closing the editor that had the histedit script open
- when continuing the edit using `histedit -c`
there is no way to save the log message without completly changing how
histedit works afaik...
On Tue, Oct 24, 2023 at 12:43:13PM +0200, Lorenz (xha) wrote:
> hi,
>
> as discussed on irc, i propose to change the histedit command `mesg`
> to behave like the `pick` command but to edit the commit message in
> $EDITOR. this is how that would look like:
>
> ```
> drop <commit>
> fold <commit>
> # same as `pick` but edit log message in $EDITOR
> mesg <commit>
> ```
>
> these are the reasons for this change:
> - having fold operate on the next commit and mesg on the previous one is
> confusing. there is no good place to put mesg
> - probably none is using the scripting functionality of mesg outside of
> the regression tests. you can still use a editor.sh script
> - it is more intuitive to use `mesg` like `pick`
>
> the regress tests are passing for me. as expected, i had to add some
> editor.sh "hacks".
>
> diff /home/lorenz/src/got
> commit - 41208069f572694ef8847dbe9d9a47337f7083bd
> path + /home/lorenz/src/got
> blob - 52eeeda8df9fb52a8581faa28c2d29c19ca5a2be
> file + got/got.1
> --- got/got.1
> +++ got/got.1
> @@ -3016,18 +3016,7 @@ Regular editing of history must eventually be resumed
> .It Cm fold Ar commit Ta Combine the specified commit with the next commit
> listed further below that will be used.
> .It Cm drop Ar commit Ta Remove this commit from the edited history.
> -.It Cm mesg Oo Ar log-message Oc Ta Create a new log message for the commit of
> -a preceding
> -.Cm pick
> -or
> -.Cm edit
> -command on the previous line of the histedit script.
> -The optional
> -.Ar log-message
> -argument provides a new single-line log message to use.
> -If the
> -.Ar log-message
> -argument is omitted, open an editor where a new log message can be written.
> +.It Cm mesg Ar commit Ta Use the specified commit but edit the log message.
> .El
> .Pp
> Every commit in the history being edited must be mentioned in the script.
> blob - 73812ddbb0f2e3a0fee927fc0ae5b873c04e385a
> file + got/got.c
> --- got/got.c
> +++ got/got.c
> @@ -11696,8 +11696,7 @@ static const struct got_histedit_cmd {
> { GOT_HISTEDIT_FOLD, "fold", "combine with next commit that will "
> "be used" },
> { GOT_HISTEDIT_DROP, "drop", "remove commit from history" },
> - { GOT_HISTEDIT_MESG, "mesg",
> - "single-line log message for commit above (open editor if empty)" },
> + { GOT_HISTEDIT_MESG, "mesg", "use commit but edit the log message" },
> };
>
> struct got_histedit_list_entry {
> @@ -11760,16 +11759,11 @@ histedit_write_commit_list(struct got_object_id_queue
> histedit_cmd = "edit";
> else if (fold_only && STAILQ_NEXT(qid, entry) != NULL)
> histedit_cmd = "fold";
> + else if (edit_logmsg_only)
> + histedit_cmd = "mesg";
> err = histedit_write_commit(&qid->id, histedit_cmd, f, repo);
> if (err)
> break;
> - if (edit_logmsg_only) {
> - int n = fprintf(f, "%c\n", GOT_HISTEDIT_MESG);
> - if (n < 0) {
> - err = got_ferror(f, GOT_ERR_IO);
> - break;
> - }
> - }
> }
>
> return err;
> @@ -11986,7 +11980,7 @@ histedit_parse_list(struct got_histedit_list *histedit
> char *line = NULL, *p, *end;
> size_t i, linesize = 0;
> ssize_t linelen;
> - int lineno = 0, lastcmd = -1;
> + int lineno = 0;
> const struct got_histedit_cmd *cmd;
> struct got_object_id *commit_id = NULL;
> struct got_histedit_list_entry *hle = NULL;
> @@ -12026,37 +12020,15 @@ histedit_parse_list(struct got_histedit_list *histedit
> }
> while (isspace((unsigned char)p[0]))
> p++;
> - if (cmd->code == GOT_HISTEDIT_MESG) {
> - if (lastcmd != GOT_HISTEDIT_PICK &&
> - lastcmd != GOT_HISTEDIT_EDIT) {
> - err = got_error(GOT_ERR_HISTEDIT_CMD);
> - break;
> - }
> - if (p[0] == '\0') {
> - err = histedit_edit_logmsg(hle, repo);
> - if (err)
> - break;
> - } else {
> - hle->logmsg = strdup(p);
> - if (hle->logmsg == NULL) {
> - err = got_error_from_errno("strdup");
> - break;
> - }
> - }
> - lastcmd = cmd->code;
> - continue;
> - } else {
> - end = p;
> - while (end[0] && !isspace((unsigned char)end[0]))
> - end++;
> - *end = '\0';
> -
> - err = got_object_resolve_id_str(&commit_id, repo, p);
> - if (err) {
> - /* override error code */
> - err = histedit_syntax_error(lineno);
> - break;
> - }
> + end = p;
> + while (end[0] && !isspace((unsigned char)end[0]))
> + end++;
> + *end = '\0';
> + err = got_object_resolve_id_str(&commit_id, repo, p);
> + if (err) {
> + /* override error code */
> + err = histedit_syntax_error(lineno);
> + break;
> }
> hle = malloc(sizeof(*hle));
> if (hle == NULL) {
> @@ -12068,7 +12040,12 @@ histedit_parse_list(struct got_histedit_list *histedit
> hle->logmsg = NULL;
> commit_id = NULL;
> TAILQ_INSERT_TAIL(histedit_cmds, hle, entry);
> - lastcmd = cmd->code;
> +
> + if (cmd->code == GOT_HISTEDIT_MESG) {
> + err = histedit_edit_logmsg(hle, repo);
> + if (err)
> + break;
> + }
> }
>
> free(line);
> @@ -12270,15 +12247,6 @@ histedit_save_list(struct got_histedit_list *histedit_
> repo);
> if (err)
> break;
> -
> - if (hle->logmsg) {
> - int n = fprintf(f, "%c %s\n",
> - GOT_HISTEDIT_MESG, hle->logmsg);
> - if (n < 0) {
> - err = got_ferror(f, GOT_ERR_IO);
> - break;
> - }
> - }
> }
> done:
> if (f && fclose(f) == EOF && err == NULL)
> @@ -12416,6 +12384,7 @@ show_histedit_progress(struct got_commit_object *commi
> switch (hle->cmd->code) {
> case GOT_HISTEDIT_PICK:
> case GOT_HISTEDIT_EDIT:
> + case GOT_HISTEDIT_MESG:
> printf("%s -> %s: %s\n", old_id_str,
> new_id_str ? new_id_str : "no-op change", logmsg);
> break;
> blob - a8c20c791a546fc257c69e471cb4ff9e59cd4d66
> file + regress/cmdline/histedit.sh
> --- regress/cmdline/histedit.sh
> +++ regress/cmdline/histedit.sh
> @@ -491,13 +491,22 @@ test_histedit_fold() {
> return 1
> fi
>
> + cat > $testroot/editor.sh <<EOF
> +#!/bin/sh
> +ed -s "\$1" <<-EOF
> + ,s/.*/committing folded changes/
> + w
> + EOF
> +EOF
> + chmod +x $testroot/editor.sh
> +
> echo "fold $old_commit1" > $testroot/histedit-script
> echo "drop $old_commit2" >> $testroot/histedit-script
> echo "pick $old_commit3" >> $testroot/histedit-script
> - echo "mesg committing folded changes" >> $testroot/histedit-script
>
> - (cd $testroot/wt && got histedit -F $testroot/histedit-script \
> - > $testroot/stdout)
> + (cd $testroot/wt && env EDITOR="$testroot/editor.sh" \
> + VISUAL="$testroot/editor.sh" \
> + got histedit -F $testroot/histedit-script > $testroot/stdout)
>
> local new_commit1=`git_show_parent_commit $testroot/repo`
> local new_commit2=`git_show_head $testroot/repo`
> @@ -603,7 +612,6 @@ test_histedit_edit() {
> fi
>
> echo "edit $old_commit1" > $testroot/histedit-script
> - echo "mesg committing changes" >> $testroot/histedit-script
> echo "pick $old_commit2" >> $testroot/histedit-script
>
> (cd $testroot/wt && got histedit -F $testroot/histedit-script \
> @@ -650,8 +658,20 @@ test_histedit_edit() {
> fi
>
> (cd $testroot/wt && got unstage alpha > /dev/null)
> - (cd $testroot/wt && got histedit -c > $testroot/stdout)
>
> + cat > $testroot/editor.sh <<EOF
> +#!/bin/sh
> +ed -s "\$1" <<-EOF
> + ,s/.*/committing changes/
> + w
> + EOF
> +EOF
> + chmod +x $testroot/editor.sh
> +
> + (cd $testroot/wt && env EDITOR="$testroot/editor.sh" \
> + VISUAL="$testroot/editor.sh" \
> + got histedit -c > $testroot/stdout)
> +
> local new_commit1=`git_show_parent_commit $testroot/repo`
> local new_commit2=`git_show_head $testroot/repo`
>
> @@ -771,7 +791,7 @@ test_histedit_fold_last_commit() {
> test_done "$testroot" "$ret"
> }
>
> -test_histedit_missing_commit() {
> +test_histedit_missing_commit_pick() {
> local testroot=`test_init histedit_missing_commit`
>
> local orig_commit=`git_show_head $testroot/repo`
> @@ -795,7 +815,6 @@ test_histedit_missing_commit() {
> fi
>
> echo "pick $old_commit1" > $testroot/histedit-script
> - echo "mesg committing changes" >> $testroot/histedit-script
>
> (cd $testroot/wt && got histedit -F $testroot/histedit-script \
> > $testroot/stdout 2> $testroot/stderr)
> @@ -818,6 +837,63 @@ test_histedit_missing_commit() {
> test_done "$testroot" "$ret"
> }
>
> +test_histedit_missing_commit_mesg() {
> + local testroot=`test_init histedit_missing_commit`
> +
> + local orig_commit=`git_show_head $testroot/repo`
> +
> + echo "modified alpha on master" > $testroot/repo/alpha
> + git -C $testroot/repo rm -q beta
> + echo "new file on master" > $testroot/repo/epsilon/new
> + git -C $testroot/repo add epsilon/new
> + git_commit $testroot/repo -m "committing changes"
> + local old_commit1=`git_show_head $testroot/repo`
> +
> + echo "modified zeta on master" > $testroot/repo/epsilon/zeta
> + git_commit $testroot/repo -m "committing to zeta on master"
> + local old_commit2=`git_show_head $testroot/repo`
> +
> + got checkout -c $orig_commit $testroot/repo $testroot/wt > /dev/null
> + ret=$?
> + if [ $ret -ne 0 ]; then
> + test_done "$testroot" "$ret"
> + return 1
> + fi
> +
> + cat > $testroot/editor.sh <<EOF
> +#!/bin/sh
> +ed -s "\$1" <<-EOF
> + ,s/.*/committing folded changes/
> + w
> + EOF
> +EOF
> + chmod +x $testroot/editor.sh
> +
> + echo "mesg $old_commit1" > $testroot/histedit-script
> +
> + (cd $testroot/wt && env EDITOR="$testroot/editor.sh" \
> + VISUAL="$testroot/editor.sh" \
> + got histedit -F $testroot/histedit-script > $testroot/stdout \
> + 2>$testroot/stderr)
> +
> + ret=$?
> + if [ $ret -eq 0 ]; then
> + echo "histedit succeeded unexpectedly" >&2
> + test_done "$testroot" "1"
> + return 1
> + fi
> +
> + echo "got: commit $old_commit2 missing from histedit script" \
> + > $testroot/stderr.expected
> +
> + cmp -s $testroot/stderr.expected $testroot/stderr
> + ret=$?
> + if [ $ret -ne 0 ]; then
> + diff -u $testroot/stderr.expected $testroot/stderr
> + fi
> + test_done "$testroot" "$ret"
> +}
> +
> test_histedit_abort() {
> local testroot=`test_init histedit_abort`
>
> @@ -845,7 +921,6 @@ test_histedit_abort() {
> touch $testroot/wt/unversioned-file
>
> echo "edit $old_commit1" > $testroot/histedit-script
> - echo "mesg committing changes" >> $testroot/histedit-script
> echo "pick $old_commit2" >> $testroot/histedit-script
>
> (cd $testroot/wt && got histedit -F $testroot/histedit-script \
> @@ -1051,7 +1126,6 @@ test_histedit_path_prefix_edit() {
> fi
>
> echo "edit $old_commit1" > $testroot/histedit-script
> - echo "mesg modified zeta" >> $testroot/histedit-script
>
> (cd $testroot/wt && got histedit -F $testroot/histedit-script \
> > $testroot/stdout 2> $testroot/stderr)
> @@ -1120,8 +1194,19 @@ test_histedit_path_prefix_edit() {
> test_done "$testroot" "$ret"
> return 1
> fi
> +
> + cat > $testroot/editor.sh <<EOF
> +#!/bin/sh
> +ed -s "\$1" <<-EOF
> + ,s/.*/modified zeta/
> + w
> + EOF
> +EOF
> + chmod +x $testroot/editor.sh
>
> - (cd $testroot/wt && got histedit -c > $testroot/stdout)
> + (cd $testroot/wt && env EDITOR="$testroot/editor.sh" \
> + VISUAL="$testroot/editor.sh" \
> + got histedit -c > $testroot/stdout)
>
> local new_commit1=`git_show_head $testroot/repo`
> local short_new_commit1=`trim_obj_id 28 $new_commit1`
> @@ -1244,13 +1329,23 @@ test_histedit_fold_last_commit_swap() {
> return 1
> fi
>
> + cat > $testroot/editor.sh <<EOF
> +#!/bin/sh
> +ed -s "\$1" <<-EOF
> + ,s/.*/committing folded changes/
> + w
> + EOF
> +EOF
> + chmod +x $testroot/editor.sh
> +
> # fold commit2 into commit1 (requires swapping commits)
> echo "fold $old_commit2" > $testroot/histedit-script
> - echo "pick $old_commit1" >> $testroot/histedit-script
> - echo "mesg committing folded changes" >> $testroot/histedit-script
> + echo "mesg $old_commit1" >> $testroot/histedit-script
>
> - (cd $testroot/wt && got histedit -F $testroot/histedit-script \
> - > $testroot/stdout 2> $testroot/stderr)
> + (cd $testroot/wt && env EDITOR="$testroot/editor.sh" \
> + VISUAL="$testroot/editor.sh" \
> + got histedit -F $testroot/histedit-script > $testroot/stdout \
> + 2> $testroot/stderr)
>
> ret=$?
> if [ $ret -ne 0 ]; then
> @@ -1470,13 +1565,22 @@ test_histedit_fold_add_delete() {
> return 1
> fi
>
> + cat > $testroot/editor.sh <<EOF
> +#!/bin/sh
> +ed -s "\$1" <<-EOF
> + ,s/.*/folded changes/
> + w
> + EOF
> +EOF
> + chmod +x $testroot/editor.sh
> +
> echo "fold $old_commit1" > $testroot/histedit-script
> echo "fold $old_commit2" >> $testroot/histedit-script
> echo "pick $old_commit3" >> $testroot/histedit-script
> - echo "mesg folded changes" >> $testroot/histedit-script
>
> - (cd $testroot/wt && got histedit -F $testroot/histedit-script \
> - > $testroot/stdout)
> + (cd $testroot/wt && env EDITOR="$testroot/editor.sh" \
> + VISUAL="$testroot/editor.sh" \
> + got histedit -F $testroot/histedit-script > $testroot/stdout)
>
> local new_commit1=`git_show_head $testroot/repo`
>
> @@ -1565,12 +1669,21 @@ test_histedit_fold_edit_delete() {
> return 1
> fi
>
> + cat > $testroot/editor.sh <<EOF
> +#!/bin/sh
> +ed -s "\$1" <<-EOF
> + ,s/.*/folded changes/
> + w
> + EOF
> +EOF
> + chmod +x $testroot/editor.sh
> +
> echo "fold $old_commit1" > $testroot/histedit-script
> echo "pick $old_commit2" >> $testroot/histedit-script
> - echo "mesg folded changes" >> $testroot/histedit-script
>
> - (cd $testroot/wt && got histedit -F $testroot/histedit-script \
> - > $testroot/stdout)
> + (cd $testroot/wt && env EDITOR="$testroot/editor.sh" \
> + VISUAL="$testroot/editor.sh" \
> + got histedit -F $testroot/histedit-script > $testroot/stdout)
>
> local new_commit1=`git_show_head $testroot/repo`
>
> @@ -1645,12 +1758,21 @@ test_histedit_fold_delete_add() {
> return 1
> fi
>
> + cat > $testroot/editor.sh <<EOF
> +#!/bin/sh
> +ed -s "\$1" <<-EOF
> + ,s/.*/folded changes/
> + w
> + EOF
> +EOF
> + chmod +x $testroot/editor.sh
> +
> echo "fold $old_commit1" > $testroot/histedit-script
> echo "pick $old_commit2" >> $testroot/histedit-script
> - echo "mesg folded changes" >> $testroot/histedit-script
>
> - (cd $testroot/wt && got histedit -F $testroot/histedit-script \
> - > $testroot/stdout)
> + (cd $testroot/wt && env EDITOR="$testroot/editor.sh" \
> + VISUAL="$testroot/editor.sh" \
> + got histedit -F $testroot/histedit-script > $testroot/stdout)
>
> local new_commit1=`git_show_head $testroot/repo`
>
> @@ -2142,126 +2264,6 @@ EOF
> test_done "$testroot" $ret
> }
>
> -test_histedit_mesg_invalid() {
> - local testroot=`test_init mesg_invalid`
> -
> - local orig_commit=`git_show_head $testroot/repo`
> -
> - echo "modified alpha on master" > $testroot/repo/alpha
> - git -C $testroot/repo rm -q beta
> - echo "new file on master" > $testroot/repo/epsilon/new
> - git -C $testroot/repo add epsilon/new
> - git_commit $testroot/repo -m 'committing changes'
> - local old_commit1=`git_show_head $testroot/repo`
> -
> - echo "modified zeta on master" > $testroot/repo/epsilon/zeta
> - git_commit $testroot/repo -m 'committing to zeto on master'
> - local old_commit2=`git_show_head $testroot/repo`
> -
> - got checkout -c $orig_commit $testroot/repo $testroot/wt > /dev/null
> - ret=$?
> - if [ $ret -ne 0 ]; then
> - test_done "$testroot" $ret
> - return 1
> - fi
> -
> - # try with a leading mesg
> -
> - echo "mesg something something" > $testroot/histedit-script
> - echo "pick $old_commit1" >> $testroot/histedit-script
> - echo "pick $old_commit2" >> $testroot/histedit-script
> -
> - (cd $testroot/wt && got histedit -F $testroot/histedit-script \
> - > $testroot/stdout 2> $testroot/stderr)
> - ret=$?
> - if [ $ret -eq 0 ]; then
> - echo "histedit succeeded unexpectedly" >&2
> - test_done "$testroot" 1
> - return 1
> - fi
> -
> - echo "got: bad histedit command" > $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
> -
> - # try again with mesg -> mesg
> -
> - echo "pick $old_commit1" > $testroot/histedit-script
> - echo "mesg something something" >> $testroot/histedit-script
> - echo "mesg something something else" >> $testroot/histedit-script
> - echo "pick $old_commit2" >> $testroot/histedit-script
> -
> - (cd $testroot/wt && got histedit -F $testroot/histedit-script \
> - > $testroot/stdout 2> $testroot/stderr)
> - ret=$?
> - if [ $ret -eq 0 ]; then
> - echo "histedit succeeded unexpectedly" >&2
> - test_done "$testroot" 1
> - return 1
> - fi
> -
> - echo "got: bad histedit command" > $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
> -
> - # try again with drop -> mesg
> -
> - echo "drop $old_commit1" > $testroot/histedit-script
> - echo "mesg something something" >> $testroot/histedit-script
> - echo "pick $old_commit2" >> $testroot/histedit-script
> -
> - (cd $testroot/wt && got histedit -F $testroot/histedit-script \
> - > $testroot/stdout 2> $testroot/stderr)
> - ret=$?
> - if [ $ret -eq 0 ]; then
> - echo "histedit succeeded unexpectedly" >&2
> - test_done "$testroot" 1
> - return 1
> - fi
> -
> - echo "got: bad histedit command" > $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
> -
> - # try again with fold -> mesg
> -
> - echo "fold $old_commit1" > $testroot/histedit-script
> - echo "mesg something something" >> $testroot/histedit-script
> - echo "pick $old_commit2" >> $testroot/histedit-script
> -
> - (cd $testroot/wt && got histedit -F $testroot/histedit-script \
> - > $testroot/stdout 2> $testroot/stderr)
> - ret=$?
> - if [ $ret -eq 0 ]; then
> - echo "histedit succeeded unexpectedly" >&2
> - test_done "$testroot" 1
> - return 1
> - fi
> -
> - echo "got: bad histedit command" > $testroot/stderr.expected
> - cmp -s $testroot/stderr.expected $testroot/stderr
> - ret=$?
> - if [ $ret -ne 0 ]; then
> - diff -u $testroot/stderr.expected $testroot/stderr
> - fi
> - test_done "$testroot" $ret
> -}
> -
> test_histedit_resets_committer() {
> local testroot=`test_init histedit_resets_committer`
> local orig_commit=`git_show_head $testroot/repo`
> @@ -2354,13 +2356,22 @@ test_histedit_umask() {
> return 1
> fi
>
> + cat > $testroot/editor.sh <<EOF
> +#!/bin/sh
> +ed -s "\$1" <<-EOF
> + ,s/.*/folding changes/
> + w
> + EOF
> +EOF
> + chmod +x $testroot/editor.sh
> +
> echo fold $commit1 >$testroot/histedit-script
> echo fold $commit2 >>$testroot/histedit-script
> echo pick $commit3 >>$testroot/histedit-script
> - echo mesg folding changes >>$testroot/histedit-script
>
> # using a subshell to avoid clobbering global umask
> (umask 077 && cd "$testroot/wt" && \
> + env EDITOR="$testroot/editor.sh" VISUAL="$testroot/editor.sh" \
> got histedit -F "$testroot/histedit-script") >/dev/null
> ret=$?
>
> @@ -2604,7 +2615,8 @@ run_test test_histedit_drop
> run_test test_histedit_fold
> run_test test_histedit_edit
> run_test test_histedit_fold_last_commit
> -run_test test_histedit_missing_commit
> +run_test test_histedit_missing_commit_pick
> +run_test test_histedit_missing_commit_mesg
> run_test test_histedit_abort
> run_test test_histedit_path_prefix_drop
> run_test test_histedit_path_prefix_edit
> @@ -2619,7 +2631,6 @@ run_test test_histedit_fold_only
> 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
> run_test test_histedit_umask
> run_test test_histedit_mesg_filemode_change
>
[PATCH] got histedit: make mesg behave like pick