]> git.ipfire.org Git - thirdparty/git.git/blobdiff - diff.h
Merge branch 'jt/t5500-unflake'
[thirdparty/git.git] / diff.h
diff --git a/diff.h b/diff.h
index ce5e8a8183e848b2e36d50bea271f687a450e3af..9443dc1b0039026ba6c32efd3e445fa61a0860f5 100644 (file)
--- a/diff.h
+++ b/diff.h
@@ -9,16 +9,60 @@
 #include "object.h"
 #include "oidset.h"
 
-struct rev_info;
+/**
+ * The diff API is for programs that compare two sets of files (e.g. two trees,
+ * one tree and the index) and present the found difference in various ways.
+ * The calling program is responsible for feeding the API pairs of files, one
+ * from the "old" set and the corresponding one from "new" set, that are
+ * different.
+ * The library called through this API is called diffcore, and is responsible
+ * for two things.
+ *
+ * - finding total rewrites (`-B`), renames (`-M`) and copies (`-C`), and
+ * changes that touch a string (`-S`), as specified by the caller.
+ *
+ * - outputting the differences in various formats, as specified by the caller.
+ *
+ * Calling sequence
+ * ----------------
+ *
+ * - Prepare `struct diff_options` to record the set of diff options, and then
+ * call `repo_diff_setup()` to initialize this structure.  This sets up the
+ * vanilla default.
+ *
+ * - Fill in the options structure to specify desired output format, rename
+ * detection, etc.  `diff_opt_parse()` can be used to parse options given
+ * from the command line in a way consistent with existing git-diff family
+ * of programs.
+ *
+ * - Call `diff_setup_done()`; this inspects the options set up so far for
+ * internal consistency and make necessary tweaking to it (e.g. if textual
+ * patch output was asked, recursive behaviour is turned on); the callback
+ * set_default in diff_options can be used to tweak this more.
+ *
+ * - As you find different pairs of files, call `diff_change()` to feed
+ * modified files, `diff_addremove()` to feed created or deleted files, or
+ * `diff_unmerge()` to feed a file whose state is 'unmerged' to the API.
+ * These are thin wrappers to a lower-level `diff_queue()` function that is
+ * flexible enough to record any of these kinds of changes.
+ *
+ * - Once you finish feeding the pairs of files, call `diffcore_std()`.
+ * This will tell the diffcore library to go ahead and do its work.
+ *
+ * - Calling `diff_flush()` will produce the output.
+ */
+
+struct combine_diff_path;
+struct commit;
+struct diff_filespec;
 struct diff_options;
 struct diff_queue_struct;
-struct strbuf;
-struct diff_filespec;
-struct userdiff_driver;
 struct oid_array;
-struct commit;
-struct combine_diff_path;
+struct option;
 struct repository;
+struct rev_info;
+struct strbuf;
+struct userdiff_driver;
 
 typedef int (*pathchange_fn_t)(struct diff_options *options,
                 struct combine_diff_path *path);
@@ -64,39 +108,85 @@ typedef struct strbuf *(*diff_prefix_fn_t)(struct diff_options *opt, void *data)
 
 #define DIFF_FLAGS_INIT { 0 }
 struct diff_flags {
-       unsigned recursive:1;
-       unsigned tree_in_recursive:1;
-       unsigned binary:1;
-       unsigned text:1;
-       unsigned full_index:1;
-       unsigned silent_on_remove:1;
-       unsigned find_copies_harder:1;
-       unsigned follow_renames:1;
-       unsigned rename_empty:1;
-       unsigned has_changes:1;
-       unsigned quick:1;
-       unsigned no_index:1;
-       unsigned allow_external:1;
-       unsigned exit_with_status:1;
-       unsigned reverse_diff:1;
-       unsigned check_failed:1;
-       unsigned relative_name:1;
-       unsigned ignore_submodules:1;
-       unsigned dirstat_cumulative:1;
-       unsigned dirstat_by_file:1;
-       unsigned allow_textconv:1;
-       unsigned textconv_set_via_cmdline:1;
-       unsigned diff_from_contents:1;
-       unsigned dirty_submodules:1;
-       unsigned ignore_untracked_in_submodules:1;
-       unsigned ignore_dirty_submodules:1;
-       unsigned override_submodule_config:1;
-       unsigned dirstat_by_line:1;
-       unsigned funccontext:1;
-       unsigned default_follow_renames:1;
-       unsigned stat_with_summary:1;
-       unsigned suppress_diff_headers:1;
-       unsigned dual_color_diffed_diffs:1;
+
+       /**
+        * Tells if tree traversal done by tree-diff should recursively descend
+        * into a tree object pair that are different in preimage and postimage set.
+        */
+       unsigned recursive;
+       unsigned tree_in_recursive;
+
+       /* Affects the way how a file that is seemingly binary is treated. */
+       unsigned binary;
+       unsigned text;
+
+       /**
+        * Tells the patch output format not to use abbreviated object names on the
+        * "index" lines.
+        */
+       unsigned full_index;
+
+       /* Affects if diff-files shows removed files. */
+       unsigned silent_on_remove;
+
+       /**
+        * Tells the diffcore library that the caller is feeding unchanged
+        * filepairs to allow copies from unmodified files be detected.
+        */
+       unsigned find_copies_harder;
+
+       unsigned follow_renames;
+       unsigned rename_empty;
+
+       /* Internal; used for optimization to see if there is any change. */
+       unsigned has_changes;
+
+       unsigned quick;
+
+       /**
+        * Tells diff-files that the input is not tracked files but files in random
+        * locations on the filesystem.
+        */
+       unsigned no_index;
+
+       /**
+        * Tells output routine that it is Ok to call user specified patch output
+        * routine.  Plumbing disables this to ensure stable output.
+        */
+       unsigned allow_external;
+
+       /**
+        * For communication between the calling program and the options parser;
+        * tell the calling program to signal the presence of difference using
+        * program exit code.
+        */
+       unsigned exit_with_status;
+
+       /**
+        * Tells the library that the calling program is feeding the filepairs
+        * reversed; `one` is two, and `two` is one.
+        */
+       unsigned reverse_diff;
+
+       unsigned check_failed;
+       unsigned relative_name;
+       unsigned ignore_submodules;
+       unsigned dirstat_cumulative;
+       unsigned dirstat_by_file;
+       unsigned allow_textconv;
+       unsigned textconv_set_via_cmdline;
+       unsigned diff_from_contents;
+       unsigned dirty_submodules;
+       unsigned ignore_untracked_in_submodules;
+       unsigned ignore_dirty_submodules;
+       unsigned override_submodule_config;
+       unsigned dirstat_by_line;
+       unsigned funccontext;
+       unsigned default_follow_renames;
+       unsigned stat_with_summary;
+       unsigned suppress_diff_headers;
+       unsigned dual_color_diffed_diffs;
+       unsigned suppress_hunk_header_line_count;
 };
 
 static inline void diff_flags_or(struct diff_flags *a,
@@ -129,36 +219,77 @@ enum diff_submodule_format {
        DIFF_SUBMODULE_INLINE_DIFF
 };
 
+/**
+ * the set of options the calling program wants to affect the operation of
+ * diffcore library with.
+ */
 struct diff_options {
        const char *orderfile;
+
+       /**
+        * A constant string (can and typically does contain newlines to look for
+        * a block of text, not just a single line) to filter out the filepairs
+        * that do not change the number of strings contained in its preimage and
+        * postimage of the diff_queue.
+        */
        const char *pickaxe;
+
        const char *single_follow;
        const char *a_prefix, *b_prefix;
        const char *line_prefix;
        size_t line_prefix_length;
+
+       /**
+        * collection of boolean options that affects the operation, but some do
+        * not have anything to do with the diffcore library.
+        */
        struct diff_flags flags;
 
        /* diff-filter bits */
        unsigned int filter;
 
        int use_color;
+
+       /* Number of context lines to generate in patch output. */
        int context;
+
        int interhunkcontext;
+
+       /* Affects the way detection logic for complete rewrites, renames and
+        * copies.
+        */
        int break_opt;
        int detect_rename;
+
        int irreversible_delete;
        int skip_stat_unmatch;
        int line_termination;
+
+       /* The output format used when `diff_flush()` is run. */
        int output_format;
+
        unsigned pickaxe_opts;
+
+       /* Affects the way detection logic for complete rewrites, renames and
+        * copies.
+        */
        int rename_score;
        int rename_limit;
+
        int needed_rename_limit;
        int degraded_cc_to_c;
        int show_rename_progress;
        int dirstat_permille;
        int setup;
+
+       /* Number of hexdigits to abbreviate raw format output to. */
        int abbrev;
+
+       /* If non-zero, then stop computing after this many changes. */
+       int max_changes;
+       /* For internal use only. */
+       int num_changes;
+
        int ita_invisible_in_index;
 /* white-space error highlighting */
 #define WSEH_NEW (1<<12)
@@ -168,7 +299,7 @@ struct diff_options {
        const char *prefix;
        int prefix_length;
        const char *stat_sep;
-       long xdl_opts;
+       int xdl_opts;
 
        /* see Documentation/diff-options.txt */
        char **anchors;
@@ -190,6 +321,7 @@ struct diff_options {
        /* to support internal diff recursion by --follow hack*/
        int found_follow;
 
+       /* Callback which allows tweaking the options in diff_setup_done(). */
        void (*set_default)(struct diff_options *);
 
        FILE *file;
@@ -225,11 +357,15 @@ struct diff_options {
 
        /* XDF_WHITESPACE_FLAGS regarding block detection are set at 2, 3, 4 */
        #define COLOR_MOVED_WS_ALLOW_INDENTATION_CHANGE (1<<5)
-       int color_moved_ws_handling;
+       #define COLOR_MOVED_WS_ERROR (1<<0)
+       unsigned color_moved_ws_handling;
 
        struct repository *repo;
+       struct option *parseopts;
 };
 
+unsigned diff_filter_bit(char status);
+
 void diff_emit_submodule_del(struct diff_options *o, const char *line);
 void diff_emit_submodule_add(struct diff_options *o, const char *line);
 void diff_emit_submodule_untracked(struct diff_options *o, const char *path);
@@ -239,6 +375,22 @@ void diff_emit_submodule_error(struct diff_options *o, const char *err);
 void diff_emit_submodule_pipethrough(struct diff_options *o,
                                     const char *line, int len);
 
+struct diffstat_t {
+       int nr;
+       int alloc;
+       struct diffstat_file {
+               char *from_name;
+               char *name;
+               char *print_name;
+               const char *comments;
+               unsigned is_unmerged:1;
+               unsigned is_binary:1;
+               unsigned is_renamed:1;
+               unsigned is_interesting:1;
+               uintmax_t added, deleted;
+       } **files;
+};
+
 enum color_diff {
        DIFF_RESET = 0,
        DIFF_CONTEXT = 1,
@@ -264,6 +416,7 @@ enum color_diff {
        DIFF_FILE_OLD_BOLD = 21,
        DIFF_FILE_NEW_BOLD = 22,
 };
+
 const char *diff_get_color(int diff_use_color, enum color_diff ix);
 #define diff_get_color_opt(o, ix) \
        diff_get_color((o)->use_color, ix)
@@ -293,6 +446,7 @@ struct combine_diff_path {
                char status;
                unsigned int mode;
                struct object_id oid;
+               struct strbuf path;
        } parent[FLEX_ARRAY];
 };
 #define combine_diff_path_size(n, l) \
@@ -327,6 +481,10 @@ void diff_change(struct diff_options *,
 
 struct diff_filepair *diff_unmerge(struct diff_options *, const char *path);
 
+void compute_diffstat(struct diff_options *options, struct diffstat_t *diffstat,
+                     struct diff_queue_struct *q);
+void free_diffstat_info(struct diffstat_t *diffstat);
+
 #define DIFF_SETUP_REVERSE             1
 #define DIFF_SETUP_USE_SIZE_CACHE      4
 
@@ -366,7 +524,7 @@ int git_config_rename(const char *var, const char *value);
 #define DIFF_PICKAXE_IGNORE_CASE       32
 
 void diffcore_std(struct diff_options *);
-void diffcore_fix_diff_index(struct diff_options *);
+void diffcore_fix_diff_index(void);
 
 #define COMMON_DIFF_OPTIONS_HELP \
 "\ncommon diff options:\n" \
@@ -430,13 +588,16 @@ int run_diff_files(struct rev_info *revs, unsigned int option);
 int run_diff_index(struct rev_info *revs, int cached);
 
 int do_diff_cache(const struct object_id *, struct diff_options *);
-int diff_flush_patch_id(struct diff_options *, struct object_id *, int);
+int diff_flush_patch_id(struct diff_options *, struct object_id *, int, int);
+void flush_one_hunk(struct object_id *result, git_hash_ctx *ctx);
 
 int diff_result_code(struct diff_options *, int);
 
-void diff_no_index(struct repository *, struct rev_info *, int, const char **);
+int diff_no_index(struct rev_info *,
+                 int implicit_no_index, int, const char **);
 
-int index_differs_from(const char *def, const struct diff_flags *flags,
+int index_differs_from(struct repository *r, const char *def,
+                      const struct diff_flags *flags,
                       int ita_invisible_in_index);
 
 /*
@@ -460,7 +621,7 @@ size_t fill_textconv(struct repository *r,
  * and only if it has textconv enabled (otherwise return NULL). The result
  * can be passed to fill_textconv().
  */
-struct userdiff_driver *get_textconv(struct index_state *istate,
+struct userdiff_driver *get_textconv(struct repository *r,
                                     struct diff_filespec *one);
 
 /*