Commit Diff


commit - 5b66608142185bf4240db42d8819f75303538281
commit + 083957f4072e9d36c5c770055348c03850e63b30
blob - 3dcc6009d2063864e985ca249bda77e9434e537f
blob + b255255c35b0599f3ce3cfba03065a17637afdea
--- got/got.1
+++ got/got.1
@@ -988,13 +988,17 @@ 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 Op Fl F Ar histedit-script
+.It Cm histedit Oo Fl a Oc Oo Fl c 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
 Editing of commit history is controlled via a
 .Ar histedit script
-which can be edited interactively or passed on the command line.
+which can be edited interactively, passed on the command line,
+or generated with the
+.Fl m
+option if only log messages need to be edited.
+.Pp
 The format of the histedit script is line-based.
 Each line in the script begins with a command name, followed by
 whitespace and an argument.
@@ -1088,6 +1092,14 @@ 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 m
+Edit log messages only.
+This option is a quick equivalent to a histedit script which edits
+only log messages but otherwise uses every commit as-is.
+The
+.Fl m
+option can only be used when starting a new histedit operation.
+If this option is used, no other command-line arguments are allowed.
 .El
 .It Cm he
 Short alias for
@@ -1581,7 +1593,16 @@ This will also merge local changes, if any, with the i
 .Pp
 .Dl $ got update -b origin/master
 .Dl $ got rebase master
+.Pp
+On the
+.Dq master
+branch, log messages for local changes can now be amended with
+.Dq OK
+by other developers and any other important new information:
 .Pp
+.Dl $ got update -c origin/master
+.Dl $ got histedit -m
+.Pp
 Local changes on the
 .Dq master
 branch can then be pushed to the remote
blob - 4a5d5fcafa19f89e6039addb90f3c1979ea584e3
blob + 7a50d3a7ec56e05bab9576a9e6d61188b261f9a5
--- got/got.c
+++ got/got.c
@@ -5561,7 +5561,7 @@ done:
 __dead static void
 usage_histedit(void)
 {
-	fprintf(stderr, "usage: %s histedit [-a] [-c] [-F histedit-script]\n",
+	fprintf(stderr, "usage: %s histedit [-a] [-c] [-F histedit-script] [-m]\n",
 	    getprogname());
 	exit(1);
 }
@@ -5627,8 +5627,8 @@ done:
 }
 
 static const struct got_error *
-histedit_write_commit_list(struct got_object_id_queue *commits, FILE *f,
-    struct got_repository *repo)
+histedit_write_commit_list(struct got_object_id_queue *commits,
+    FILE *f, int edit_logmsg_only, struct got_repository *repo)
 {
 	const struct got_error *err = NULL;
 	struct got_object_qid *qid;
@@ -5641,6 +5641,13 @@ histedit_write_commit_list(struct got_object_id_queue 
 		    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;
@@ -6018,7 +6025,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,
-    struct got_repository *repo)
+    int edit_logmsg_only, struct got_repository *repo)
 {
 	const struct got_error *err;
 	FILE *f = NULL;
@@ -6032,23 +6039,27 @@ histedit_edit_script(struct got_histedit_list *histedi
 	if (err)
 		goto done;
 
-	err = histedit_write_commit_list(commits, f, repo);
+	err = histedit_write_commit_list(commits, f, edit_logmsg_only, repo);
 	if (err)
 		goto done;
 
-	if (fclose(f) != 0) {
-		err = got_error_from_errno("fclose");
-		goto done;
-	}
-	f = NULL;
-
-	err = histedit_run_editor(histedit_cmds, path, commits, repo);
-	if (err) {
-		if (err->code != GOT_ERR_HISTEDIT_SYNTAX &&
-		    err->code != GOT_ERR_HISTEDIT_CMD)
+	if (edit_logmsg_only) {
+		rewind(f);
+		err = histedit_parse_list(histedit_cmds, f, repo);
+	} else {
+		if (fclose(f) != 0) {
+			err = got_error_from_errno("fclose");
 			goto done;
-		err = histedit_edit_list_retry(histedit_cmds, err,
-		    commits, path, branch_name, repo);
+		}
+		f = NULL;
+		err = histedit_run_editor(histedit_cmds, path, commits, repo);
+		if (err) {
+			if (err->code != GOT_ERR_HISTEDIT_SYNTAX &&
+			    err->code != GOT_ERR_HISTEDIT_CMD)
+				goto done;
+			err = histedit_edit_list_retry(histedit_cmds, err,
+			    commits, path, branch_name, repo);
+		}
 	}
 done:
 	if (f && fclose(f) != 0 && err == NULL)
@@ -6163,7 +6174,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, repo);
+			    commits, branch_name, 0, repo);
 			if (err) {
 				if (err->code != GOT_ERR_HISTEDIT_SYNTAX &&
 				    err->code != GOT_ERR_HISTEDIT_CMD)
@@ -6354,6 +6365,7 @@ cmd_histedit(int argc, char *argv[])
 	struct got_commit_object *commit = NULL;
 	int ch, rebase_in_progress = 0, did_something;
 	int edit_in_progress = 0, abort_edit = 0, continue_edit = 0;
+	int edit_logmsg_only = 0;
 	const char *edit_script_path = NULL;
 	unsigned char rebase_status = GOT_STATUS_NO_CHANGE;
 	struct got_object_id_queue commits;
@@ -6367,7 +6379,7 @@ cmd_histedit(int argc, char *argv[])
 	TAILQ_INIT(&histedit_cmds);
 	TAILQ_INIT(&merged_paths);
 
-	while ((ch = getopt(argc, argv, "acF:")) != -1) {
+	while ((ch = getopt(argc, argv, "acF:m")) != -1) {
 		switch (ch) {
 		case 'a':
 			abort_edit = 1;
@@ -6378,6 +6390,9 @@ cmd_histedit(int argc, char *argv[])
 		case 'F':
 			edit_script_path = optarg;
 			break;
+		case 'm':
+			edit_logmsg_only = 1;
+			break;
 		default:
 			usage_histedit();
 			/* NOTREACHED */
@@ -6393,7 +6408,13 @@ cmd_histedit(int argc, char *argv[])
 		err(1, "pledge");
 #endif
 	if (abort_edit && continue_edit)
-		usage_histedit();
+		errx(1, "histedit's -a and -c options are mutually exclusive");
+	if (edit_script_path && edit_logmsg_only)
+		errx(1, "histedit's -F and -m options are mutually exclusive");
+	if (abort_edit && edit_logmsg_only)
+		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 (argc != 0)
 		usage_histedit();
 
@@ -6432,6 +6453,14 @@ cmd_histedit(int argc, char *argv[])
 	if (error)
 		goto done;
 
+	if (edit_in_progress && edit_logmsg_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 -m option can be used");
+		goto done;
+	}
+
 	if (edit_in_progress && abort_edit) {
 		error = got_worktree_histedit_continue(&resume_commit_id,
 		    &tmp_branch, &branch, &base_commit_id, &fileindex,
@@ -6564,7 +6593,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, repo);
+			    branch_name, edit_logmsg_only, repo);
 			if (error) {
 				got_worktree_histedit_abort(worktree, fileindex,
 				    repo, branch, base_commit_id,