commit - 3f670bfb38a502b7309f7db354b9d4f767ea12fc
commit + 466785b9264da1a24c92aed9d706e76cc826601d
blob - c44524c54ba55850265ed0fc7be1f083914d1309
blob + f8e70b868b5d03985616d549fb6447025772eef9
--- got/got.1
+++ got/got.1
.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
.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 only if 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
.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
+commits, combining them all into one 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
__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);
}
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) {
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;
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 {
} 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)
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;
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;
case 'c':
continue_edit = 1;
break;
+ case 'f':
+ fold_only = 1;
+ break;
case 'F':
edit_script_path = optarg;
break;
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();
"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,
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,