From: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
To: Edmundo Carmona Antoranz <eantoranz@gmail.com>
Cc: git@vger.kernel.org
Subject: Re: [PATCH v1] rebase - recycle
Date: Sat, 23 Apr 2022 00:57:12 +0200 [thread overview]
Message-ID: <220423.86bkwsra4a.gmgdl@evledraar.gmail.com> (raw)
In-Reply-To: <20220422183744.347327-1-eantoranz@gmail.com>
On Fri, Apr 22 2022, Edmundo Carmona Antoranz wrote:
Just minor nits from a quick read. Not on the main logic, just syntax
etc. issues:
> #define DEFAULT_REFLOG_ACTION "rebase"
>
> @@ -49,7 +52,8 @@ static GIT_PATH_FUNC(merge_dir, "rebase-merge")
> enum rebase_type {
> REBASE_UNSPECIFIED = -1,
> REBASE_APPLY,
> - REBASE_MERGE
> + REBASE_MERGE,
> + REBASE_RECYCLE
> };
>
> enum empty_type {
> @@ -83,6 +87,8 @@ struct rebase_options {
> REBASE_DIFFSTAT = 1<<2,
> REBASE_FORCE = 1<<3,
> REBASE_INTERACTIVE_EXPLICIT = 1<<4,
> + REBASE_RECYCLE_OR_FAIL = 1 << 5,
> + REBASE_ATTEMPT_RECYCLE = 1<<6,
Needs consistent whitespace for <<.
> } flags;
> struct strvec git_am_opts;
> const char *action;
> @@ -104,6 +110,16 @@ struct rebase_options {
> int fork_point;
> };
>
> +struct recycle_parent_mapping {
> + struct oidmap_entry e;
> + struct commit *new_parent;
> +};
> +
> +struct recycle_progress_info {
> + struct progress *progress;
> + int commits;
> +};
> +
> #define REBASE_OPTIONS_INIT { \
> .type = REBASE_UNSPECIFIED, \
> .empty = EMPTY_UNSPECIFIED, \
> @@ -384,6 +400,12 @@ static int is_merge(struct rebase_options *opts)
> return opts->type == REBASE_MERGE;
> }
>
> +static int can_recycle(struct rebase_options *opts)
> +{
> + return oideq(get_commit_tree_oid(opts->onto),
> + get_commit_tree_oid(opts->upstream));
> +}
> +
> static void imply_merge(struct rebase_options *opts, const char *option)
> {
> switch (opts->type) {
> @@ -771,6 +793,173 @@ static int run_specific_rebase(struct rebase_options *opts, enum action action)
> return status ? -1 : 0;
> }
>
> +static struct commit *recycle_commit(struct commit *orig_commit,
> + struct oidmap *parents)
> +{
> + const char *body;
> + size_t body_length;
> + const char *author_raw;
> + size_t author_length;
> + struct strbuf author = STRBUF_INIT;
> + const char *message;
> + size_t message_length;
> + int result;
> +
We tend not to \n\n-break the variables.
> + if (result)
> + die("Could not create a recycled revision for %s\n",
Error messages should not start wth capital letters, so "could.." not
"Could". Also needs _() markings for translation. Then don't add a \n.
> + struct recycle_parent_mapping *mapping;
> + mapping = xmalloc(sizeof(*mapping));
Add \n\n between variable decls & code.
In this case though we can just put the xmalloc() with decl...
> + struct commit *orig_head;
> + struct commit *new_head = NULL;
> + struct commit *commit;
> + struct commit_list *old_commits = NULL;
> + struct commit_list *old_commit;
> + struct oidmap parents;
> + struct progress *progress = NULL;
> + int commit_counter = 0;
> +
> + init_revisions(&revs, NULL);
> + revs.commit_format = CMIT_FMT_RAW;
> + orig_head = lookup_commit_or_die(&opts->orig_head, "head");
Just declare this with the variable, seems it doesn't need
init_revisions, or does it...?
> +
> + opts->upstream->object.flags |= UNINTERESTING;
> + add_pending_object(&revs, &opts->upstream->object, "upstream");
> + add_pending_object(&revs, &orig_head->object, "head");
> +
> + if (prepare_revision_walk(&revs))
> + die("Could not get commits to recycle");
ditto capital letters, _() etc.
> + if (isatty(2)) {
Skip {} for one-statement if's.
> + start_delayed_progress(_("Recycling commits"),
Missing the assignment to progerss, so this never works, presumably...
> + commit_list_count(old_commits));
> + }
> +
> + old_commit = old_commits;
> + while (old_commit) {
> + display_progress(progress, ++commit_counter);
I.e. still NULL here...
> + new_head = recycle_commit(old_commit->item, &parents);
> + recycle_save_parent_mapping(&parents, old_commit->item,
> + new_head);
> + old_commit = old_commit->next;
> + }
> +
> + stop_progress(&progress);
> +
> + return new_head;
> +}
> +
> +static void recycle_wrapup(struct rebase_options *opts,
> + const char *branch_name, struct commit *new_head)
> +{
> + struct strvec args = STRVEC_INIT;
\n\n again.
> + if (opts->head_name) {
> + struct wt_status s = { 0 };
> +
> + s.show_branch = 1;
> + wt_status_prepare(the_repository, &s);
> + wt_status_collect(&s);
> + if (!strcmp(s.branch, opts->head_name)) {
> + struct reset_head_opts ropts = { 0 };
> + struct strbuf msg = STRBUF_INIT;
ditto.
> + strbuf_addf(&msg, "rebase recycle: "
> + "moving to %s",
> + oid_to_hex(&new_head->object.oid));
> + ropts.oid = &new_head->object.oid;
> + ropts.orig_head = &opts->orig_head,
> + ropts.flags = RESET_HEAD_HARD |
> + RESET_HEAD_RUN_POST_CHECKOUT_HOOK;
> + ropts.head_msg = msg.buf;
> + ropts.default_reflog_action = DEFAULT_REFLOG_ACTION;
> + if (reset_head(the_repository, &ropts))
> + die(_("Could not reset"));
> + strbuf_release(&msg);
> + } else {
> + update_ref(NULL, opts->head_name,
> + &new_head->object.oid, NULL,
> + 0, UPDATE_REFS_DIE_ON_ERR);
> +
> + strvec_pushf(&args, "checkout");
> + strvec_pushf(&args, "--quiet");
> + strvec_pushf(&args, "%s", branch_name);
You want just strvec_pushl() here., or strvec_push(), but definitely not
strvec_pushf(). You're not using the formatting.
> +
> + run_command_v_opt(args.v, RUN_GIT_CMD);
> + strvec_clear(&args);
> + }
> + } else {
> + strvec_pushf(&args, "checkout");
> + strvec_pushf(&args, "--quiet");
> + strvec_pushf(&args, "%s", oid_to_hex(&new_head->object.oid));
Ditto.
> +
> + run_command_v_opt(args.v, RUN_GIT_CMD);
> + strvec_clear(&args);
> + }
> +}
> +
> static int rebase_config(const char *var, const char *value, void *data)
> {
> struct rebase_options *opts = data;
> @@ -1154,6 +1343,12 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
> N_("automatically re-schedule any `exec` that fails")),
> OPT_BOOL(0, "reapply-cherry-picks", &options.reapply_cherry_picks,
> N_("apply all changes, even those already present upstream")),
> + OPT_BIT(0, "recycle", &options.flags,
> + N_("Run a recycle, if possible. Fails otherwise."),
run not Run, and drop the "." at the end.
> + REBASE_RECYCLE_OR_FAIL),
> + OPT_BIT(0, "attempt-recycle", &options.flags,
> + N_("Run a recycle, if possible. Continue with other approaches if it can't be done."),
Ditto.
Also I think you want "OPT_BOOL"...?
> + REBASE_ATTEMPT_RECYCLE),
> OPT_END(),
> };
> int i;
> @@ -1234,6 +1429,20 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
> die(_("The --edit-todo action can only be used during "
> "interactive rebase."));
>
> + if (options.flags & (REBASE_RECYCLE_OR_FAIL | REBASE_ATTEMPT_RECYCLE)) {
> + if ((options.flags & (REBASE_RECYCLE_OR_FAIL | REBASE_ATTEMPT_RECYCLE)) ==
> + (REBASE_RECYCLE_OR_FAIL | REBASE_ATTEMPT_RECYCLE))
> + die(_("Can't use both --recycle and --attempt-recycle."));
You can use OPT_CMDMODE() to declare flags that are mutually exclusive,
but maybe it's not a good fit in this case.
> + if (options.flags & REBASE_INTERACTIVE_EXPLICIT)
> + die(_("Can't use --recycle/--attempt-recycle with interactive mode."));
> + if (options.strategy) {
> + die(_("Can't specify a strategy when using --recycle/--atempt-recycle."));
> + }
> + if (options.signoff) {
> + die(_("Can't use --signoff with --recycle/--atempt-recycle"));
> + }
Aside from capital, _() etc. these can also drop {}'s
> + printf(_("Recycled %s onto %s.\n"),
> + branch_name, options.onto_name);
> + recycle_wrapup(&options, branch_name,
> + new_head);
> + ret = 0;
> + goto cleanup;
> + }
> + } else
> + printf(_("upstream and onto do not share the same tree. "
> + "Can't run a recycle.\n"));
Don't use printf() when puts() would do (the latter case).
The else is missing {} (see CodingGuidelines). I.e. if one arm gets it
all of them get it.
next prev parent reply other threads:[~2022-04-22 23:25 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-04-22 18:37 [PATCH v1] rebase - recycle Edmundo Carmona Antoranz
2022-04-22 21:50 ` Junio C Hamano
2022-04-23 9:17 ` Edmundo Carmona Antoranz
2022-04-23 16:34 ` Junio C Hamano
2022-04-22 22:57 ` Ævar Arnfjörð Bjarmason [this message]
2022-04-23 9:12 ` Edmundo Carmona Antoranz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=220423.86bkwsra4a.gmgdl@evledraar.gmail.com \
--to=avarab@gmail.com \
--cc=eantoranz@gmail.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.