Skip to content

Commit 90e8b9b

Browse files
committed
Merge branch 'jc/fix-add-u-unmerged' into maint
* jc/fix-add-u-unmerged: Fix "add -u" that sometimes fails to resolve unmerged paths Conflicts: builtin/add.c
2 parents 81f9068 + 75973b2 commit 90e8b9b

File tree

2 files changed

+30
-39
lines changed

2 files changed

+30
-39
lines changed

builtin/add.c

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,27 @@ struct update_callback_data {
2626
int add_errors;
2727
};
2828

29+
static int fix_unmerged_status(struct diff_filepair *p,
30+
struct update_callback_data *data)
31+
{
32+
if (p->status != DIFF_STATUS_UNMERGED)
33+
return p->status;
34+
if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL) && !p->two->mode)
35+
/*
36+
* This is not an explicit add request, and the
37+
* path is missing from the working tree (deleted)
38+
*/
39+
return DIFF_STATUS_DELETED;
40+
else
41+
/*
42+
* Either an explicit add request, or path exists
43+
* in the working tree. An attempt to explicitly
44+
* add a path that does not exist in the working tree
45+
* will be caught as an error by the caller immediately.
46+
*/
47+
return DIFF_STATUS_MODIFIED;
48+
}
49+
2950
static void update_callback(struct diff_queue_struct *q,
3051
struct diff_options *opt, void *cbdata)
3152
{
@@ -35,30 +56,9 @@ static void update_callback(struct diff_queue_struct *q,
3556
for (i = 0; i < q->nr; i++) {
3657
struct diff_filepair *p = q->queue[i];
3758
const char *path = p->one->path;
38-
switch (p->status) {
59+
switch (fix_unmerged_status(p, data)) {
3960
default:
4061
die(_("unexpected diff status %c"), p->status);
41-
case DIFF_STATUS_UNMERGED:
42-
/*
43-
* ADD_CACHE_IGNORE_REMOVAL is unset if "git
44-
* add -u" is calling us, In such a case, a
45-
* missing work tree file needs to be removed
46-
* if there is an unmerged entry at stage #2,
47-
* but such a diff record is followed by
48-
* another with DIFF_STATUS_DELETED (and if
49-
* there is no stage #2, we won't see DELETED
50-
* nor MODIFIED). We can simply continue
51-
* either way.
52-
*/
53-
if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL))
54-
continue;
55-
/*
56-
* Otherwise, it is "git add path" is asking
57-
* to explicitly add it; we fall through. A
58-
* missing work tree file is an error and is
59-
* caught by add_file_to_index() in such a
60-
* case.
61-
*/
6262
case DIFF_STATUS_MODIFIED:
6363
case DIFF_STATUS_TYPE_CHANGED:
6464
if (add_file_to_index(&the_index, path, data->flags)) {
@@ -91,6 +91,7 @@ int add_files_to_cache(const char *prefix, const char **pathspec, int flags)
9191
data.flags = flags;
9292
data.add_errors = 0;
9393
rev.diffopt.format_callback_data = &data;
94+
rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
9495
run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
9596
return !!data.add_errors;
9697
}

t/t2200-add-update.sh

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -149,31 +149,21 @@ test_expect_success 'add -u resolves unmerged paths' '
149149
echo 3 >path1 &&
150150
echo 2 >path3 &&
151151
echo 2 >path5 &&
152-
git add -u &&
153-
git ls-files -s path1 path2 path3 path4 path5 path6 >actual &&
154-
{
155-
echo "100644 $three 0 path1"
156-
echo "100644 $one 1 path3"
157-
echo "100644 $one 1 path4"
158-
echo "100644 $one 3 path5"
159-
echo "100644 $one 3 path6"
160-
} >expect &&
161-
test_cmp expect actual &&
162152
163-
# Bonus tests. Explicit resolving
164-
git add path3 path5 &&
153+
# Explicit resolving by adding removed paths should fail
165154
test_must_fail git add path4 &&
166155
test_must_fail git add path6 &&
167-
git rm path4 &&
168-
git rm path6 &&
169156
170-
git ls-files -s "path?" >actual &&
157+
# "add -u" should notice removals no matter what stages
158+
# the index entries are in.
159+
git add -u &&
160+
git ls-files -s path1 path2 path3 path4 path5 path6 >actual &&
171161
{
172162
echo "100644 $three 0 path1"
173163
echo "100644 $two 0 path3"
174164
echo "100644 $two 0 path5"
175-
} >expect
176-
165+
} >expect &&
166+
test_cmp expect actual
177167
'
178168

179169
test_expect_success '"add -u non-existent" should fail' '

0 commit comments

Comments
 (0)