From: "Elijah Newren via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: "Jeff King" <peff@peff.net>,
"Jonathan Nieder" <jrnieder@gmail.com>,
"Sergey Organov" <sorganov@gmail.com>,
"Bagas Sanjaya" <bagasdotme@gmail.com>,
"Elijah Newren" <newren@gmail.com>,
"Ævar Arnfjörð Bjarmason" <avarab@gmail.com>,
"Neeraj Singh" <nksingh85@gmail.com>,
"Elijah Newren" <newren@gmail.com>,
"Elijah Newren" <newren@gmail.com>
Subject: [PATCH v2 7/8] diff: add ability to insert additional headers for paths
Date: Sat, 25 Dec 2021 07:59:18 +0000 [thread overview]
Message-ID: <e94706513038adc85e818e8736ad713b2e6b6be4.1640419160.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.1103.v2.git.1640419159.gitgitgadget@gmail.com>
From: Elijah Newren <newren@gmail.com>
When additional headers are provided, we need to
* add diff_filepairs to diff_queued_diff for each paths in the
additional headers map which, unless that path is part of
another diff_filepair already found in diff_queued_diff
* format the headers (colorization, line_prefix for --graph)
* make sure the various codepaths that attempt to return early
if there are "no changes" take into account the headers that
need to be shown.
Signed-off-by: Elijah Newren <newren@gmail.com>
---
diff.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++--
diff.h | 3 +-
log-tree.c | 2 +-
3 files changed, 115 insertions(+), 6 deletions(-)
diff --git a/diff.c b/diff.c
index 861282db1c3..aaa6a19f158 100644
--- a/diff.c
+++ b/diff.c
@@ -27,6 +27,7 @@
#include "help.h"
#include "promisor-remote.h"
#include "dir.h"
+#include "strmap.h"
#ifdef NO_FAST_WORKING_DIRECTORY
#define FAST_WORKING_DIRECTORY 0
@@ -3406,6 +3407,31 @@ struct userdiff_driver *get_textconv(struct repository *r,
return userdiff_get_textconv(r, one->driver);
}
+static struct strbuf *additional_headers(struct diff_options *o,
+ const char *path)
+{
+ if (!o->additional_path_headers)
+ return NULL;
+ return strmap_get(o->additional_path_headers, path);
+}
+
+static void add_formatted_headers(struct strbuf *msg,
+ struct strbuf *more_headers,
+ const char *line_prefix,
+ const char *meta,
+ const char *reset)
+{
+ char *next, *newline;
+
+ for (next = more_headers->buf; *next; next = newline) {
+ newline = strchrnul(next, '\n');
+ strbuf_addf(msg, "%s%s%.*s%s\n", line_prefix, meta,
+ (int)(newline - next), next, reset);
+ if (*newline)
+ newline++;
+ }
+}
+
static void builtin_diff(const char *name_a,
const char *name_b,
struct diff_filespec *one,
@@ -3464,6 +3490,17 @@ static void builtin_diff(const char *name_a,
b_two = quote_two(b_prefix, name_b + (*name_b == '/'));
lbl[0] = DIFF_FILE_VALID(one) ? a_one : "/dev/null";
lbl[1] = DIFF_FILE_VALID(two) ? b_two : "/dev/null";
+ if (!DIFF_FILE_VALID(one) && !DIFF_FILE_VALID(two)) {
+ /*
+ * We should only reach this point for pairs from
+ * create_filepairs_for_header_only_notifications(). For
+ * these, we should avoid the "/dev/null" special casing
+ * above, meaning we avoid showing such pairs as either
+ * "new file" or "deleted file" below.
+ */
+ lbl[0] = a_one;
+ lbl[1] = b_two;
+ }
strbuf_addf(&header, "%s%sdiff --git %s %s%s\n", line_prefix, meta, a_one, b_two, reset);
if (lbl[0][0] == '/') {
/* /dev/null */
@@ -4328,6 +4365,7 @@ static void fill_metainfo(struct strbuf *msg,
const char *set = diff_get_color(use_color, DIFF_METAINFO);
const char *reset = diff_get_color(use_color, DIFF_RESET);
const char *line_prefix = diff_line_prefix(o);
+ struct strbuf *more_headers = NULL;
*must_show_header = 1;
strbuf_init(msg, PATH_MAX * 2 + 300);
@@ -4364,6 +4402,11 @@ static void fill_metainfo(struct strbuf *msg,
default:
*must_show_header = 0;
}
+ if ((more_headers = additional_headers(o, name))) {
+ add_formatted_headers(msg, more_headers,
+ line_prefix, set, reset);
+ *must_show_header = 1;
+ }
if (one && two && !oideq(&one->oid, &two->oid)) {
const unsigned hexsz = the_hash_algo->hexsz;
int abbrev = o->abbrev ? o->abbrev : DEFAULT_ABBREV;
@@ -5852,12 +5895,22 @@ int diff_unmodified_pair(struct diff_filepair *p)
static void diff_flush_patch(struct diff_filepair *p, struct diff_options *o)
{
- if (diff_unmodified_pair(p))
+ /*
+ * Check if we can return early without showing a diff. Note that
+ * diff_filepair only stores {oid, path, mode, is_valid}
+ * information for each path, and thus diff_unmodified_pair() only
+ * considers those bits of info. However, we do not want pairs
+ * created by create_filepairs_for_header_only_notifications() to
+ * be ignored, so return early if both p is unmodified AND
+ * p->one->path is not in additional headers.
+ */
+ if (diff_unmodified_pair(p) && !additional_headers(o, p->one->path))
return;
+ /* Actually, we can also return early to avoid showing tree diffs */
if ((DIFF_FILE_VALID(p->one) && S_ISDIR(p->one->mode)) ||
(DIFF_FILE_VALID(p->two) && S_ISDIR(p->two->mode)))
- return; /* no tree diffs in patch format */
+ return;
run_diff(p, o);
}
@@ -5888,10 +5941,14 @@ static void diff_flush_checkdiff(struct diff_filepair *p,
run_checkdiff(p, o);
}
-int diff_queue_is_empty(void)
+int diff_queue_is_empty(struct diff_options *o)
{
struct diff_queue_struct *q = &diff_queued_diff;
int i;
+
+ if (o->additional_path_headers &&
+ !strmap_empty(o->additional_path_headers))
+ return 0;
for (i = 0; i < q->nr; i++)
if (!diff_unmodified_pair(q->queue[i]))
return 0;
@@ -6325,6 +6382,54 @@ void diff_warn_rename_limit(const char *varname, int needed, int degraded_cc)
warning(_(rename_limit_advice), varname, needed);
}
+static void create_filepairs_for_header_only_notifications(struct diff_options *o)
+{
+ struct strset present;
+ struct diff_queue_struct *q = &diff_queued_diff;
+ struct hashmap_iter iter;
+ struct strmap_entry *e;
+ int i;
+
+ strset_init_with_options(&present, /*pool*/ NULL, /*strdup*/ 0);
+
+ /*
+ * Find out which paths exist in diff_queued_diff, preferring
+ * one->path for any pair that has multiple paths.
+ */
+ for (i = 0; i < q->nr; i++) {
+ struct diff_filepair *p = q->queue[i];
+ char *path = p->one->path ? p->one->path : p->two->path;
+
+ if (strmap_contains(o->additional_path_headers, path))
+ strset_add(&present, path);
+ }
+
+ /*
+ * Loop over paths in additional_path_headers; for each NOT already
+ * in diff_queued_diff, create a synthetic filepair and insert that
+ * into diff_queued_diff.
+ */
+ strmap_for_each_entry(o->additional_path_headers, &iter, e) {
+ if (!strset_contains(&present, e->key)) {
+ struct diff_filespec *one, *two;
+ struct diff_filepair *p;
+
+ one = alloc_filespec(e->key);
+ two = alloc_filespec(e->key);
+ fill_filespec(one, null_oid(), 0, 0);
+ fill_filespec(two, null_oid(), 0, 0);
+ p = diff_queue(q, one, two);
+ p->status = DIFF_STATUS_MODIFIED;
+ }
+ }
+
+ /* Re-sort the filepairs */
+ diffcore_fix_diff_index();
+
+ /* Cleanup */
+ strset_clear(&present);
+}
+
static void diff_flush_patch_all_file_pairs(struct diff_options *o)
{
int i;
@@ -6337,6 +6442,9 @@ static void diff_flush_patch_all_file_pairs(struct diff_options *o)
if (o->color_moved)
o->emitted_symbols = &esm;
+ if (o->additional_path_headers)
+ create_filepairs_for_header_only_notifications(o);
+
for (i = 0; i < q->nr; i++) {
struct diff_filepair *p = q->queue[i];
if (check_pair_status(p))
@@ -6413,7 +6521,7 @@ void diff_flush(struct diff_options *options)
* Order: raw, stat, summary, patch
* or: name/name-status/checkdiff (other bits clear)
*/
- if (!q->nr)
+ if (!q->nr && !options->additional_path_headers)
goto free_queue;
if (output_format & (DIFF_FORMAT_RAW |
diff --git a/diff.h b/diff.h
index 8ba85c5e605..06a0a67afda 100644
--- a/diff.h
+++ b/diff.h
@@ -395,6 +395,7 @@ struct diff_options {
struct repository *repo;
struct option *parseopts;
+ struct strmap *additional_path_headers;
int no_free;
};
@@ -593,7 +594,7 @@ void diffcore_fix_diff_index(void);
" show all files diff when -S is used and hit is found.\n" \
" -a --text treat all files as text.\n"
-int diff_queue_is_empty(void);
+int diff_queue_is_empty(struct diff_options*);
void diff_flush(struct diff_options*);
void diff_free(struct diff_options*);
void diff_warn_rename_limit(const char *varname, int needed, int degraded_cc);
diff --git a/log-tree.c b/log-tree.c
index d4655b63d75..33c28f537a6 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -850,7 +850,7 @@ int log_tree_diff_flush(struct rev_info *opt)
opt->shown_dashes = 0;
diffcore_std(&opt->diffopt);
- if (diff_queue_is_empty()) {
+ if (diff_queue_is_empty(&opt->diffopt)) {
int saved_fmt = opt->diffopt.output_format;
opt->diffopt.output_format = DIFF_FORMAT_NO_OUTPUT;
diff_flush(&opt->diffopt);
--
gitgitgadget
next prev parent reply other threads:[~2021-12-25 7:59 UTC|newest]
Thread overview: 113+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-21 18:05 [PATCH 0/9] Add a new --remerge-diff capability to show & log Elijah Newren via GitGitGadget
2021-12-21 18:05 ` [PATCH 1/9] tmp_objdir: add a helper function for discarding all contained objects Elijah Newren via GitGitGadget
2021-12-21 23:26 ` Junio C Hamano
2021-12-21 23:51 ` Elijah Newren
2021-12-22 6:23 ` Junio C Hamano
2021-12-25 2:29 ` Elijah Newren
2021-12-21 18:05 ` [PATCH 2/9] ll-merge: make callers responsible for showing warnings Elijah Newren via GitGitGadget
2021-12-21 21:19 ` Ævar Arnfjörð Bjarmason
2021-12-21 21:57 ` Elijah Newren
2021-12-21 23:02 ` Ævar Arnfjörð Bjarmason
2021-12-21 23:15 ` Elijah Newren
2021-12-21 23:44 ` Junio C Hamano
2021-12-23 18:26 ` Elijah Newren
2021-12-21 18:05 ` [PATCH 3/9] merge-ort: capture and print ll-merge warnings in our preferred fashion Elijah Newren via GitGitGadget
2021-12-22 0:00 ` Junio C Hamano
2021-12-23 18:36 ` Elijah Newren
2021-12-21 18:05 ` [PATCH 4/9] merge-ort: mark a few more conflict messages as omittable Elijah Newren via GitGitGadget
2021-12-22 0:06 ` Junio C Hamano
2021-12-23 18:38 ` Elijah Newren
2021-12-21 18:05 ` [PATCH 5/9] merge-ort: make path_messages available to external callers Elijah Newren via GitGitGadget
2021-12-21 18:05 ` [PATCH 6/9] diff: add ability to insert additional headers for paths Elijah Newren via GitGitGadget
2021-12-22 0:24 ` Junio C Hamano
2021-12-25 2:35 ` Elijah Newren
2021-12-21 18:05 ` [PATCH 7/9] merge-ort: format messages slightly different for use in headers Elijah Newren via GitGitGadget
2021-12-21 18:05 ` [PATCH 8/9] show, log: provide a --remerge-diff capability Elijah Newren via GitGitGadget
2021-12-21 21:23 ` Ævar Arnfjörð Bjarmason
2021-12-21 22:18 ` Elijah Newren
2021-12-21 18:05 ` [PATCH 9/9] doc/diff-options: explain the new --remerge-diff option Elijah Newren via GitGitGadget
2021-12-21 21:28 ` Ævar Arnfjörð Bjarmason
2021-12-21 22:24 ` Elijah Newren
2021-12-21 23:47 ` Ævar Arnfjörð Bjarmason
2021-12-22 19:05 ` Elijah Newren
2021-12-21 23:20 ` [PATCH 0/9] Add a new --remerge-diff capability to show & log Junio C Hamano
2021-12-21 23:43 ` Elijah Newren
2021-12-22 0:33 ` Junio C Hamano
2021-12-25 7:59 ` [PATCH v2 0/8] " Elijah Newren via GitGitGadget
2021-12-25 7:59 ` [PATCH v2 1/8] show, log: provide a --remerge-diff capability Elijah Newren via GitGitGadget
2021-12-28 10:56 ` Johannes Altmanninger
2021-12-28 22:34 ` Elijah Newren
2021-12-28 23:01 ` brian m. carlson
2021-12-28 23:45 ` Elijah Newren
2021-12-25 7:59 ` [PATCH v2 2/8] log: clean unneeded objects during `log --remerge-diff` Elijah Newren via GitGitGadget
2021-12-25 7:59 ` [PATCH v2 3/8] ll-merge: make callers responsible for showing warnings Elijah Newren via GitGitGadget
2021-12-28 10:56 ` Johannes Altmanninger
2021-12-28 19:37 ` Elijah Newren
2021-12-28 22:05 ` Johannes Altmanninger
2021-12-25 7:59 ` [PATCH v2 4/8] merge-ort: capture and print ll-merge warnings in our preferred fashion Elijah Newren via GitGitGadget
2021-12-25 7:59 ` [PATCH v2 5/8] merge-ort: mark a few more conflict messages as omittable Elijah Newren via GitGitGadget
2021-12-25 7:59 ` [PATCH v2 6/8] merge-ort: format messages slightly different for use in headers Elijah Newren via GitGitGadget
2021-12-26 18:30 ` In-tree strbuf "in-place" search/replace (was: [PATCH v2 6/8] merge-ort: format messages slightly different for use in headers) Ævar Arnfjörð Bjarmason
2021-12-28 10:56 ` [PATCH v2 6/8] merge-ort: format messages slightly different for use in headers Johannes Altmanninger
2021-12-28 21:48 ` Elijah Newren
2021-12-25 7:59 ` Elijah Newren via GitGitGadget [this message]
2021-12-28 10:57 ` [PATCH v2 7/8] diff: add ability to insert additional headers for paths Johannes Altmanninger
2021-12-28 21:09 ` Elijah Newren
2021-12-29 0:16 ` Johannes Altmanninger
2021-12-30 22:04 ` Elijah Newren
2021-12-31 3:07 ` Johannes Altmanninger
2021-12-25 7:59 ` [PATCH v2 8/8] show, log: include conflict/warning messages in --remerge-diff headers Elijah Newren via GitGitGadget
2021-12-28 10:57 ` Johannes Altmanninger
2021-12-28 23:42 ` Elijah Newren
2021-12-26 21:52 ` [PATCH v2 0/8] Add a new --remerge-diff capability to show & log Ævar Arnfjörð Bjarmason
2021-12-27 21:11 ` Elijah Newren
2022-01-10 15:48 ` Ævar Arnfjörð Bjarmason
2021-12-28 10:55 ` Johannes Altmanninger
2021-12-30 23:36 ` [PATCH v3 0/9] " Elijah Newren via GitGitGadget
2021-12-30 23:36 ` [PATCH v3 1/9] show, log: provide a --remerge-diff capability Elijah Newren via GitGitGadget
2022-01-19 15:49 ` Ævar Arnfjörð Bjarmason
2022-01-20 2:31 ` Elijah Newren
2022-01-20 7:53 ` Elijah Newren
2022-01-19 16:01 ` Ævar Arnfjörð Bjarmason
2022-01-20 2:33 ` Elijah Newren
2021-12-30 23:36 ` [PATCH v3 2/9] log: clean unneeded objects during `log --remerge-diff` Elijah Newren via GitGitGadget
2021-12-30 23:36 ` [PATCH v3 3/9] ll-merge: make callers responsible for showing warnings Elijah Newren via GitGitGadget
2022-01-19 16:41 ` Ævar Arnfjörð Bjarmason
2022-01-20 3:29 ` Elijah Newren
2021-12-30 23:36 ` [PATCH v3 4/9] merge-ort: capture and print ll-merge warnings in our preferred fashion Elijah Newren via GitGitGadget
2021-12-30 23:36 ` [PATCH v3 5/9] merge-ort: mark a few more conflict messages as omittable Elijah Newren via GitGitGadget
2021-12-30 23:36 ` [PATCH v3 6/9] merge-ort: format messages slightly different for use in headers Elijah Newren via GitGitGadget
2021-12-30 23:36 ` [PATCH v3 7/9] diff: add ability to insert additional headers for paths Elijah Newren via GitGitGadget
2021-12-30 23:36 ` [PATCH v3 8/9] show, log: include conflict/warning messages in --remerge-diff headers Elijah Newren via GitGitGadget
2022-01-19 16:19 ` Ævar Arnfjörð Bjarmason
2022-01-21 2:16 ` Elijah Newren
2022-01-21 16:55 ` Elijah Newren
2021-12-30 23:36 ` [PATCH v3 9/9] merge-ort: mark conflict/warning messages from inner merges as omittable Elijah Newren via GitGitGadget
2021-12-31 8:46 ` [PATCH v3 0/9] Add a new --remerge-diff capability to show & log Junio C Hamano
2022-01-21 19:12 ` [PATCH v4 00/10] " Elijah Newren via GitGitGadget
2022-01-21 19:12 ` [PATCH v4 01/10] show, log: provide a --remerge-diff capability Elijah Newren via GitGitGadget
2022-02-01 9:09 ` Ævar Arnfjörð Bjarmason
2022-02-01 16:40 ` Elijah Newren
2022-01-21 19:12 ` [PATCH v4 02/10] log: clean unneeded objects during `log --remerge-diff` Elijah Newren via GitGitGadget
2022-02-01 9:35 ` Ævar Arnfjörð Bjarmason
2022-02-01 16:54 ` Elijah Newren
2022-02-02 11:17 ` Ævar Arnfjörð Bjarmason
2022-01-21 19:12 ` [PATCH v4 03/10] ll-merge: make callers responsible for showing warnings Elijah Newren via GitGitGadget
2022-01-21 19:12 ` [PATCH v4 04/10] merge-ort: capture and print ll-merge warnings in our preferred fashion Elijah Newren via GitGitGadget
2022-01-21 19:12 ` [PATCH v4 05/10] merge-ort: mark a few more conflict messages as omittable Elijah Newren via GitGitGadget
2022-01-21 19:12 ` [PATCH v4 06/10] merge-ort: format messages slightly different for use in headers Elijah Newren via GitGitGadget
2022-01-21 19:12 ` [PATCH v4 07/10] diff: add ability to insert additional headers for paths Elijah Newren via GitGitGadget
2022-01-21 19:12 ` [PATCH v4 08/10] show, log: include conflict/warning messages in --remerge-diff headers Elijah Newren via GitGitGadget
2022-01-21 19:12 ` [PATCH v4 09/10] merge-ort: mark conflict/warning messages from inner merges as omittable Elijah Newren via GitGitGadget
2022-01-21 19:12 ` [PATCH v4 10/10] diff-merges: avoid history simplifications when diffing merges Elijah Newren via GitGitGadget
2022-02-02 2:37 ` [PATCH v5 00/10] Add a new --remerge-diff capability to show & log Elijah Newren via GitGitGadget
2022-02-02 2:37 ` [PATCH v5 01/10] show, log: provide a --remerge-diff capability Elijah Newren via GitGitGadget
2022-02-02 2:37 ` [PATCH v5 02/10] log: clean unneeded objects during `log --remerge-diff` Elijah Newren via GitGitGadget
2022-02-02 2:37 ` [PATCH v5 03/10] ll-merge: make callers responsible for showing warnings Elijah Newren via GitGitGadget
2022-02-02 2:37 ` [PATCH v5 04/10] merge-ort: capture and print ll-merge warnings in our preferred fashion Elijah Newren via GitGitGadget
2022-02-02 2:37 ` [PATCH v5 05/10] merge-ort: mark a few more conflict messages as omittable Elijah Newren via GitGitGadget
2022-02-02 2:37 ` [PATCH v5 06/10] merge-ort: format messages slightly different for use in headers Elijah Newren via GitGitGadget
2022-02-02 2:37 ` [PATCH v5 07/10] diff: add ability to insert additional headers for paths Elijah Newren via GitGitGadget
2022-02-02 2:37 ` [PATCH v5 08/10] show, log: include conflict/warning messages in --remerge-diff headers Elijah Newren via GitGitGadget
2022-02-02 2:37 ` [PATCH v5 09/10] merge-ort: mark conflict/warning messages from inner merges as omittable Elijah Newren via GitGitGadget
2022-02-02 2:37 ` [PATCH v5 10/10] diff-merges: avoid history simplifications when diffing merges Elijah Newren via GitGitGadget
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
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=e94706513038adc85e818e8736ad713b2e6b6be4.1640419160.git.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=avarab@gmail.com \
--cc=bagasdotme@gmail.com \
--cc=git@vger.kernel.org \
--cc=jrnieder@gmail.com \
--cc=newren@gmail.com \
--cc=nksingh85@gmail.com \
--cc=peff@peff.net \
--cc=sorganov@gmail.com \
/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.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
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 read-only IMAP folder(s) and NNTP newsgroup(s).