git/diff.h

/*
 * Copyright (C) 2005 Junio C Hamano
 */
#ifndef DIFF_H
#define DIFF_H

#include "hash.h"
#include "pathspec.h"
#include "strbuf.h"

struct oidset;

/**
 * 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, it will call
 *   `diff_free()` to free any resources, e.g. those allocated in
 *   `diff_opt_parse()`.
 *
 * - Set `.no_free = 1` before calling `diff_flush()` to defer the
 *   freeing of allocated memory in diff_options. This is useful when
 *   `diff_flush()` is being called in a loop, rather than as a
 *   one-off. When setting `.no_free = 1` you must ensure that
 *   `diff_free()` is called at the end, either by flipping the flag
 *   before the last `diff_flush()` call, or by flipping it before
 *   calling `diff_free()` yourself.
 */

struct combine_diff_path;
struct commit;
struct diff_filespec;
struct diff_options;
struct diff_queue_struct;
struct oid_array;
struct option;
struct repository;
struct rev_info;
struct userdiff_driver;

pathchange_fn_t;

change_fn_t;

add_remove_fn_t;

diff_format_fn_t;

diff_prefix_fn_t;

#define DIFF_FORMAT_RAW
#define DIFF_FORMAT_DIFFSTAT
#define DIFF_FORMAT_NUMSTAT
#define DIFF_FORMAT_SUMMARY
#define DIFF_FORMAT_PATCH
#define DIFF_FORMAT_SHORTSTAT
#define DIFF_FORMAT_DIRSTAT

/* These override all above */
#define DIFF_FORMAT_NAME
#define DIFF_FORMAT_NAME_STATUS
#define DIFF_FORMAT_CHECKDIFF

/* Same as output_format = 0 but we know that -s flag was given
 * and we should not give default value to output_format.
 */
#define DIFF_FORMAT_NO_OUTPUT

#define DIFF_FORMAT_CALLBACK

#define DIFF_FLAGS_INIT
struct diff_flags {};

static inline void diff_flags_or(struct diff_flags *a,
				 const struct diff_flags *b)
{}

#define DIFF_XDL_TST(opts, flag)
#define DIFF_XDL_SET(opts, flag)
#define DIFF_XDL_CLR(opts, flag)

#define DIFF_WITH_ALG(opts, flag)

enum diff_words_type {};

enum diff_submodule_format {};

/**
 * the set of options the calling program wants to affect the operation of
 * diffcore library with.
 */
struct diff_options {};

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);
void diff_emit_submodule_modified(struct diff_options *o, const char *path);
void diff_emit_submodule_header(struct diff_options *o, const char *header);
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 {};

enum color_diff {};

const char *diff_get_color(int diff_use_color, enum color_diff ix);
#define diff_get_color_opt(o, ix)


const char *diff_line_prefix(struct diff_options *);


extern const char mime_boundary_leader[];

struct combine_diff_path *diff_tree_paths(
	struct combine_diff_path *p, const struct object_id *oid,
	const struct object_id **parents_oid, int nparent,
	struct strbuf *base, struct diff_options *opt);
void diff_tree_oid(const struct object_id *old_oid,
		   const struct object_id *new_oid,
		   const char *base, struct diff_options *opt);
void diff_root_tree_oid(const struct object_id *new_oid, const char *base,
			struct diff_options *opt);

struct combine_diff_path {};
#define combine_diff_path_size(n, l)

void show_combined_diff(struct combine_diff_path *elem, int num_parent,
			struct rev_info *);

void diff_tree_combined(const struct object_id *oid, const struct oid_array *parents, struct rev_info *rev);

void diff_tree_combined_merge(const struct commit *commit, struct rev_info *rev);

void diff_set_mnemonic_prefix(struct diff_options *options, const char *a, const char *b);
void diff_set_noprefix(struct diff_options *options);
void diff_set_default_prefix(struct diff_options *options);

int diff_can_quit_early(struct diff_options *);

void diff_addremove(struct diff_options *,
		    int addremove,
		    unsigned mode,
		    const struct object_id *oid,
		    int oid_valid,
		    const char *fullpath, unsigned dirty_submodule);

void diff_change(struct diff_options *,
		 unsigned mode1, unsigned mode2,
		 const struct object_id *old_oid,
		 const struct object_id *new_oid,
		 int old_oid_valid, int new_oid_valid,
		 const char *fullpath,
		 unsigned dirty_submodule1, unsigned dirty_submodule2);

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
#define DIFF_SETUP_USE_SIZE_CACHE

/*
 * Poor man's alternative to parse-option, to allow both stuck form
 * (--option=value) and separate form (--option value).
 */
int parse_long_opt(const char *opt, const char **argv,
		   const char **optarg);

struct config_context;
int git_diff_basic_config(const char *var, const char *value,
			  const struct config_context *ctx, void *cb);
int git_diff_heuristic_config(const char *var, const char *value, void *cb);
void init_diff_ui_defaults(void);
int git_diff_ui_config(const char *var, const char *value,
		       const struct config_context *ctx, void *cb);
void repo_diff_setup(struct repository *, struct diff_options *);
struct option *add_diff_options(const struct option *, struct diff_options *);
int diff_opt_parse(struct diff_options *, const char **, int, const char *);
void diff_setup_done(struct diff_options *);

/*
 * Returns true if the pathspec can work with --follow mode. If die_on_error is
 * set, die() with a specific error message rather than returning false.
 */
int diff_check_follow_pathspec(struct pathspec *ps, int die_on_error);

int git_config_rename(const char *var, const char *value);

#define DIFF_DETECT_RENAME
#define DIFF_DETECT_COPY

#define DIFF_PICKAXE_ALL
#define DIFF_PICKAXE_REGEX

#define DIFF_PICKAXE_KIND_S
#define DIFF_PICKAXE_KIND_G
#define DIFF_PICKAXE_KIND_OBJFIND

#define DIFF_PICKAXE_KINDS_MASK
#define DIFF_PICKAXE_KINDS_G_REGEX_MASK
#define DIFF_PICKAXE_KINDS_ALL_OBJFIND_MASK

#define DIFF_PICKAXE_IGNORE_CASE

void init_diffstat_widths(struct diff_options *);
void diffcore_std(struct diff_options *);
void diffcore_fix_diff_index(void);

#define COMMON_DIFF_OPTIONS_HELP

int diff_queue_is_empty(struct diff_options *o);
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-raw status letters */
#define DIFF_STATUS_ADDED
#define DIFF_STATUS_COPIED
#define DIFF_STATUS_DELETED
#define DIFF_STATUS_MODIFIED
#define DIFF_STATUS_RENAMED
#define DIFF_STATUS_TYPE_CHANGED
#define DIFF_STATUS_UNKNOWN
#define DIFF_STATUS_UNMERGED

/* these are not diff-raw status letters proper, but used by
 * diffcore-filter insn to specify additional restrictions.
 */
#define DIFF_STATUS_FILTER_AON
#define DIFF_STATUS_FILTER_BROKEN

/*
 * This is different from repo_find_unique_abbrev() in that
 * it stuffs the result with dots for alignment.
 */
const char *diff_aligned_abbrev(const struct object_id *sha1, int);

void diff_get_merge_base(const struct rev_info *revs, struct object_id *mb);

/* do not report anything on removed paths */
#define DIFF_SILENT_ON_REMOVED
/* report racily-clean paths as modified */
#define DIFF_RACY_IS_MODIFIED
void run_diff_files(struct rev_info *revs, unsigned int option);

#define DIFF_INDEX_CACHED
#define DIFF_INDEX_MERGE_BASE
void run_diff_index(struct rev_info *revs, unsigned int option);

int do_diff_cache(const struct object_id *, struct diff_options *);
int diff_flush_patch_id(struct diff_options *, struct object_id *, int);
void flush_one_hunk(struct object_id *result, git_hash_ctx *ctx);

int diff_result_code(struct rev_info *);

int diff_no_index(struct rev_info *,
		  int implicit_no_index, int, const char **);

int index_differs_from(struct repository *r, const char *def,
		       const struct diff_flags *flags,
		       int ita_invisible_in_index);

/*
 * Emit an interdiff of two object ID's to 'diff_options.file' optionally
 * indented by 'indent' spaces.
 */
void show_interdiff(const struct object_id *, const struct object_id *,
		    int indent, struct diff_options *);

/*
 * Fill the contents of the filespec "df", respecting any textconv defined by
 * its userdiff driver.  The "driver" parameter must come from a
 * previous call to get_textconv(), and therefore should either be NULL or have
 * textconv enabled.
 *
 * Note that the memory ownership of the resulting buffer depends on whether
 * the driver field is NULL. If it is, then the memory belongs to the filespec
 * struct. If it is non-NULL, then "outbuf" points to a newly allocated buffer
 * that should be freed by the caller.
 */
size_t fill_textconv(struct repository *r,
		     struct userdiff_driver *driver,
		     struct diff_filespec *df,
		     char **outbuf);

/*
 * Look up the userdiff driver for the given filespec, and return it if
 * and only if it has textconv enabled (otherwise return NULL). The result
 * can be passed to fill_textconv().
 */
struct userdiff_driver *get_textconv(struct repository *r,
				     struct diff_filespec *one);

/*
 * Prepare diff_filespec and convert it using diff textconv API
 * if the textconv driver exists.
 * Return 1 if the conversion succeeds, 0 otherwise.
 */
int textconv_object(struct repository *repo,
		    const char *path,
		    unsigned mode,
		    const struct object_id *oid, int oid_valid,
		    char **buf, unsigned long *buf_size);

int parse_rename_score(const char **cp_p);

long parse_algorithm_value(const char *value);

void print_stat_summary(FILE *fp, int files,
			int insertions, int deletions);
void setup_diff_pager(struct diff_options *);

extern int diff_auto_refresh_index;

#endif /* DIFF_H */