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

From:
Tracey Emery <tracey@openbsd.org>
Subject:
Re: Histedit fold shortcut
To:
Josh Rickmar <joshrickmar@outlook.com>
Cc:
gameoftrees@openbsd.org
Date:
Thu, 10 Dec 2020 15:35:24 -0700

Download raw body.

Thread
On Thu, Dec 10, 2020 at 10:31:57PM +0000, Josh Rickmar wrote:
> This patch adds a -f flag to histedit (analogous to -m) to execute a
> histedit script which folds all commits into a single commit.
> 
> diff refs/heads/main refs/heads/test
> blob - c44524c54ba55850265ed0fc7be1f083914d1309
> blob + 9d61031ad09e3dbaac790c50d74317574b79e7d2
> --- got/got.1
> +++ got/got.1
> @@ -1489,7 +1489,7 @@ If this option is used, no other command-line argument
>  .It Cm rb
>  Short alias for
>  .Cm rebase .
> -.It Cm histedit Oo Fl a Oc Oo Fl c Oc Oo Fl F Ar histedit-script Oc Oo Fl m Oc
> +.It Cm histedit Oo Fl a Oc Oo Fl c Oc Oo Fl f Oc Oo Fl F Ar histedit-script Oc Oo Fl m Oc
>  Edit commit history between the work tree's current base commit and
>  the tip commit of the work tree's current branch.
>  .Pp
> @@ -1517,8 +1517,15 @@ Editing of commit history is controlled via a
>  .Ar histedit script
>  which can be written in an editor based on a template, passed on the
>  command line, or generated with the
> +.Fl f
> +or
>  .Fl m
> -option if only log messages need to be edited.
> +options.
> +The
> +.Fl f
> +option folds all commits into one commit, while the
> +.Fl m
> +option is used if only log messages need to be edited.

I still think this needs to be "only if" instead of "if only".

>  .Pp
>  The format of the histedit script is line-based.
>  Each line in the script begins with a command name, followed by
> @@ -1618,6 +1625,11 @@ If this option is used, no other command-line argument
>  .It Fl c
>  Continue an interrupted histedit operation.
>  If this option is used, no other command-line arguments are allowed.
> +.It Fl f
> +Fold all commits into a single commit.
> +This option is a quick equivalent to a histedit script which folds all
> +but the final commit into the final picked commit.
> +If this option is used, no other command-line arguments are allowed.
>  .It Fl F Ar histedit-script
>  Use the specified
>  .Ar histedit-script
> blob - 3b8ba655c02b9df7b4088a73f765a46b9f598e97
> blob + 7bdd9e142a5f26254c73c308684bb6d6da95ef20
> --- got/got.c
> +++ got/got.c
> @@ -7747,7 +7747,7 @@ done:
>  __dead static void
>  usage_histedit(void)
>  {
> -	fprintf(stderr, "usage: %s histedit [-a] [-c] [-F histedit-script] [-m]\n",
> +	fprintf(stderr, "usage: %s histedit [-a] [-c] [-f] [-F histedit-script] [-m]\n",
>  	    getprogname());
>  	exit(1);
>  }
> @@ -7814,17 +7814,20 @@ done:
>  
>  static const struct got_error *
>  histedit_write_commit_list(struct got_object_id_queue *commits,
> -    FILE *f, int edit_logmsg_only, struct got_repository *repo)
> +    FILE *f, int edit_logmsg_only, int fold_only, struct got_repository *repo)
>  {
>  	const struct got_error *err = NULL;
>  	struct got_object_qid *qid;
> +	const char *histedit_cmd = NULL;
>  
>  	if (SIMPLEQ_EMPTY(commits))
>  		return got_error(GOT_ERR_EMPTY_HISTEDIT);
>  
>  	SIMPLEQ_FOREACH(qid, commits, entry) {
> -		err = histedit_write_commit(qid->id, got_histedit_cmds[0].name,
> -		    f, repo);
> +		histedit_cmd = got_histedit_cmds[0].name;
> +		if (fold_only && SIMPLEQ_NEXT(qid, entry) != NULL)
> +			histedit_cmd = "fold";
> +		err = histedit_write_commit(qid->id, histedit_cmd, f, repo);
>  		if (err)
>  			break;
>  		if (edit_logmsg_only) {
> @@ -8232,7 +8235,7 @@ histedit_edit_list_retry(struct got_histedit_list *, c
>  static const struct got_error *
>  histedit_edit_script(struct got_histedit_list *histedit_cmds,
>      struct got_object_id_queue *commits, const char *branch_name,
> -    int edit_logmsg_only, struct got_repository *repo)
> +    int edit_logmsg_only, int fold_only, struct got_repository *repo)
>  {
>  	const struct got_error *err;
>  	FILE *f = NULL;
> @@ -8246,11 +8249,12 @@ histedit_edit_script(struct got_histedit_list *histedi
>  	if (err)
>  		goto done;
>  
> -	err = histedit_write_commit_list(commits, f, edit_logmsg_only, repo);
> +	err = histedit_write_commit_list(commits, f, edit_logmsg_only,
> +	    fold_only, repo);
>  	if (err)
>  		goto done;
>  
> -	if (edit_logmsg_only) {
> +	if (edit_logmsg_only || fold_only) {
>  		rewind(f);
>  		err = histedit_parse_list(histedit_cmds, f, repo);
>  	} else {
> @@ -8381,7 +8385,7 @@ histedit_edit_list_retry(struct got_histedit_list *his
>  		} else if (resp == 'r') {
>  			histedit_free_list(histedit_cmds);
>  			err = histedit_edit_script(histedit_cmds,
> -			    commits, branch_name, 0, repo);
> +			    commits, branch_name, 0, 0, repo);
>  			if (err) {
>  				if (err->code != GOT_ERR_HISTEDIT_SYNTAX &&
>  				    err->code != GOT_ERR_HISTEDIT_CMD)
> @@ -8573,7 +8577,7 @@ cmd_histedit(int argc, char *argv[])
>  	int ch, rebase_in_progress = 0;
>  	struct got_update_progress_arg upa;
>  	int edit_in_progress = 0, abort_edit = 0, continue_edit = 0;
> -	int edit_logmsg_only = 0;
> +	int edit_logmsg_only = 0, fold_only = 0;
>  	const char *edit_script_path = NULL;
>  	unsigned char rebase_status = GOT_STATUS_NO_CHANGE;
>  	struct got_object_id_queue commits;
> @@ -8588,7 +8592,7 @@ cmd_histedit(int argc, char *argv[])
>  	TAILQ_INIT(&merged_paths);
>  	memset(&upa, 0, sizeof(upa));
>  
> -	while ((ch = getopt(argc, argv, "acF:m")) != -1) {
> +	while ((ch = getopt(argc, argv, "acfF:m")) != -1) {
>  		switch (ch) {
>  		case 'a':
>  			abort_edit = 1;
> @@ -8596,6 +8600,9 @@ cmd_histedit(int argc, char *argv[])
>  		case 'c':
>  			continue_edit = 1;
>  			break;
> +		case 'f':
> +			fold_only = 1;
> +			break;
>  		case 'F':
>  			edit_script_path = optarg;
>  			break;
> @@ -8624,6 +8631,12 @@ cmd_histedit(int argc, char *argv[])
>  		errx(1, "histedit's -a and -m options are mutually exclusive");
>  	if (continue_edit && edit_logmsg_only)
>  		errx(1, "histedit's -c and -m options are mutually exclusive");
> +	if (abort_edit && fold_only)
> +		errx(1, "histedit's -a and -f options are mutually exclusive");
> +	if (continue_edit && fold_only)
> +		errx(1, "histedit's -c and -f options are mutually exclusive");
> +	if (fold_only && edit_logmsg_only)
> +		errx(1, "histedit's -f and -m options are mutually exclusive");
>  	if (argc != 0)
>  		usage_histedit();
>  
> @@ -8672,6 +8685,13 @@ cmd_histedit(int argc, char *argv[])
>  		    "before the -m option can be used");
>  		goto done;
>  	}
> +	if (edit_in_progress && fold_only) {
> +		error = got_error_msg(GOT_ERR_HISTEDIT_BUSY,
> +		    "histedit operation is in progress in this "
> +		    "work tree and must be continued or aborted "
> +		    "before the -f option can be used");
> +		goto done;
> +	}
>  
>  	if (edit_in_progress && abort_edit) {
>  		error = got_worktree_histedit_continue(&resume_commit_id,
> @@ -8807,7 +8827,7 @@ cmd_histedit(int argc, char *argv[])
>  			if (strncmp(branch_name, "refs/heads/", 11) == 0)
>  				branch_name += 11;
>  			error = histedit_edit_script(&histedit_cmds, &commits,
> -			    branch_name, edit_logmsg_only, repo);
> +			    branch_name, edit_logmsg_only, fold_only, repo);
>  			if (error) {
>  				got_worktree_histedit_abort(worktree, fileindex,
>  				    repo, branch, base_commit_id,

-- 

Tracey Emery