rebase-merges: try and use branch names as labels

When interactively rebasing merge commits, the commit message is parsed to
extract a probably meaningful label name. For instance if the merge commit
is “Merge branch 'feature0'”, then the rebase script will have thes lines:
```
label feature0

merge -C $sha feature0 # “Merge branch 'feature0'
```

This heuristic fails in the case of octopus merges or when the merge commit
message is actually unrelated to the parent commits.

An example that combines both is:
```
*---.   967bfa4 (HEAD -> integration) Integration
|\ \ \
| | | * 2135be1 (feature2, feat2) Feature 2
| |_|/
|/| |
| | * c88b01a Feature 1
| |/
|/|
| * 75f3139 (feat0) Feature 0
|/
* 25c86d0 (main) Initial commit
```
yields the labels Integration, Integration-2 and Integration-3.

Fix this by using a branch name for each merge commit's parent that is the
tip of at least one branch, and falling back to a label derived from the
merge commit message otherwise.
In the example above, the labels become feat0, Integration and feature2.

Signed-off-by: Nicolas Guichard <nicolas@guichard.eu>
Acked-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Nicolas Guichard
2024-10-09 07:58:20 +00:00
committed by Junio C Hamano
parent 68c9fcb027
commit 436892123d
3 changed files with 25 additions and 16 deletions

View File

@ -5819,7 +5819,7 @@ static int make_script_with_merges(struct pretty_print_context *pp,
int root_with_onto = flags & TODO_LIST_ROOT_WITH_ONTO;
int skipped_commit = 0;
struct strbuf buf = STRBUF_INIT, oneline = STRBUF_INIT;
struct strbuf label = STRBUF_INIT;
struct strbuf label_from_message = STRBUF_INIT;
struct commit_list *commits = NULL, **tail = &commits, *iter;
struct commit_list *tips = NULL, **tips_tail = &tips;
struct commit *commit;
@ -5842,6 +5842,7 @@ static int make_script_with_merges(struct pretty_print_context *pp,
oidmap_init(&state.commit2label, 0);
hashmap_init(&state.labels, labels_cmp, NULL, 0);
strbuf_init(&state.buf, 32);
load_branch_decorations();
if (revs->cmdline.nr && (revs->cmdline.rev[0].flags & BOTTOM)) {
struct labels_entry *onto_label_entry;
@ -5902,18 +5903,18 @@ static int make_script_with_merges(struct pretty_print_context *pp,
continue;
}
/* Create a label */
strbuf_reset(&label);
/* Create a label from the commit message */
strbuf_reset(&label_from_message);
if (skip_prefix(oneline.buf, "Merge ", &p1) &&
(p1 = strchr(p1, '\'')) &&
(p2 = strchr(++p1, '\'')))
strbuf_add(&label, p1, p2 - p1);
strbuf_add(&label_from_message, p1, p2 - p1);
else if (skip_prefix(oneline.buf, "Merge pull request ",
&p1) &&
(p1 = strstr(p1, " from ")))
strbuf_addstr(&label, p1 + strlen(" from "));
strbuf_addstr(&label_from_message, p1 + strlen(" from "));
else
strbuf_addbuf(&label, &oneline);
strbuf_addbuf(&label_from_message, &oneline);
strbuf_reset(&buf);
strbuf_addf(&buf, "%s -C %s",
@ -5921,6 +5922,14 @@ static int make_script_with_merges(struct pretty_print_context *pp,
/* label the tips of merged branches */
for (; to_merge; to_merge = to_merge->next) {
const char *label = label_from_message.buf;
const struct name_decoration *decoration =
get_name_decoration(&to_merge->item->object);
if (decoration)
skip_prefix(decoration->name, "refs/heads/",
&label);
oid = &to_merge->item->object.oid;
strbuf_addch(&buf, ' ');
@ -5933,7 +5942,7 @@ static int make_script_with_merges(struct pretty_print_context *pp,
tips_tail = &commit_list_insert(to_merge->item,
tips_tail)->next;
strbuf_addstr(&buf, label_oid(oid, label.buf, &state));
strbuf_addstr(&buf, label_oid(oid, label, &state));
}
strbuf_addf(&buf, " # %s", oneline.buf);
@ -6041,7 +6050,7 @@ static int make_script_with_merges(struct pretty_print_context *pp,
free_commit_list(commits);
free_commit_list(tips);
strbuf_release(&label);
strbuf_release(&label_from_message);
strbuf_release(&oneline);
strbuf_release(&buf);