summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2016-06-06 18:16:41 +0700
committerJunio C Hamano <gitster@pobox.com>2016-06-06 15:25:39 -0700
commit5e19b2444896dcdc2f44d096bf61cb57a6ca4388 (patch)
treea6067d7ead261833919cb932ba6e4a7627ca4a92
parent80bd6efc1a3f1f482f1d2212996a0d85fccfd7b3 (diff)
downloadgit-5e19b2444896dcdc2f44d096bf61cb57a6ca4388.tar.gz
Resurrect "diff-lib.c: adjust position of i-t-a entries in diff"
The original commit d95d728aba06a34394d15466045cbdabdada58a2 was reverted in commit 78cc1a540ba127b13f2f3fd531777b57f3a9cd46 because we were (and still are) not ready for a new world order. A lot more investigation must be done to see what is impacted. See the 78cc1a5 for details. This patch takes a smaller and safer step. The new behavior is controlled by SHIFT_INTENT_TO_ADD flag. We can gradually move more diff users to the new behavior after we are sure it's safe to do so. This flag is exposed to outside as "--shift-ita". Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--Documentation/diff-options.txt6
-rw-r--r--diff-lib.c14
-rw-r--r--diff.c2
-rw-r--r--diff.h1
-rwxr-xr-xt/t2203-add-intent.sh20
-rw-r--r--wt-status.c5
6 files changed, 46 insertions, 2 deletions
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 3cb301556e..904438b8c8 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -559,5 +559,11 @@ endif::git-format-patch[]
--no-prefix::
Do not show any source or destination prefix.
+--shift-ita::
+ By default entries added by "git add -N" appear as an existing
+ empty file in "git diff" and a new file in "git diff --cached".
+ This option makes the entry appear as a new file in "git diff"
+ and non-existent in "git diff --cached".
+
For more detailed explanation on these common options, see also
linkgit:gitdiffcore[7].
diff --git a/diff-lib.c b/diff-lib.c
index 27887d08d0..1248970f5a 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -212,6 +212,12 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
ce->sha1, !is_null_sha1(ce->sha1),
ce->name, 0);
continue;
+ } else if (DIFF_OPT_TST(&revs->diffopt, SHIFT_INTENT_TO_ADD) &&
+ ce_intent_to_add(ce)) {
+ diff_addremove(&revs->diffopt, '+', ce->ce_mode,
+ EMPTY_BLOB_SHA1_BIN, 0,
+ ce->name, 0);
+ continue;
}
changed = match_stat_with_submodule(&revs->diffopt, ce, &st,
@@ -376,6 +382,14 @@ static void do_oneway_diff(struct unpack_trees_options *o,
struct rev_info *revs = o->unpack_data;
int match_missing, cached;
+ /* i-t-a entries do not actually exist in the index */
+ if (DIFF_OPT_TST(&revs->diffopt, SHIFT_INTENT_TO_ADD) &&
+ idx && ce_intent_to_add(idx)) {
+ idx = NULL;
+ if (!tree)
+ return; /* nothing to diff.. */
+ }
+
/* if the entry is not checked out, don't examine work tree */
cached = o->index_only ||
(idx && ((idx->ce_flags & CE_VALID) || ce_skip_worktree(idx)));
diff --git a/diff.c b/diff.c
index f70425f6b3..b624e6479d 100644
--- a/diff.c
+++ b/diff.c
@@ -3910,6 +3910,8 @@ int diff_opt_parse(struct diff_options *options,
return parse_submodule_opt(options, arg);
else if (skip_prefix(arg, "--ws-error-highlight=", &arg))
return parse_ws_error_highlight(options, arg);
+ else if (!strcmp(arg, "--shift-ita"))
+ DIFF_OPT_SET(options, SHIFT_INTENT_TO_ADD);
/* misc options */
else if (!strcmp(arg, "-z"))
diff --git a/diff.h b/diff.h
index b497078c2f..9e42556dfc 100644
--- a/diff.h
+++ b/diff.h
@@ -92,6 +92,7 @@ typedef struct strbuf *(*diff_prefix_fn_t)(struct diff_options *opt, void *data)
#define DIFF_OPT_FUNCCONTEXT (1 << 29)
#define DIFF_OPT_PICKAXE_IGNORE_CASE (1 << 30)
#define DIFF_OPT_DEFAULT_FOLLOW_RENAMES (1U << 31)
+#define DIFF_OPT_SHIFT_INTENT_TO_ADD (1UL << 32)
#define DIFF_OPT_TST(opts, flag) ((opts)->flags & DIFF_OPT_##flag)
#define DIFF_OPT_TOUCHED(opts, flag) ((opts)->touched_flags & DIFF_OPT_##flag)
diff --git a/t/t2203-add-intent.sh b/t/t2203-add-intent.sh
index 2a4a749b4f..4ae98f44e7 100755
--- a/t/t2203-add-intent.sh
+++ b/t/t2203-add-intent.sh
@@ -5,10 +5,24 @@ test_description='Intent to add'
. ./test-lib.sh
test_expect_success 'intent to add' '
+ test_commit 1 &&
+ git rm 1.t &&
+ echo hello >1.t &&
echo hello >file &&
echo hello >elif &&
git add -N file &&
- git add elif
+ git add elif &&
+ git add -N 1.t
+'
+
+test_expect_success 'git status' '
+ git status --porcelain | grep -v actual >actual &&
+ cat >expect <<-\EOF &&
+ DA 1.t
+ A elif
+ A file
+ EOF
+ test_cmp expect actual
'
test_expect_success 'check result of "add -N"' '
@@ -43,7 +57,9 @@ test_expect_success 'i-t-a entry is simply ignored' '
git add -N nitfol &&
git commit -m second &&
test $(git ls-tree HEAD -- nitfol | wc -l) = 0 &&
- test $(git diff --name-only HEAD -- nitfol | wc -l) = 1
+ test $(git diff --name-only HEAD -- nitfol | wc -l) = 1 &&
+ test $(git diff --name-only --shift-ita HEAD -- nitfol | wc -l) = 0 &&
+ test $(git diff --name-only --shift-ita -- nitfol | wc -l) = 1
'
test_expect_success 'can commit with an unrelated i-t-a entry in index' '
diff --git a/wt-status.c b/wt-status.c
index 4f27bd62af..cb89005696 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -497,6 +497,7 @@ static void wt_status_collect_changes_worktree(struct wt_status *s)
setup_revisions(0, NULL, &rev, NULL);
rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
DIFF_OPT_SET(&rev.diffopt, DIRTY_SUBMODULES);
+ DIFF_OPT_SET(&rev.diffopt, SHIFT_INTENT_TO_ADD);
if (!s->show_untracked_files)
DIFF_OPT_SET(&rev.diffopt, IGNORE_UNTRACKED_IN_SUBMODULES);
if (s->ignore_submodule_arg) {
@@ -520,6 +521,7 @@ static void wt_status_collect_changes_index(struct wt_status *s)
setup_revisions(0, NULL, &rev, &opt);
DIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);
+ DIFF_OPT_SET(&rev.diffopt, SHIFT_INTENT_TO_ADD);
if (s->ignore_submodule_arg) {
handle_ignore_submodules_arg(&rev.diffopt, s->ignore_submodule_arg);
} else {
@@ -555,6 +557,8 @@ static void wt_status_collect_changes_initial(struct wt_status *s)
if (!ce_path_match(ce, &s->pathspec, NULL))
continue;
+ if (ce_intent_to_add(ce))
+ continue;
it = string_list_insert(&s->change, ce->name);
d = it->util;
if (!d) {
@@ -853,6 +857,7 @@ static void wt_status_print_verbose(struct wt_status *s)
init_revisions(&rev, NULL);
DIFF_OPT_SET(&rev.diffopt, ALLOW_TEXTCONV);
+ DIFF_OPT_SET(&rev.diffopt, SHIFT_INTENT_TO_ADD);
memset(&opt, 0, sizeof(opt));
opt.def = s->is_initial ? EMPTY_TREE_SHA1_HEX : s->reference;