Skip to content

Commit 425a28e

Browse files
pcloudsgitster
authored andcommitted
diff-lib: allow ita entries treated as "not yet exist in index"
When comparing the index and the working tree to show which paths are new, and comparing the tree recorded in the HEAD and the index to see if committing the contents recorded in the index would result in an empty commit, we would want the former comparison to say "these are new paths" and the latter to say "there is no change" for paths that are marked as intent-to-add. We made a similar attempt at d95d728 ("diff-lib.c: adjust position of i-t-a entries in diff", 2015-03-16), which redefined the semantics of these two comparison modes globally, which was a disaster and had to be reverted at 78cc1a5 ("Revert "diff-lib.c: adjust position of i-t-a entries in diff"", 2015-06-23). To make sure we do not repeat the same mistake, introduce a new internal diffopt option so that this different semantics can be asked for only by callers that ask it, while making sure other unaudited callers will get the same comparison result. Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 21f862b commit 425a28e

File tree

5 files changed

+38
-4
lines changed

5 files changed

+38
-4
lines changed

diff-lib.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,12 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
214214
!is_null_oid(&ce->oid),
215215
ce->name, 0);
216216
continue;
217+
} else if (revs->diffopt.ita_invisible_in_index &&
218+
ce_intent_to_add(ce)) {
219+
diff_addremove(&revs->diffopt, '+', ce->ce_mode,
220+
EMPTY_BLOB_SHA1_BIN, 0,
221+
ce->name, 0);
222+
continue;
217223
}
218224

219225
changed = match_stat_with_submodule(&revs->diffopt, ce, &st,
@@ -379,6 +385,14 @@ static void do_oneway_diff(struct unpack_trees_options *o,
379385
struct rev_info *revs = o->unpack_data;
380386
int match_missing, cached;
381387

388+
/* i-t-a entries do not actually exist in the index */
389+
if (revs->diffopt.ita_invisible_in_index &&
390+
idx && ce_intent_to_add(idx)) {
391+
idx = NULL;
392+
if (!tree)
393+
return; /* nothing to diff.. */
394+
}
395+
382396
/* if the entry is not checked out, don't examine work tree */
383397
cached = o->index_only ||
384398
(idx && ((idx->ce_flags & CE_VALID) || ce_skip_worktree(idx)));

diff.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ struct diff_options {
146146
int dirstat_permille;
147147
int setup;
148148
int abbrev;
149+
int ita_invisible_in_index;
149150
/* white-space error highlighting */
150151
#define WSEH_NEW 1
151152
#define WSEH_CONTEXT 2

t/t2203-add-intent.sh

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,24 @@ test_description='Intent to add'
55
. ./test-lib.sh
66

77
test_expect_success 'intent to add' '
8+
test_commit 1 &&
9+
git rm 1.t &&
10+
echo hello >1.t &&
811
echo hello >file &&
912
echo hello >elif &&
1013
git add -N file &&
11-
git add elif
14+
git add elif &&
15+
git add -N 1.t
16+
'
17+
18+
test_expect_success 'git status' '
19+
git status --porcelain | grep -v actual >actual &&
20+
cat >expect <<-\EOF &&
21+
DA 1.t
22+
A elif
23+
A file
24+
EOF
25+
test_cmp expect actual
1226
'
1327

1428
test_expect_success 'check result of "add -N"' '

t/t7064-wtstatus-pv2.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,8 @@ test_expect_success 'verify --intent-to-add output' '
246246
git add --intent-to-add intent1.add intent2.add &&
247247
248248
cat >expect <<-EOF &&
249-
1 AM N... 000000 100644 100644 $_z40 $EMPTY_BLOB intent1.add
250-
1 AM N... 000000 100644 100644 $_z40 $EMPTY_BLOB intent2.add
249+
1 .A N... 000000 000000 100644 $_z40 $_z40 intent1.add
250+
1 .A N... 000000 000000 100644 $_z40 $_z40 intent2.add
251251
EOF
252252
253253
git status --porcelain=v2 >actual &&

wt-status.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ static void wt_status_collect_changed_cb(struct diff_queue_struct *q,
437437

438438
switch (p->status) {
439439
case DIFF_STATUS_ADDED:
440-
die("BUG: worktree status add???");
440+
d->mode_worktree = p->two->mode;
441441
break;
442442

443443
case DIFF_STATUS_DELETED:
@@ -547,6 +547,7 @@ static void wt_status_collect_changes_worktree(struct wt_status *s)
547547
setup_revisions(0, NULL, &rev, NULL);
548548
rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
549549
DIFF_OPT_SET(&rev.diffopt, DIRTY_SUBMODULES);
550+
rev.diffopt.ita_invisible_in_index = 1;
550551
if (!s->show_untracked_files)
551552
DIFF_OPT_SET(&rev.diffopt, IGNORE_UNTRACKED_IN_SUBMODULES);
552553
if (s->ignore_submodule_arg) {
@@ -570,6 +571,7 @@ static void wt_status_collect_changes_index(struct wt_status *s)
570571
setup_revisions(0, NULL, &rev, &opt);
571572

572573
DIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);
574+
rev.diffopt.ita_invisible_in_index = 1;
573575
if (s->ignore_submodule_arg) {
574576
handle_ignore_submodules_arg(&rev.diffopt, s->ignore_submodule_arg);
575577
} else {
@@ -605,6 +607,8 @@ static void wt_status_collect_changes_initial(struct wt_status *s)
605607

606608
if (!ce_path_match(ce, &s->pathspec, NULL))
607609
continue;
610+
if (ce_intent_to_add(ce))
611+
continue;
608612
it = string_list_insert(&s->change, ce->name);
609613
d = it->util;
610614
if (!d) {
@@ -911,6 +915,7 @@ static void wt_longstatus_print_verbose(struct wt_status *s)
911915

912916
init_revisions(&rev, NULL);
913917
DIFF_OPT_SET(&rev.diffopt, ALLOW_TEXTCONV);
918+
rev.diffopt.ita_invisible_in_index = 1;
914919

915920
memset(&opt, 0, sizeof(opt));
916921
opt.def = s->is_initial ? EMPTY_TREE_SHA1_HEX : s->reference;

0 commit comments

Comments
 (0)