Git development
 help / color / mirror / Atom feed
From: Phillip Wood <phillip.wood123@gmail.com>
To: git@vger.kernel.org
Cc: Elijah Newren <newren@gmail.com>, Johannes Sixt <j6t@kdbg.org>,
	Phillip Wood <phillip.wood123@gmail.com>
Subject: [PATCH v2 0/2] checkout -m: recreate conflict labels
Date: Mon,  5 Oct 2026 14:24:47 +0100	[thread overview]
Message-ID: <cover.1791206658.git.phillip.wood@dunelm.org.uk> (raw)
In-Reply-To: <cover.1790761727.git.phillip.wood@dunelm.org.uk>

When "git checkout -m <path>" recreates a merge conflict, it uses
the labels "base", "ours", "theirs", rather than the labels used by
the original merge. This short series teaches the ort machinery to
write the labels to ".git/MERGE_LABELS" when it switches to a merge
result containing conflicts, so that "git checkout -m" can then read
that file and use the same labels.

As "git checkout -m" is recreating the original conflict I wonder
if we should remember the conflict style as well so that

    git -c merge.conflictStyle=diff3 git merge topic
    git checkout -m <unmerged-path>

would recreate diff3 style conflicts, instead of using the default
config. I cannot decide if that would be convenient or confusing and
am interested to hear what others think.

Changes since V1:

 - use strbuf_getline() rather than strbuf_read_file() to read labels
   so that the newline handling of the reading and writing sides match.

NB ".git/MERGE_LABELS" is still undocumented - I'm hoping to find time
to add some documentation for all the MERGE_* files in a future series.
Johannes suggested using an index extension to store the labels,
but as we already have MERGE_MODE, MERGE_RR and MERGE_MSG I think it
is easier just to add another file.

base-commit: 3bc0341126508f78f5869cbfc0005e987efdf0c7
Published-As: https://github.com/phillipwood/git/releases/tag/pw%2Fconflict-labels%2Fv2
View-Changes-At: https://github.com/phillipwood/git/compare/3bc034112...18bdf7df4
Fetch-It-Via: git fetch https://github.com/phillipwood/git pw/conflict-labels/v2


Phillip Wood (2):
  remove_branch_state: convert boolean argument to flags
  merge: remember conflict labels

 branch.c           | 17 ++++++++----
 branch.h           |  4 ++-
 builtin/checkout.c | 30 ++++++++++++++++++----
 builtin/commit.c   |  1 +
 merge-ort.c        | 19 ++++++++++++++
 merge.c            | 64 ++++++++++++++++++++++++++++++++++++++++++++++
 merge.h            |  4 +++
 path.c             |  1 +
 path.h             |  1 +
 repository.c       |  1 +
 repository.h       |  1 +
 sequencer.c        |  1 +
 t/t7201-co.sh      | 21 +++++++++++++++
 13 files changed, 154 insertions(+), 11 deletions(-)

Range-diff against v1:
1:  86ef0f848a = 1:  86ef0f848a remove_branch_state: convert boolean argument to flags
2:  fdaf3da993 ! 2:  18bdf7df49 merge: remember conflict labels
    @@ merge.c: int checkout_fast_forward(struct repository *r,
     +	return 0;
     +}
     +
    -+static int parse_merge_label_line(const char **p, char **line)
    ++static char *parse_merge_label_line(struct strbuf *buf, FILE *fp)
     +{
    -+	const char *eol = strchr(*p, '\n');
    -+
    -+	if (!eol)
    -+		return -1;
    -+
    -+	*line = xmemdupz(*p, eol - *p);
    -+	*p = eol + 1;
    -+
    -+	return 0;
    ++	if (strbuf_getline(buf, fp) == EOF)
    ++		return NULL;
    ++
    ++	return xmemdupz(buf->buf, buf->len);
     +}
     +
     +int read_merge_labels(struct repository *r,
     +		      char **pbase, char** pours, char** ptheirs)
     +{
     +	struct strbuf buf = STRBUF_INIT;
    -+	const char *p;
     +	char *base = NULL, *ours = NULL, *theirs = NULL;
     +	int ret = -1;
    ++	FILE *fp = fopen(git_path_merge_labels(r), "r");
     +
    -+	if (strbuf_read_file(&buf, git_path_merge_labels(r), 0) < 0)
    ++	if (!fp)
     +		return -1;
     +
    -+	p = buf.buf;
    -+	if (parse_merge_label_line(&p, &base))
    -+		goto out;
    -+	if (parse_merge_label_line(&p, &ours))
    -+		goto out;
    -+	if (parse_merge_label_line(&p, &theirs))
    -+		goto out;
    ++	base = parse_merge_label_line(&buf, fp);
    ++	if (!base)
    ++		goto out;
    ++
    ++	ours = parse_merge_label_line(&buf, fp);
    ++	if (!ours)
    ++		goto out;
    ++
    ++	theirs = parse_merge_label_line(&buf, fp);
    ++	if (!theirs)
    ++		goto out;
    ++
     +	ret = 0;
     +	*pbase = base;
     +	*pours = ours;
    @@ merge.c: int checkout_fast_forward(struct repository *r,
     +		free(ours);
     +		free(theirs);
     +	}
    ++	fclose(fp);
     +	strbuf_release(&buf);
     +
     +	return ret;
-- 
2.56.0.134.g299a3c16181


  parent reply	other threads:[~2026-10-05 13:25 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-30  9:48 [PATCH 0/2] checkout -m: recreate conflict labels Phillip Wood
2026-09-30  9:48 ` [PATCH 1/2] remove_branch_state: convert boolean argument to flags Phillip Wood
2026-09-30  9:48 ` [PATCH 2/2] merge: remember conflict labels Phillip Wood
2026-09-30 16:42   ` Junio C Hamano
2026-10-01  8:54     ` Phillip Wood
2026-10-01 17:14       ` Junio C Hamano
2026-09-30 20:24 ` [PATCH 0/2] checkout -m: recreate " Johannes Sixt
2026-09-30 20:40   ` Junio C Hamano
2026-09-30 21:20     ` Johannes Sixt
2026-10-01  8:45   ` Phillip Wood
2026-10-05 13:24 ` Phillip Wood [this message]
2026-10-05 13:24   ` [PATCH v2 1/2] remove_branch_state: convert boolean argument to flags Phillip Wood
2026-10-05 13:24   ` [PATCH v2 2/2] merge: remember conflict labels Phillip Wood
2026-10-05 16:19     ` Junio C Hamano
2026-10-06 15:21       ` Phillip Wood
2026-10-05 16:31     ` Junio C Hamano
2026-10-06 15:05       ` Phillip Wood
2026-10-06 15:46     ` Junio C Hamano
2026-10-07 13:38       ` Phillip Wood
2026-10-05 14:48   ` [PATCH v2 0/2] checkout -m: recreate " Johannes Sixt
2026-10-05 15:09     ` Phillip Wood
2026-10-05 15:53   ` Junio C Hamano
2026-10-09  9:13 ` [PATCH v3 " Phillip Wood
2026-10-09  9:13   ` [PATCH v3 1/2] remove_branch_state: convert boolean argument to flags Phillip Wood
2026-10-09  9:13   ` [PATCH v3 2/2] merge: remember conflict labels Phillip Wood
2026-10-10  0:24     ` Junio C Hamano
2026-10-09 20:31   ` [PATCH v3 0/2] checkout -m: recreate " Junio C Hamano

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=cover.1791206658.git.phillip.wood@dunelm.org.uk \
    --to=phillip.wood123@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=j6t@kdbg.org \
    --cc=newren@gmail.com \
    --cc=phillip.wood@dunelm.org.uk \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox