From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Subject: [PATCH 1/2] resolve-undo: allow resurrecting conflicted state that resolved to deletion
Date: Thu, 27 Jul 2023 14:46:22 -0700 [thread overview]
Message-ID: <xmqq3519auz5.fsf@gitster.g> (raw)
The resolve-undo index extension records up to three (mode, object
name) tuples for non-zero stages for each path that was resolved,
to be used to recreate the original conflicted state later when the
user requests.
The unmerge_index_entry_at() function uses the resolve-undo data to
do so, but it assumes that the path for which the conflicted state
needs to be recreated can be specified by the position in the
active_cache[] array. This obviously cannot salvage a conflicted
state that was resolved by removing them. A delete-modify conflict,
in which the change whose "modify" side made is a trivial typofix,
may legitimately be resolved to remove the path, and resolve-undo
extension does record the two (mode, object name) tuples for the
common ancestor version and their version, lacking our version.
Introduce a new unmerge_index_entry() helper function that takes the
path (which does not necessarily have to exist in the active_cache[]
array) and resolve-undo data, and use it to reimplement unmerge_index()
public function that is used by "git rerere".
The limited interface is still kept for now, as it is used by "git
checkout -m" and "git update-index --unmerge", but these two codepaths
will be updated to lift the assumption to allow conflicts that resolved
to deletion can be recreated.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
* No new tests, as unmerge_index() that is used by "git rerere"
already exercises the codepath. We'll use the new function also
in "update-index" in a future patch.
resolve-undo.c | 46 +++++++++++++++++++++++++++++++++++++++++-----
resolve-undo.h | 1 +
2 files changed, 42 insertions(+), 5 deletions(-)
diff --git a/resolve-undo.c b/resolve-undo.c
index 7817f5d6db..9ceab129ac 100644
--- a/resolve-undo.c
+++ b/resolve-undo.c
@@ -184,19 +184,55 @@ void unmerge_marked_index(struct index_state *istate)
}
}
+int unmerge_index_entry(struct index_state *istate, const char *path,
+ struct resolve_undo_info *ru)
+{
+ int i = index_name_pos(istate, path, strlen(path));
+
+ if (i < 0) {
+ /* unmerged? */
+ i = -i - 1;
+ if (i < istate->cache_nr &&
+ !strcmp(istate->cache[i]->name, path))
+ /* yes, it is already unmerged */
+ return 0;
+ /* fallthru: resolved to removal */
+ } else {
+ /* merged - remove it to replace it with unmerged entries */
+ remove_index_entry_at(istate, i);
+ }
+
+ for (i = 0; i < 3; i++) {
+ struct cache_entry *ce;
+ if (!ru->mode[i])
+ continue;
+ ce = make_cache_entry(istate, ru->mode[i], &ru->oid[i],
+ path, i + 1, 0);
+ if (add_index_entry(istate, ce, ADD_CACHE_OK_TO_ADD))
+ return error("cannot unmerge '%s'", path);
+ }
+ return 0;
+}
+
void unmerge_index(struct index_state *istate, const struct pathspec *pathspec)
{
- int i;
+ struct string_list_item *item;
if (!istate->resolve_undo)
return;
/* TODO: audit for interaction with sparse-index. */
ensure_full_index(istate);
- for (i = 0; i < istate->cache_nr; i++) {
- const struct cache_entry *ce = istate->cache[i];
- if (!ce_path_match(istate, ce, pathspec, NULL))
+
+ for_each_string_list_item(item, istate->resolve_undo) {
+ const char *path = item->string;
+ struct resolve_undo_info *ru = item->util;
+ if (!item->util)
+ continue;
+ if (!match_pathspec(istate, pathspec,
+ item->string, strlen(item->string),
+ 0, NULL, 0))
continue;
- i = unmerge_index_entry_at(istate, i);
+ unmerge_index_entry(istate, path, ru);
}
}
diff --git a/resolve-undo.h b/resolve-undo.h
index c5deafc92f..1ae321c88b 100644
--- a/resolve-undo.h
+++ b/resolve-undo.h
@@ -18,6 +18,7 @@ void resolve_undo_write(struct strbuf *, struct string_list *);
struct string_list *resolve_undo_read(const char *, unsigned long);
void resolve_undo_clear_index(struct index_state *);
int unmerge_index_entry_at(struct index_state *, int);
+int unmerge_index_entry(struct index_state *, const char *, struct resolve_undo_info *);
void unmerge_index(struct index_state *, const struct pathspec *);
void unmerge_marked_index(struct index_state *);
--
2.41.0-459-gb4fce4b6e4
next reply other threads:[~2023-07-27 21:46 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-27 21:46 Junio C Hamano [this message]
2023-07-27 21:51 ` [PATCH 2/2] update-index: use unmerge_index_entry() to support removal Junio C Hamano
2023-07-28 19:49 ` [PATCH 3/2] update-index: remove stale fallback code for "--unresolve" 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=xmqq3519auz5.fsf@gitster.g \
--to=gitster@pobox.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.