{"thread":{"id":"40154","subject":"[PATCH 7/8] diff.h: extend \"flags\" field to 64 bits because we're out of bits","startedAt":"2015-08-22T01:14:22Z","lastAt":"2015-08-22T01:14:38Z","messageCount":2,"participants":["Nguyễn Thái Ngọc Duy"],"isPatch":true,"patchVersion":1,"patchTotal":8},"messages":[{"id":"268482","messageId":"1440206062-20504-1-git-send-email-pclouds@gmail.com","threadId":"40154","inReplyTo":"1440205700-19749-1-git-send-email-pclouds","subject":"[PATCH 7/8] diff.h: extend \"flags\" field to 64 bits because we're out of bits","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2015-08-22T01:14:22Z","receivedAt":"2015-08-22T01:14:22Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"I renamed both \"flags\" and \"touched_flags\" fields while making this\npatch to make sure I was aware of how these flags were manipulated\n(besides DIFF_OPT* macros). So hopefully I didn't miss anything.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n Resend to the right recipients. I screwed send-email up..\n\n builtin/commit.c | 2 +-\n diff-lib.c       | 4 ++--\n diff.c           | 2 +-\n diff.h           | 8 +++++---\n 4 files changed, 9 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 4cbd5ff..95f7296 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -895,7 +895,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,\n \t\t\t * submodules which were manually staged, which would\n \t\t\t * be really confusing.\n \t\t\t */\n-\t\t\tint diff_flags = DIFF_OPT_OVERRIDE_SUBMODULE_CONFIG;\n+\t\t\tdiff_flags_t diff_flags = DIFF_OPT_OVERRIDE_SUBMODULE_CONFIG;\n \t\t\tif (ignore_submodule_arg &&\n \t\t\t    !strcmp(ignore_submodule_arg, \"all\"))\n \t\t\t\tdiff_flags |= DIFF_OPT_IGNORE_SUBMODULES;\ndiff --git a/diff-lib.c b/diff-lib.c\nindex 241a843..ae09034 100644\n--- a/diff-lib.c\n+++ b/diff-lib.c\n@@ -71,7 +71,7 @@ static int match_stat_with_submodule(struct diff_options *diffopt,\n {\n \tint changed = ce_match_stat(ce, st, ce_option);\n \tif (S_ISGITLINK(ce->ce_mode)) {\n-\t\tunsigned orig_flags = diffopt->flags;\n+\t\tdiff_flags_t orig_flags = diffopt->flags;\n \t\tif (!DIFF_OPT_TST(diffopt, OVERRIDE_SUBMODULE_CONFIG))\n \t\t\tset_diffopt_flags_from_submodule_config(diffopt, ce->name);\n \t\tif (DIFF_OPT_TST(diffopt, IGNORE_SUBMODULES))\n@@ -516,7 +516,7 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt)\n \treturn 0;\n }\n \n-int index_differs_from(const char *def, int diff_flags)\n+int index_differs_from(const char *def, diff_flags_t diff_flags)\n {\n \tstruct rev_info rev;\n \tstruct setup_revision_opt opt;\ndiff --git a/diff.c b/diff.c\nindex 7deac90..2485870 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -4912,7 +4912,7 @@ int diff_can_quit_early(struct diff_options *opt)\n static int is_submodule_ignored(const char *path, struct diff_options *options)\n {\n \tint ignored = 0;\n-\tunsigned orig_flags = options->flags;\n+\tdiff_flags_t orig_flags = options->flags;\n \tif (!DIFF_OPT_TST(options, OVERRIDE_SUBMODULE_CONFIG))\n \t\tset_diffopt_flags_from_submodule_config(options, path);\n \tif (DIFF_OPT_TST(options, IGNORE_SUBMODULES))\ndiff --git a/diff.h b/diff.h\nindex f7208ad..4241aa5 100644\n--- a/diff.h\n+++ b/diff.h\n@@ -110,13 +110,15 @@ enum diff_words_type {\n \tDIFF_WORDS_COLOR\n };\n \n+typedef uint64_t diff_flags_t;\n+\n struct diff_options {\n \tconst char *orderfile;\n \tconst char *pickaxe;\n \tconst char *single_follow;\n \tconst char *a_prefix, *b_prefix;\n-\tunsigned flags;\n-\tunsigned touched_flags;\n+\tdiff_flags_t flags;\n+\tdiff_flags_t touched_flags;\n \n \t/* diff-filter bits */\n \tunsigned int filter;\n@@ -347,7 +349,7 @@ extern int diff_result_code(struct diff_options *, int);\n \n extern void diff_no_index(struct rev_info *, int, const char **, const char *);\n \n-extern int index_differs_from(const char *def, int diff_flags);\n+extern int index_differs_from(const char *def, diff_flags_t diff_flags);\n \n extern size_t fill_textconv(struct userdiff_driver *driver,\n \t\t\t    struct diff_filespec *df,\n-- \n2.3.0.rc1.137.g477eb31\n"},{"id":"268483","messageId":"1440206078-20559-1-git-send-email-pclouds@gmail.com","threadId":"40154","inReplyTo":"1440205700-19749-1-git-send-email-pclouds","subject":"[PATCH 8/8] Resurrect \"diff-lib.c: adjust position of i-t-a entries in diff\"","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2015-08-22T01:14:38Z","receivedAt":"2015-08-22T01:14:38Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"The original commit d95d728aba06a34394d15466045cbdabdada58a2 was\nreverted in commit 78cc1a540ba127b13f2f3fd531777b57f3a9cd46 because we\nwere (and still are) not ready for a new world order. A lot more\ninvestigation must be done to see what is impacted. See the 78cc1a5 for\ndetails.\n\nThis patch takes a smaller and safer step. The new behavior is\ncontrolled by SHIFT_INTENT_TO_ADD flag. We can gradually move more diff\nusers to the new behavior after we are sure it's safe to do so. This\nflag is exposed to outside as \"--shift-ita\".\n\n\"git status\" sets this flag unconditionally to display i-t-a entries\ncorrectly. See d95d728 for details about \"git status\" and i-t-a entries.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n Documentation/diff-options.txt |  6 ++++++\n diff-lib.c                     | 14 ++++++++++++++\n diff.c                         |  2 ++\n diff.h                         |  1 +\n t/t2203-add-intent.sh          | 20 ++++++++++++++++++--\n wt-status.c                    |  2 ++\n 6 files changed, 43 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt\nindex d56ca90..b69db29 100644\n--- a/Documentation/diff-options.txt\n+++ b/Documentation/diff-options.txt\n@@ -556,5 +556,11 @@ endif::git-format-patch[]\n --no-prefix::\n \tDo not show any source or destination prefix.\n \n+--shift-ita::\n+\tBy default entries added by \"git add -N\" appear as an existing\n+\tempty file in \"git diff\" and a new file in \"git diff --cached\".\n+\tThis option makes the entry appear as a new file in \"git diff\"\n+\tand non-existent in \"git diff --cached\".\n+\n For more detailed explanation on these common options, see also\n linkgit:gitdiffcore[7].\ndiff --git a/diff-lib.c b/diff-lib.c\nindex ae09034..2546f5a 100644\n--- a/diff-lib.c\n+++ b/diff-lib.c\n@@ -212,6 +212,12 @@ int run_diff_files(struct rev_info *revs, unsigned int option)\n \t\t\t\t\t       ce->sha1, !is_null_sha1(ce->sha1),\n \t\t\t\t\t       ce->name, 0);\n \t\t\t\tcontinue;\n+\t\t\t} else if (DIFF_OPT_TST(&revs->diffopt, SHIFT_INTENT_TO_ADD) &&\n+\t\t\t\t   ce_intent_to_add(ce)) {\n+\t\t\t\tdiff_addremove(&revs->diffopt, '+', ce->ce_mode,\n+\t\t\t\t\t       EMPTY_BLOB_SHA1_BIN, 0,\n+\t\t\t\t\t       ce->name, 0);\n+\t\t\t\tcontinue;\n \t\t\t}\n \n \t\t\tchanged = match_stat_with_submodule(&revs->diffopt, ce, &st,\n@@ -376,6 +382,14 @@ static void do_oneway_diff(struct unpack_trees_options *o,\n \tstruct rev_info *revs = o->unpack_data;\n \tint match_missing, cached;\n \n+\t/* i-t-a entries do not actually exist in the index */\n+\tif (DIFF_OPT_TST(&revs->diffopt, SHIFT_INTENT_TO_ADD) &&\n+\t    idx && ce_intent_to_add(idx)) {\n+\t\tidx = NULL;\n+\t\tif (!tree)\n+\t\t\treturn;\t/* nothing to diff.. */\n+\t}\n+\n \t/* if the entry is not checked out, don't examine work tree */\n \tcached = o->index_only ||\n \t\t(idx && ((idx->ce_flags & CE_VALID) || ce_skip_worktree(idx)));\ndiff --git a/diff.c b/diff.c\nindex 2485870..e554cad 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -3890,6 +3890,8 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)\n \t\treturn parse_submodule_opt(options, arg);\n \telse if (skip_prefix(arg, \"--ws-error-highlight=\", &arg))\n \t\treturn parse_ws_error_highlight(options, arg);\n+\telse if (!strcmp(arg, \"--shift-ita\"))\n+\t\tDIFF_OPT_SET(options, SHIFT_INTENT_TO_ADD);\n \n \t/* misc options */\n \telse if (!strcmp(arg, \"-z\"))\ndiff --git a/diff.h b/diff.h\nindex 4241aa5..68a4400 100644\n--- a/diff.h\n+++ b/diff.h\n@@ -92,6 +92,7 @@ typedef struct strbuf *(*diff_prefix_fn_t)(struct diff_options *opt, void *data)\n #define DIFF_OPT_FUNCCONTEXT         (1 << 29)\n #define DIFF_OPT_PICKAXE_IGNORE_CASE (1 << 30)\n #define DIFF_OPT_DEFAULT_FOLLOW_RENAMES (1 << 31)\n+#define DIFF_OPT_SHIFT_INTENT_TO_ADD (1ULL << 32)\n \n #define DIFF_OPT_TST(opts, flag)    ((opts)->flags & DIFF_OPT_##flag)\n #define DIFF_OPT_TOUCHED(opts, flag)    ((opts)->touched_flags & DIFF_OPT_##flag)\ndiff --git a/t/t2203-add-intent.sh b/t/t2203-add-intent.sh\nindex d0f36a4..7c90eee 100755\n--- a/t/t2203-add-intent.sh\n+++ b/t/t2203-add-intent.sh\n@@ -5,10 +5,24 @@ test_description='Intent to add'\n . ./test-lib.sh\n \n test_expect_success 'intent to add' '\n+\ttest_commit 1 &&\n+\tgit rm 1.t &&\n+\techo hello >1.t &&\n \techo hello >file &&\n \techo hello >elif &&\n \tgit add -N file &&\n-\tgit add elif\n+\tgit add elif &&\n+\tgit add -N 1.t\n+'\n+\n+test_expect_success 'git status' '\n+\tgit status --porcelain | grep -v actual >actual &&\n+\tcat >expect <<-\\EOF &&\n+\tDA 1.t\n+\tA  elif\n+\t A file\n+\tEOF\n+\ttest_cmp expect actual\n '\n \n test_expect_success 'check result of \"add -N\"' '\n@@ -43,7 +57,9 @@ test_expect_success 'i-t-a entry is simply ignored' '\n \tgit add -N nitfol &&\n \tgit commit -m second &&\n \ttest $(git ls-tree HEAD -- nitfol | wc -l) = 0 &&\n-\ttest $(git diff --name-only HEAD -- nitfol | wc -l) = 1\n+\ttest $(git diff --name-only HEAD -- nitfol | wc -l) = 1 &&\n+\ttest $(git diff --name-only --shift-ita HEAD -- nitfol | wc -l) = 0 &&\n+\ttest $(git diff --name-only --shift-ita -- nitfol | wc -l) = 1\n '\n \n test_expect_success 'can commit with an unrelated i-t-a entry in index' '\ndiff --git a/wt-status.c b/wt-status.c\nindex 717fd48..534d4ad 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -497,6 +497,7 @@ static void wt_status_collect_changes_worktree(struct wt_status *s)\n \tsetup_revisions(0, NULL, &rev, NULL);\n \trev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;\n \tDIFF_OPT_SET(&rev.diffopt, DIRTY_SUBMODULES);\n+\tDIFF_OPT_SET(&rev.diffopt, SHIFT_INTENT_TO_ADD);\n \tif (!s->show_untracked_files)\n \t\tDIFF_OPT_SET(&rev.diffopt, IGNORE_UNTRACKED_IN_SUBMODULES);\n \tif (s->ignore_submodule_arg) {\n@@ -520,6 +521,7 @@ static void wt_status_collect_changes_index(struct wt_status *s)\n \tsetup_revisions(0, NULL, &rev, &opt);\n \n \tDIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);\n+\tDIFF_OPT_SET(&rev.diffopt, SHIFT_INTENT_TO_ADD);\n \tif (s->ignore_submodule_arg) {\n \t\thandle_ignore_submodules_arg(&rev.diffopt, s->ignore_submodule_arg);\n \t} else {\n-- \n2.3.0.rc1.137.g477eb31\n"}]}