From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Subject: [PATCH 7/7] checkout: allow "checkout -m path" to unmerge removed paths
Date: Mon, 31 Jul 2023 15:44:09 -0700 [thread overview]
Message-ID: <20230731224409.4181277-8-gitster@pobox.com> (raw)
In-Reply-To: <20230731224409.4181277-1-gitster@pobox.com>
"git checkout -m -- path" uses the unmerge_marked_index() API, whose
implementation is incapable of unresolving a path that was resolved
as removed. Extend the unmerge_index() API function so that we can
mark the ce_flags member of the cache entries we add to the index as
unmerged, and replace use of unmerge_marked_index() with it.
Now, together with its unmerge_index_entry_at() helper function,
unmerge_marked_index() function is no longer called by anybody, and
can safely be removed.
This makes two known test failures in t2070 and t7201 to succeed.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
builtin/checkout.c | 6 ++--
builtin/update-index.c | 2 +-
rerere.c | 2 +-
resolve-undo.c | 75 +++---------------------------------------
resolve-undo.h | 6 ++--
t/t2070-restore.sh | 2 +-
t/t7201-co.sh | 2 +-
7 files changed, 13 insertions(+), 82 deletions(-)
diff --git a/builtin/checkout.c b/builtin/checkout.c
index b8dfba57c6..98fcf1220a 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -566,6 +566,8 @@ static int checkout_paths(const struct checkout_opts *opts,
if (opts->source_tree)
read_tree_some(opts->source_tree, &opts->pathspec);
+ if (opts->merge)
+ unmerge_index(&the_index, &opts->pathspec, CE_MATCHED);
ps_matched = xcalloc(opts->pathspec.nr, 1);
@@ -589,10 +591,6 @@ static int checkout_paths(const struct checkout_opts *opts,
}
free(ps_matched);
- /* "checkout -m path" to recreate conflicted state */
- if (opts->merge)
- unmerge_marked_index(&the_index);
-
/* Any unmerged paths? */
for (pos = 0; pos < the_index.cache_nr; pos++) {
const struct cache_entry *ce = the_index.cache[pos];
diff --git a/builtin/update-index.c b/builtin/update-index.c
index def7f98504..69fe9c8fcb 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -646,7 +646,7 @@ static int unresolve_one(const char *path)
item = string_list_lookup(the_index.resolve_undo, path);
if (!item)
return res; /* no resolve-undo record for the path */
- res = unmerge_index_entry(&the_index, path, item->util);
+ res = unmerge_index_entry(&the_index, path, item->util, 0);
FREE_AND_NULL(item->util);
return res;
}
diff --git a/rerere.c b/rerere.c
index e968d413d6..b525dd9230 100644
--- a/rerere.c
+++ b/rerere.c
@@ -1112,7 +1112,7 @@ int rerere_forget(struct repository *r, struct pathspec *pathspec)
* recover the original conflicted state and then
* find the conflicted paths.
*/
- unmerge_index(r->index, pathspec);
+ unmerge_index(r->index, pathspec, 0);
find_conflict(r, &conflict);
for (i = 0; i < conflict.nr; i++) {
struct string_list_item *it = &conflict.items[i];
diff --git a/resolve-undo.c b/resolve-undo.c
index 3b0244e210..8e5a8072ed 100644
--- a/resolve-undo.c
+++ b/resolve-undo.c
@@ -115,75 +115,8 @@ void resolve_undo_clear_index(struct index_state *istate)
istate->cache_changed |= RESOLVE_UNDO_CHANGED;
}
-int unmerge_index_entry_at(struct index_state *istate, int pos)
-{
- const struct cache_entry *ce;
- struct string_list_item *item;
- struct resolve_undo_info *ru;
- int i, err = 0, matched;
- char *name;
-
- if (!istate->resolve_undo)
- return pos;
-
- ce = istate->cache[pos];
- if (ce_stage(ce)) {
- /* already unmerged */
- while ((pos < istate->cache_nr) &&
- ! strcmp(istate->cache[pos]->name, ce->name))
- pos++;
- return pos - 1; /* return the last entry processed */
- }
- item = string_list_lookup(istate->resolve_undo, ce->name);
- if (!item)
- return pos;
- ru = item->util;
- if (!ru)
- return pos;
- matched = ce->ce_flags & CE_MATCHED;
- name = xstrdup(ce->name);
- remove_index_entry_at(istate, pos);
- for (i = 0; i < 3; i++) {
- struct cache_entry *nce;
- if (!ru->mode[i])
- continue;
- nce = make_cache_entry(istate,
- ru->mode[i],
- &ru->oid[i],
- name, i + 1, 0);
- if (matched)
- nce->ce_flags |= CE_MATCHED;
- if (add_index_entry(istate, nce, ADD_CACHE_OK_TO_ADD)) {
- err = 1;
- error("cannot unmerge '%s'", name);
- }
- }
- free(name);
- if (err)
- return pos;
- free(ru);
- item->util = NULL;
- return unmerge_index_entry_at(istate, pos);
-}
-
-void unmerge_marked_index(struct index_state *istate)
-{
- int i;
-
- 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->ce_flags & CE_MATCHED)
- i = unmerge_index_entry_at(istate, i);
- }
-}
-
int unmerge_index_entry(struct index_state *istate, const char *path,
- struct resolve_undo_info *ru)
+ struct resolve_undo_info *ru, unsigned ce_flags)
{
int i = index_name_pos(istate, path, strlen(path));
@@ -206,13 +139,15 @@ int unmerge_index_entry(struct index_state *istate, const char *path,
continue;
ce = make_cache_entry(istate, ru->mode[i], &ru->oid[i],
path, i + 1, 0);
+ ce->ce_flags |= ce_flags;
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)
+void unmerge_index(struct index_state *istate, const struct pathspec *pathspec,
+ unsigned ce_flags)
{
struct string_list_item *item;
@@ -231,7 +166,7 @@ void unmerge_index(struct index_state *istate, const struct pathspec *pathspec)
item->string, strlen(item->string),
0, NULL, 0))
continue;
- unmerge_index_entry(istate, path, ru);
+ unmerge_index_entry(istate, path, ru, ce_flags);
free(ru);
item->util = NULL;
}
diff --git a/resolve-undo.h b/resolve-undo.h
index 1ae321c88b..f3f8462751 100644
--- a/resolve-undo.h
+++ b/resolve-undo.h
@@ -17,9 +17,7 @@ void record_resolve_undo(struct index_state *, struct cache_entry *);
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 *);
+int unmerge_index_entry(struct index_state *, const char *, struct resolve_undo_info *, unsigned);
+void unmerge_index(struct index_state *, const struct pathspec *, unsigned);
#endif
diff --git a/t/t2070-restore.sh b/t/t2070-restore.sh
index d97ecc2483..16d6348b69 100755
--- a/t/t2070-restore.sh
+++ b/t/t2070-restore.sh
@@ -180,7 +180,7 @@ test_expect_success 'restore --merge to unresolve after (mistaken) resolution' '
test_cmp expect file
'
-test_expect_failure 'restore --merge to unresolve after (mistaken) resolution' '
+test_expect_success 'restore --merge to unresolve after (mistaken) resolution' '
O=$(echo original | git hash-object -w --stdin) &&
A=$(echo ourside | git hash-object -w --stdin) &&
B=$(echo theirside | git hash-object -w --stdin) &&
diff --git a/t/t7201-co.sh b/t/t7201-co.sh
index 4b07a26c14..df582295df 100755
--- a/t/t7201-co.sh
+++ b/t/t7201-co.sh
@@ -543,7 +543,7 @@ test_expect_success 'checkout -m works after (mistaken) resolution' '
test_cmp merged file
'
-test_expect_failure 'checkout -m works after (mistaken) resolution to remove' '
+test_expect_success 'checkout -m works after (mistaken) resolution to remove' '
setup_conflicting_index &&
echo "none of the above" >sample &&
cat sample >fild &&
--
2.41.0-478-gee48e70a82
next prev parent reply other threads:[~2023-07-31 22:45 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-31 22:44 [PATCH 0/7] unresolve removal Junio C Hamano
2023-07-31 22:44 ` [PATCH 1/7] update-index: do not read HEAD and MERGE_HEAD unconditionally Junio C Hamano
2023-07-31 22:44 ` [PATCH 2/7] resolve-undo: allow resurrecting conflicted state that resolved to deletion Junio C Hamano
2023-07-31 22:44 ` [PATCH 3/7] update-index: use unmerge_index_entry() to support removal Junio C Hamano
2023-07-31 23:14 ` Junio C Hamano
2023-07-31 22:44 ` [PATCH 4/7] update-index: remove stale fallback code for "--unresolve" Junio C Hamano
2023-07-31 22:44 ` [PATCH 5/7] checkout/restore: refuse unmerging paths unless checking out of the index Junio C Hamano
2023-07-31 22:44 ` [PATCH 6/7] checkout/restore: add basic tests for --merge Junio C Hamano
2023-07-31 22:44 ` Junio C Hamano [this message]
2023-08-04 19:03 ` [PATCH 0/7] unresolve removal Taylor Blau
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=20230731224409.4181277-8-gitster@pobox.com \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).