exit(1);
}
-enum {
- FORMAT_PATCH = 0,
- FORMAT_COMPACT = 1,
- FORMAT_RAW = 2
-};
-
int main(int argc, char *argv[])
{
git_repository *repo = NULL;
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff_find_options findopts = GIT_DIFF_FIND_OPTIONS_INIT;
git_diff *diff;
- int i, color = -1, format = FORMAT_PATCH, cached = 0;
+ int i, color = -1, cached = 0;
+ git_diff_format_t format = GIT_DIFF_FORMAT_PATCH;
char *a, *treeish1 = NULL, *treeish2 = NULL;
const char *dir = ".";
}
else if (!strcmp(a, "-p") || !strcmp(a, "-u") ||
!strcmp(a, "--patch"))
- format = FORMAT_PATCH;
+ format = GIT_DIFF_FORMAT_PATCH;
else if (!strcmp(a, "--cached"))
cached = 1;
+ else if (!strcmp(a, "--name-only"))
+ format = GIT_DIFF_FORMAT_NAME_ONLY;
else if (!strcmp(a, "--name-status"))
- format = FORMAT_COMPACT;
+ format = GIT_DIFF_FORMAT_NAME_STATUS;
else if (!strcmp(a, "--raw"))
- format = FORMAT_RAW;
+ format = GIT_DIFF_FORMAT_RAW;
else if (!strcmp(a, "--color"))
color = 0;
else if (!strcmp(a, "--no-color"))
if (color >= 0)
fputs(colors[0], stdout);
- switch (format) {
- case FORMAT_PATCH:
- check(git_diff_print_patch(diff, printer, &color), "Displaying diff");
- break;
- case FORMAT_COMPACT:
- check(git_diff_print_compact(diff, printer, &color), "Displaying diff");
- break;
- case FORMAT_RAW:
- check(git_diff_print_raw(diff, printer, &color), "Displaying diff");
- break;
- }
+ check(git_diff_print(diff, format, printer, &color), "Displaying diff");
if (color >= 0)
fputs(colors[0], stdout);
check(git_diff_tree_to_tree(
&diff, git_commit_owner(commit), a, b, &diffopts),
"Diff commit with parent", NULL);
- check(git_diff_print_patch(diff, print_diff, NULL),
+ check(git_diff_print(diff, GIT_DIFF_FORMAT_PATCH, print_diff, NULL),
"Displaying diff", NULL);
git_diff_free(diff);
* Calculating diffs is generally done in two phases: building a list of
* diffs then traversing it. This makes is easier to share logic across
* the various types of diffs (tree vs tree, workdir vs index, etc.), and
- * also allows you to insert optional diff list post-processing phases,
+ * also allows you to insert optional diff post-processing phases,
* such as rename detection, in between the steps. When you are done with
* a diff object, it must be freed.
*
typedef enum {
/** Normal diff, the default */
GIT_DIFF_NORMAL = 0,
- /** Reverse the sides of the diff */
- GIT_DIFF_REVERSE = (1 << 0),
- /** Treat all files as text, disabling binary attributes & detection */
- GIT_DIFF_FORCE_TEXT = (1 << 1),
- /** Ignore all whitespace */
- GIT_DIFF_IGNORE_WHITESPACE = (1 << 2),
- /** Ignore changes in amount of whitespace */
- GIT_DIFF_IGNORE_WHITESPACE_CHANGE = (1 << 3),
- /** Ignore whitespace at end of line */
- GIT_DIFF_IGNORE_WHITESPACE_EOL = (1 << 4),
- /** Treat all submodules as unmodified */
- GIT_DIFF_IGNORE_SUBMODULES = (1 << 5),
- /** Use the "patience diff" algorithm (currently unimplemented) */
- GIT_DIFF_PATIENCE = (1 << 6),
- /** Include ignored files in the diff list */
- GIT_DIFF_INCLUDE_IGNORED = (1 << 7),
- /** Include untracked files in the diff list */
- GIT_DIFF_INCLUDE_UNTRACKED = (1 << 8),
- /** Include unmodified files in the diff list */
- GIT_DIFF_INCLUDE_UNMODIFIED = (1 << 9),
- /** Even with GIT_DIFF_INCLUDE_UNTRACKED, an entire untracked
- * directory will be marked with only a single entry in the diff list
- * (a la what core Git does in `git status`); this flag adds *all*
- * files under untracked directories as UNTRACKED entries, too.
+ /*
+ * Options controlling which files will be in the diff
*/
- GIT_DIFF_RECURSE_UNTRACKED_DIRS = (1 << 10),
- /** If the pathspec is set in the diff options, this flags means to
- * apply it as an exact match instead of as an fnmatch pattern.
- */
- GIT_DIFF_DISABLE_PATHSPEC_MATCH = (1 << 11),
+ /** Reverse the sides of the diff */
+ GIT_DIFF_REVERSE = (1u << 0),
- /** Use case insensitive filename comparisons */
- GIT_DIFF_DELTAS_ARE_ICASE = (1 << 12),
+ /** Include ignored files in the diff */
+ GIT_DIFF_INCLUDE_IGNORED = (1u << 1),
- /** When generating patch text, include the content of untracked
- * files. This automatically turns on GIT_DIFF_INCLUDE_UNTRACKED but
- * it does not turn on GIT_DIFF_RECURSE_UNTRACKED_DIRS. Add that
- * flag if you want the content of every single UNTRACKED file.
+ /** Even with GIT_DIFF_INCLUDE_IGNORED, an entire ignored directory
+ * will be marked with only a single entry in the diff; this flag
+ * adds all files under the directory as IGNORED entries, too.
*/
- GIT_DIFF_INCLUDE_UNTRACKED_CONTENT = (1 << 13),
+ GIT_DIFF_RECURSE_IGNORED_DIRS = (1u << 2),
- /** Disable updating of the `binary` flag in delta records. This is
- * useful when iterating over a diff if you don't need hunk and data
- * callbacks and want to avoid having to load file completely.
+ /** Include untracked files in the diff */
+ GIT_DIFF_INCLUDE_UNTRACKED = (1u << 3),
+
+ /** Even with GIT_DIFF_INCLUDE_UNTRACKED, an entire untracked
+ * directory will be marked with only a single entry in the diff
+ * (a la what core Git does in `git status`); this flag adds *all*
+ * files under untracked directories as UNTRACKED entries, too.
*/
- GIT_DIFF_SKIP_BINARY_CHECK = (1 << 14),
+ GIT_DIFF_RECURSE_UNTRACKED_DIRS = (1u << 4),
+
+ /** Include unmodified files in the diff */
+ GIT_DIFF_INCLUDE_UNMODIFIED = (1u << 5),
/** Normally, a type change between files will be converted into a
* DELETED record for the old and an ADDED record for the new; this
* options enabled the generation of TYPECHANGE delta records.
*/
- GIT_DIFF_INCLUDE_TYPECHANGE = (1 << 15),
+ GIT_DIFF_INCLUDE_TYPECHANGE = (1u << 6),
/** Even with GIT_DIFF_INCLUDE_TYPECHANGE, blob->tree changes still
* generally show as a DELETED blob. This flag tries to correctly
* label blob->tree transitions as TYPECHANGE records with new_file's
* mode set to tree. Note: the tree SHA will not be available.
*/
- GIT_DIFF_INCLUDE_TYPECHANGE_TREES = (1 << 16),
+ GIT_DIFF_INCLUDE_TYPECHANGE_TREES = (1u << 7),
/** Ignore file mode changes */
- GIT_DIFF_IGNORE_FILEMODE = (1 << 17),
+ GIT_DIFF_IGNORE_FILEMODE = (1u << 8),
- /** Even with GIT_DIFF_INCLUDE_IGNORED, an entire ignored directory
- * will be marked with only a single entry in the diff list; this flag
- * adds all files under the directory as IGNORED entries, too.
+ /** Treat all submodules as unmodified */
+ GIT_DIFF_IGNORE_SUBMODULES = (1u << 9),
+
+ /** Use case insensitive filename comparisons */
+ GIT_DIFF_IGNORE_CASE = (1u << 10),
+
+ /** If the pathspec is set in the diff options, this flags means to
+ * apply it as an exact match instead of as an fnmatch pattern.
+ */
+ GIT_DIFF_DISABLE_PATHSPEC_MATCH = (1u << 12),
+
+ /** Disable updating of the `binary` flag in delta records. This is
+ * useful when iterating over a diff if you don't need hunk and data
+ * callbacks and want to avoid having to load file completely.
+ */
+ GIT_DIFF_SKIP_BINARY_CHECK = (1u << 13),
+
+ /** When diff finds an untracked directory, to match the behavior of
+ * core Git, it scans the contents for IGNORED and UNTRACKED files.
+ * If *all* contents are IGNORED, then the directory is IGNORED; if
+ * any contents are not IGNORED, then the directory is UNTRACKED.
+ * This is extra work that may not matter in many cases. This flag
+ * turns off that scan and immediately labels an untracked directory
+ * as UNTRACKED (changing the behavior to not match core Git).
*/
- GIT_DIFF_RECURSE_IGNORED_DIRS = (1 << 18),
-
- /** Core Git scans inside untracked directories, labeling them IGNORED
- * if they are empty or only contain ignored files; a directory is
- * consider UNTRACKED only if it has an actual untracked file in it.
- * This scan is extra work for a case you often don't care about. This
- * flag makes libgit2 immediately label an untracked directory as
- * UNTRACKED without looking inside it (which differs from core Git).
- * Of course, ignore rules are still checked for the directory itself.
+ GIT_DIFF_ENABLE_FAST_UNTRACKED_DIRS = (1u << 14),
+
+ /*
+ * Options controlling how output will be generated
*/
- GIT_DIFF_FAST_UNTRACKED_DIRS = (1 << 19),
+ /** Treat all files as text, disabling binary attributes & detection */
+ GIT_DIFF_FORCE_TEXT = (1u << 20),
/** Treat all files as binary, disabling text diffs */
- GIT_DIFF_FORCE_BINARY = (1 << 20),
+ GIT_DIFF_FORCE_BINARY = (1u << 21),
+
+ /** Ignore all whitespace */
+ GIT_DIFF_IGNORE_WHITESPACE = (1u << 22),
+ /** Ignore changes in amount of whitespace */
+ GIT_DIFF_IGNORE_WHITESPACE_CHANGE = (1u << 23),
+ /** Ignore whitespace at end of line */
+ GIT_DIFF_IGNORE_WHITESPACE_EOL = (1u << 24),
+
+ /** When generating patch text, include the content of untracked
+ * files. This automatically turns on GIT_DIFF_INCLUDE_UNTRACKED but
+ * it does not turn on GIT_DIFF_RECURSE_UNTRACKED_DIRS. Add that
+ * flag if you want the content of every single UNTRACKED file.
+ */
+ GIT_DIFF_SHOW_UNTRACKED_CONTENT = (1u << 25),
+
+ /** When generating output, include the names of unmodified files if
+ * they are included in the git_diff. Normally these are skipped in
+ * the formats that list files (e.g. name-only, name-status, raw).
+ * Even with this, these will not be included in patch format.
+ */
+ GIT_DIFF_SHOW_UNMODIFIED = (1u << 26),
+
+ /** Use the "patience diff" algorithm (currently unimplemented) */
+ GIT_DIFF_PATIENCE = (1u << 28),
} git_diff_option_t;
/**
* considered reserved for internal or future use.
*/
typedef enum {
- GIT_DIFF_FLAG_BINARY = (1 << 0), /** file(s) treated as binary data */
- GIT_DIFF_FLAG_NOT_BINARY = (1 << 1), /** file(s) treated as text data */
- GIT_DIFF_FLAG_VALID_OID = (1 << 2), /** `oid` value is known correct */
+ GIT_DIFF_FLAG_BINARY = (1u << 0), /** file(s) treated as binary data */
+ GIT_DIFF_FLAG_NOT_BINARY = (1u << 1), /** file(s) treated as text data */
+ GIT_DIFF_FLAG_VALID_OID = (1u << 2), /** `oid` value is known correct */
} git_diff_flag_t;
/**
* What type of change is described by a git_diff_delta?
*
* `GIT_DELTA_RENAMED` and `GIT_DELTA_COPIED` will only show up if you run
- * `git_diff_find_similar()` on the diff list object.
+ * `git_diff_find_similar()` on the diff object.
*
* `GIT_DELTA_TYPECHANGE` only shows up given `GIT_DIFF_INCLUDE_TYPECHANGE`
* in the option flags (otherwise type changes will be split into ADDED /
*
* When the callback:
* - returns < 0, the diff process will be aborted.
- * - returns > 0, the delta will not be inserted into the diff list, but the
+ * - returns > 0, the delta will not be inserted into the diff, but the
* diff process continues.
- * - returns 0, the delta is inserted into the diff list, and the diff process
+ * - returns 0, the delta is inserted into the diff, and the diff process
* continues.
*/
typedef int (*git_diff_notify_cb)(
typedef struct {
unsigned int version; /**< version for the struct */
uint32_t flags; /**< defaults to GIT_DIFF_NORMAL */
- uint16_t context_lines; /**< defaults to 3 */
- uint16_t interhunk_lines; /**< defaults to 0 */
- const char *old_prefix; /**< defaults to "a" */
- const char *new_prefix; /**< defaults to "b" */
+
+ /* options controlling which files are in the diff */
+
+ git_submodule_ignore_t ignore_submodules; /** << submodule ignore rule */
git_strarray pathspec; /**< defaults to include all paths */
- git_off_t max_size; /**< defaults to 512MB */
git_diff_notify_cb notify_cb;
void *notify_payload;
- git_submodule_ignore_t ignore_submodules; /** << submodule ignore rule */
+
+ /* options controlling how to diff text is generated */
+
+ uint16_t context_lines; /**< defaults to 3 */
+ uint16_t interhunk_lines; /**< defaults to 0 */
+ uint16_t oid_abbrev; /**< default 'core.abbrev' or 7 if unset */
+ git_off_t max_size; /**< defaults to 512MB */
+ const char *old_prefix; /**< defaults to "a" */
+ const char *new_prefix; /**< defaults to "b" */
} git_diff_options;
#define GIT_DIFF_OPTIONS_VERSION 1
-#define GIT_DIFF_OPTIONS_INIT {GIT_DIFF_OPTIONS_VERSION, GIT_DIFF_NORMAL, 3}
+#define GIT_DIFF_OPTIONS_INIT \
+ {GIT_DIFF_OPTIONS_VERSION, 0, 0, {NULL,0}, NULL, NULL, 3}
/**
* When iterating over a diff, callback that will be made per file.
*
* @param delta A pointer to the delta data for the file
- * @param progress Goes from 0 to 1 over the diff list
+ * @param progress Goes from 0 to 1 over the diff
* @param payload User-specified pointer from foreach function
*/
typedef int (*git_diff_file_cb)(
GIT_DIFF_LINE_DEL_EOFNL = '<', /**< Old has LF at end, new does not */
/* The following values will only be sent to a `git_diff_line_cb` when
- * the content of a diff is being formatted (eg. through
- * git_diff_print_patch() or git_diff_print_compact(), for instance).
+ * the content of a diff is being formatted through `git_diff_print`.
*/
GIT_DIFF_LINE_FILE_HDR = 'F',
GIT_DIFF_LINE_HUNK_HDR = 'H',
*/
typedef enum {
/** look for renames? (`--find-renames`) */
- GIT_DIFF_FIND_RENAMES = (1 << 0),
+ GIT_DIFF_FIND_RENAMES = (1u << 0),
/** consider old side of modified for renames? (`--break-rewrites=N`) */
- GIT_DIFF_FIND_RENAMES_FROM_REWRITES = (1 << 1),
+ GIT_DIFF_FIND_RENAMES_FROM_REWRITES = (1u << 1),
/** look for copies? (a la `--find-copies`) */
- GIT_DIFF_FIND_COPIES = (1 << 2),
+ GIT_DIFF_FIND_COPIES = (1u << 2),
/** consider unmodified as copy sources? (`--find-copies-harder`) */
- GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED = (1 << 3),
+ GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED = (1u << 3),
/** mark large rewrites for split (`--break-rewrites=/M`) */
- GIT_DIFF_FIND_REWRITES = (1 << 4),
+ GIT_DIFF_FIND_REWRITES = (1u << 4),
/** actually split large rewrites into delete/add pairs */
- GIT_DIFF_BREAK_REWRITES = (1 << 5),
+ GIT_DIFF_BREAK_REWRITES = (1u << 5),
/** mark rewrites for split and break into delete/add pairs */
GIT_DIFF_FIND_AND_BREAK_REWRITES =
(GIT_DIFF_FIND_REWRITES | GIT_DIFF_BREAK_REWRITES),
/** find renames/copies for untracked items in working directory */
- GIT_DIFF_FIND_FOR_UNTRACKED = (1 << 6),
+ GIT_DIFF_FIND_FOR_UNTRACKED = (1u << 6),
/** turn on all finding features */
GIT_DIFF_FIND_ALL = (0x0ff),
/** measure similarity ignoring leading whitespace (default) */
GIT_DIFF_FIND_IGNORE_LEADING_WHITESPACE = 0,
/** measure similarity ignoring all whitespace */
- GIT_DIFF_FIND_IGNORE_WHITESPACE = (1 << 12),
+ GIT_DIFF_FIND_IGNORE_WHITESPACE = (1u << 12),
/** measure similarity including all data */
- GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE = (1 << 13),
+ GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE = (1u << 13),
/** measure similarity only by comparing SHAs (fast and cheap) */
- GIT_DIFF_FIND_EXACT_MATCH_ONLY = (1 << 14),
+ GIT_DIFF_FIND_EXACT_MATCH_ONLY = (1u << 14),
/** do not break rewrites unless they contribute to a rename */
- GIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY = (1 << 15),
+ GIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY = (1u << 15),
} git_diff_find_t;
/**
#define GIT_DIFF_FIND_OPTIONS_VERSION 1
#define GIT_DIFF_FIND_OPTIONS_INIT {GIT_DIFF_FIND_OPTIONS_VERSION}
-/** @name Diff List Generator Functions
+/** @name Diff Generator Functions
*
* These are the functions you would use to create (or destroy) a
* git_diff from various objects in a repository.
/**@{*/
/**
- * Deallocate a diff list.
+ * Deallocate a diff.
*
- * @param diff The previously created diff list; cannot be used after free.
+ * @param diff The previously created diff; cannot be used after free.
*/
GIT_EXTERN(void) git_diff_free(git_diff *diff);
/**
- * Create a diff list with the difference between two tree objects.
+ * Create a diff with the difference between two tree objects.
*
* This is equivalent to `git diff <old-tree> <new-tree>`
*
const git_diff_options *opts); /**< can be NULL for defaults */
/**
- * Create a diff list between a tree and repository index.
+ * Create a diff between a tree and repository index.
*
* This is equivalent to `git diff --cached <treeish>` or if you pass
* the HEAD tree, then like `git diff --cached`.
const git_diff_options *opts); /**< can be NULL for defaults */
/**
- * Create a diff list between the repository index and the workdir directory.
+ * Create a diff between the repository index and the workdir directory.
*
* This matches the `git diff` command. See the note below on
* `git_diff_tree_to_workdir` for a discussion of the difference between
const git_diff_options *opts); /**< can be NULL for defaults */
/**
- * Create a diff list between a tree and the working directory.
+ * Create a diff between a tree and the working directory.
*
* The tree you provide will be used for the "old_file" side of the delta,
* and the working directory will be used for the "new_file" side.
* files in the index. It may come as a surprise, but there is no direct
* equivalent in core git.
*
- * To emulate `git diff <treeish>`, call both `git_diff_tree_to_index` and
- * `git_diff_index_to_workdir`, then call `git_diff_merge` on the results.
- * That will yield a `git_diff` that matches the git output.
+ * To emulate `git diff <tree>`, use `git_diff_tree_to_workdir_with_index`
+ * (or `git_diff_tree_to_index` and `git_diff_index_to_workdir`, then call
+ * `git_diff_merge` on the results). That will yield a `git_diff` that
+ * matches the git output.
*
* If this seems confusing, take the case of a file with a staged deletion
* where the file has then been put back into the working dir and modified.
const git_diff_options *opts); /**< can be NULL for defaults */
/**
- * Merge one diff list into another.
+ * Create a diff between a tree and the working directory using index data
+ * to account for staged deletes, tracked files, etc.
+ *
+ * This emulates `git diff <tree>` by diffing the tree to the index and
+ * the index to the working directory and blending the results into a
+ * single diff that includes staged deleted, etc.
+ *
+ * @param diff A pointer to a git_diff pointer that will be allocated.
+ * @param repo The repository containing the tree.
+ * @param old_tree A git_tree object to diff from, or NULL for empty tree.
+ * @param opts Structure with options to influence diff or NULL for defaults.
+ */
+GIT_EXTERN(int) git_diff_tree_to_workdir_with_index(
+ git_diff **diff,
+ git_repository *repo,
+ git_tree *old_tree,
+ const git_diff_options *opts); /**< can be NULL for defaults */
+
+/**
+ * Merge one diff into another.
*
* This merges items from the "from" list into the "onto" list. The
- * resulting diff list will have all items that appear in either list.
+ * resulting diff will have all items that appear in either list.
* If an item appears in both lists, then it will be "merged" to appear
* as if the old version was from the "onto" list and the new version
* is from the "from" list (with the exception that if the item has a
const git_diff *from);
/**
- * Transform a diff list marking file renames, copies, etc.
+ * Transform a diff marking file renames, copies, etc.
*
- * This modifies a diff list in place, replacing old entries that look
+ * This modifies a diff in place, replacing old entries that look
* like renames or copies with new entries reflecting those changes.
* This also will, if requested, break modified files into add/remove
* pairs if the amount of change is above a threshold.
*
- * @param diff Diff list to run detection algorithms on
+ * @param diff diff to run detection algorithms on
* @param options Control how detection should be run, NULL for defaults
* @return 0 on success, -1 on failure
*/
GIT_EXTERN(int) git_diff_find_similar(
git_diff *diff,
- git_diff_find_options *options);
+ const git_diff_find_options *options);
/**@}*/
-/** @name Diff List Processor Functions
+/** @name Diff Processor Functions
*
- * These are the functions you apply to a diff list to process it
+ * These are the functions you apply to a diff to process it
* or read it in some way.
*/
/**@{*/
/**
- * Loop over all deltas in a diff list issuing callbacks.
+ * Query how many diff records are there in a diff.
+ *
+ * @param diff A git_diff generated by one of the above functions
+ * @return Count of number of deltas in the list
+ */
+GIT_EXTERN(size_t) git_diff_num_deltas(const git_diff *diff);
+
+/**
+ * Query how many diff deltas are there in a diff filtered by type.
+ *
+ * This works just like `git_diff_entrycount()` with an extra parameter
+ * that is a `git_delta_t` and returns just the count of how many deltas
+ * match that particular type.
+ *
+ * @param diff A git_diff generated by one of the above functions
+ * @param type A git_delta_t value to filter the count
+ * @return Count of number of deltas matching delta_t type
+ */
+GIT_EXTERN(size_t) git_diff_num_deltas_of_type(
+ const git_diff *diff, git_delta_t type);
+
+/**
+ * Return the diff delta for an entry in the diff list.
+ *
+ * The `git_delta` pointer points to internal data and you do not have
+ * to release it when you are done with it. It will go away when the
+ * `git_diff` (or any associated `git_patch`) goes away.
+ *
+ * Note that the flags on the delta related to whether it has binary
+ * content or not may not be set if there are no attributes set for the
+ * file and there has been no reason to load the file data at this point.
+ * For now, if you need those flags to be up to date, your only option is
+ * to either use `git_diff_foreach` or create a `git_patch`.
+ *
+ * @param diff Diff list object
+ * @param idx Index into diff list
+ * @return Pointer to git_diff_delta (or NULL if `idx` out of range)
+ */
+GIT_EXTERN(const git_diff_delta *) git_diff_get_delta(
+ const git_diff *diff, size_t idx);
+
+/**
+ * Check if deltas are sorted case sensitively or insensitively.
+ *
+ * @param diff diff to check
+ * @return 0 if case sensitive, 1 if case is ignored
+ */
+GIT_EXTERN(int) git_diff_is_sorted_icase(const git_diff *diff);
+
+/**
+ * Loop over all deltas in a diff issuing callbacks.
*
* This will iterate through all of the files described in a diff. You
* should provide a file callback to learn about each file.
*
* The "hunk" and "line" callbacks are optional, and the text diff of the
* files will only be calculated if they are not NULL. Of course, these
- * callbacks will not be invoked for binary files on the diff list or for
+ * callbacks will not be invoked for binary files on the diff or for
* files whose only changed is a file mode change.
*
* Returning a non-zero value from any of the callbacks will terminate
git_diff_line_cb line_cb,
void *payload);
-/**
- * Iterate over a diff generating text output like "git diff --name-status".
- *
- * Returning a non-zero value from the callbacks will terminate the
- * iteration and cause this return `GIT_EUSER`.
- *
- * @param diff A git_diff generated by one of the above functions.
- * @param print_cb Callback to make per line of diff text.
- * @param payload Reference pointer that will be passed to your callback.
- * @return 0 on success, GIT_EUSER on non-zero callback, or error code
- */
-GIT_EXTERN(int) git_diff_print_compact(
- git_diff *diff,
- git_diff_line_cb print_cb,
- void *payload);
-
-/**
- * Iterate over a diff generating text output like "git diff --raw".
- *
- * Returning a non-zero value from the callbacks will terminate the
- * iteration and cause this return `GIT_EUSER`.
- *
- * @param diff A git_diff generated by one of the above functions.
- * @param print_cb Callback to make per line of diff text.
- * @param payload Reference pointer that will be passed to your callback.
- * @return 0 on success, GIT_EUSER on non-zero callback, or error code
- */
-GIT_EXTERN(int) git_diff_print_raw(
- git_diff *diff,
- git_diff_line_cb print_cb,
- void *payload);
-
/**
* Look up the single character abbreviation for a delta status code.
*
- * When you call `git_diff_print_compact` it prints single letter codes into
- * the output such as 'A' for added, 'D' for deleted, 'M' for modified, etc.
- * It is sometimes convenient to convert a git_delta_t value into these
- * letters for your own purposes. This function does just that. By the
- * way, unmodified will return a space (i.e. ' ').
+ * When you run `git diff --name-status` it uses single letter codes in
+ * the output such as 'A' for added, 'D' for deleted, 'M' for modified,
+ * etc. This function converts a git_delta_t value into these letters for
+ * your own purposes. GIT_DELTA_UNTRACKED will return a space (i.e. ' ').
*
* @param status The git_delta_t value to look up
* @return The single character label for that code
GIT_EXTERN(char) git_diff_status_char(git_delta_t status);
/**
- * Iterate over a diff generating text output like "git diff".
- *
- * This is a super easy way to generate a patch from a diff.
+ * Possible output formats for diff data
+ */
+typedef enum {
+ GIT_DIFF_FORMAT_PATCH = 1u, /**< full git diff */
+ GIT_DIFF_FORMAT_PATCH_HEADER = 2u, /**< just the file headers of patch */
+ GIT_DIFF_FORMAT_RAW = 3u, /**< like git diff --raw */
+ GIT_DIFF_FORMAT_NAME_ONLY = 4u, /**< like git diff --name-only */
+ GIT_DIFF_FORMAT_NAME_STATUS = 5u, /**< like git diff --name-status */
+} git_diff_format_t;
+
+/**
+ * Iterate over a diff generating formatted text output.
*
* Returning a non-zero value from the callbacks will terminate the
* iteration and cause this return `GIT_EUSER`.
*
* @param diff A git_diff generated by one of the above functions.
- * @param payload Reference pointer that will be passed to your callbacks.
- * @param print_cb Callback function to output lines of the diff. This
- * same function will be called for file headers, hunk
- * headers, and diff lines. Fortunately, you can probably
- * use various GIT_DIFF_LINE constants to determine what
- * text you are given.
+ * @param format A git_diff_forrmat_t value to pick the text format.
+ * @param print_cb Callback to make per line of diff text.
+ * @param payload Reference pointer that will be passed to your callback.
* @return 0 on success, GIT_EUSER on non-zero callback, or error code
*/
-GIT_EXTERN(int) git_diff_print_patch(
+GIT_EXTERN(int) git_diff_print(
git_diff *diff,
+ git_diff_format_t format,
git_diff_line_cb print_cb,
void *payload);
-/**
- * Query how many diff records are there in a diff list.
- *
- * @param diff A git_diff generated by one of the above functions
- * @return Count of number of deltas in the list
- */
-GIT_EXTERN(size_t) git_diff_num_deltas(git_diff *diff);
-
-/**
- * Query how many diff deltas are there in a diff list filtered by type.
- *
- * This works just like `git_diff_entrycount()` with an extra parameter
- * that is a `git_delta_t` and returns just the count of how many deltas
- * match that particular type.
- *
- * @param diff A git_diff generated by one of the above functions
- * @param type A git_delta_t value to filter the count
- * @return Count of number of deltas matching delta_t type
- */
-GIT_EXTERN(size_t) git_diff_num_deltas_of_type(
- git_diff *diff,
- git_delta_t type);
-
-/**
- * Check if deltas are sorted case sensitively or insensitively.
- *
- * @param diff Diff list to check
- * @return 0 if case sensitive, 1 if case is ignored
- */
-GIT_EXTERN(int) git_diff_is_sorted_icase(const git_diff *diff);
-
/**@}*/
* It is okay to pass NULL for either of the output parameters; if you pass
* NULL for the `git_patch`, then the text diff will not be calculated.
*
- * @param patch_out Output parameter for the delta patch object
- * @param delta_out Output parameter for the delta object
+ * @param out Output parameter for the delta patch object
* @param diff Diff list object
* @param idx Index into diff list
* @return 0 on success, other value < 0 on error
*/
GIT_EXTERN(int) git_patch_from_diff(
- git_patch **patch_out,
- const git_diff_delta **delta_out,
- git_diff *diff,
- size_t idx);
+ git_patch **out, git_diff *diff, size_t idx);
/**
* Directly generate a patch from the difference between two blobs.
/**
* Free a git_patch object.
*/
-GIT_EXTERN(void) git_patch_free(
- git_patch *patch);
+GIT_EXTERN(void) git_patch_free(git_patch *patch);
/**
* Get the delta associated with a patch
*/
-GIT_EXTERN(const git_diff_delta *) git_patch_delta(
- git_patch *patch);
+GIT_EXTERN(const git_diff_delta *) git_patch_get_delta(git_patch *patch);
/**
* Get the number of hunks in a patch
*/
-GIT_EXTERN(size_t) git_patch_num_hunks(
- git_patch *patch);
+GIT_EXTERN(size_t) git_patch_num_hunks(git_patch *patch);
/**
* Get line counts of each type in a patch.
if (!git_pathspec__match(
&diff->pathspec, entry->path,
DIFF_FLAG_IS_SET(diff, GIT_DIFF_DISABLE_PATHSPEC_MATCH),
- DIFF_FLAG_IS_SET(diff, GIT_DIFF_DELTAS_ARE_ICASE),
+ DIFF_FLAG_IS_SET(diff, GIT_DIFF_IGNORE_CASE),
&matched_pathspec, NULL))
return 0;
* the ignore_case bit set */
if (!git_iterator_ignore_case(old_iter) &&
!git_iterator_ignore_case(new_iter)) {
- diff->opts.flags &= ~GIT_DIFF_DELTAS_ARE_ICASE;
+ diff->opts.flags &= ~GIT_DIFF_IGNORE_CASE;
diff->strcomp = git__strcmp;
diff->strncomp = git__strncmp;
diff->pfxcomp = git__prefixcmp;
diff->entrycomp = git_index_entry__cmp;
} else {
- diff->opts.flags |= GIT_DIFF_DELTAS_ARE_ICASE;
+ diff->opts.flags |= GIT_DIFF_IGNORE_CASE;
diff->strcomp = git__strcasecmp;
diff->strncomp = git__strncasecmp;
if (opts) {
/* copy user options (except case sensitivity info from iterators) */
- bool icase = DIFF_FLAG_IS_SET(diff, GIT_DIFF_DELTAS_ARE_ICASE);
+ bool icase = DIFF_FLAG_IS_SET(diff, GIT_DIFF_IGNORE_CASE);
memcpy(&diff->opts, opts, sizeof(diff->opts));
- DIFF_FLAG_SET(diff, GIT_DIFF_DELTAS_ARE_ICASE, icase);
+ DIFF_FLAG_SET(diff, GIT_DIFF_IGNORE_CASE, icase);
/* initialize pathspec from options */
if (git_pathspec__vinit(&diff->pathspec, &opts->pathspec, pool) < 0)
diff->opts.flags |= GIT_DIFF_INCLUDE_TYPECHANGE;
/* flag INCLUDE_UNTRACKED_CONTENT implies INCLUDE_UNTRACKED */
- if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_INCLUDE_UNTRACKED_CONTENT))
+ if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_SHOW_UNTRACKED_CONTENT))
diff->opts.flags |= GIT_DIFF_INCLUDE_UNTRACKED;
/* load config values that affect diff behavior */
if (!git_pathspec__match(
&diff->pathspec, oitem->path,
DIFF_FLAG_IS_SET(diff, GIT_DIFF_DISABLE_PATHSPEC_MATCH),
- DIFF_FLAG_IS_SET(diff, GIT_DIFF_DELTAS_ARE_ICASE),
+ DIFF_FLAG_IS_SET(diff, GIT_DIFF_IGNORE_CASE),
&matched_pathspec, NULL))
return 0;
*/
if (!recurse_into_dir &&
delta_type == GIT_DELTA_UNTRACKED &&
- DIFF_FLAG_ISNT_SET(diff, GIT_DIFF_FAST_UNTRACKED_DIRS))
+ DIFF_FLAG_ISNT_SET(diff, GIT_DIFF_ENABLE_FAST_UNTRACKED_DIRS))
{
git_diff_delta *last;
git_buf_init(&info.ignore_prefix, 0);
/* make iterators have matching icase behavior */
- if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_DELTAS_ARE_ICASE)) {
+ if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_IGNORE_CASE)) {
if ((error = git_iterator_set_ignore_case(old_iter, true)) < 0 ||
(error = git_iterator_set_ignore_case(new_iter, true)) < 0)
goto cleanup;
* currently case insensitive, unless the user explicitly asked
* for case insensitivity
*/
- if (opts && (opts->flags & GIT_DIFF_DELTAS_ARE_ICASE) != 0)
+ if (opts && (opts->flags & GIT_DIFF_IGNORE_CASE) != 0)
iflag = GIT_ITERATOR_IGNORE_CASE;
DIFF_FROM_ITERATORS(
if (!error) {
git_diff *d = *diff;
- d->opts.flags |= GIT_DIFF_DELTAS_ARE_ICASE;
+ d->opts.flags |= GIT_DIFF_IGNORE_CASE;
d->strcomp = git__strcasecmp;
d->strncomp = git__strncasecmp;
d->pfxcomp = git__prefixcmp_icase;
return error;
}
-
int git_diff_tree_to_workdir(
git_diff **diff,
git_repository *repo,
return error;
}
-size_t git_diff_num_deltas(git_diff *diff)
+int git_diff_tree_to_workdir_with_index(
+ git_diff **diff,
+ git_repository *repo,
+ git_tree *old_tree,
+ const git_diff_options *opts)
+{
+ int error = 0;
+ git_diff *d1 = NULL, *d2 = NULL;
+
+ assert(diff && repo);
+
+ if (!(error = git_diff_tree_to_index(&d1, repo, old_tree, NULL, opts)) &&
+ !(error = git_diff_index_to_workdir(&d2, repo, NULL, opts)))
+ error = git_diff_merge(d1, d2);
+
+ git_diff_free(d2);
+
+ if (error) {
+ git_diff_free(d1);
+ d1 = NULL;
+ }
+
+ *diff = d1;
+ return error;
+}
+
+
+size_t git_diff_num_deltas(const git_diff *diff)
{
assert(diff);
- return (size_t)diff->deltas.length;
+ return diff->deltas.length;
}
-size_t git_diff_num_deltas_of_type(git_diff *diff, git_delta_t type)
+size_t git_diff_num_deltas_of_type(const git_diff *diff, git_delta_t type)
{
size_t i, count = 0;
- git_diff_delta *delta;
+ const git_diff_delta *delta;
assert(diff);
return count;
}
+const git_diff_delta *git_diff_get_delta(const git_diff *diff, size_t idx)
+{
+ assert(diff);
+ return git_vector_get(&diff->deltas, idx);
+}
+
int git_diff_is_sorted_icase(const git_diff *diff)
{
- return (diff->opts.flags & GIT_DIFF_DELTAS_ARE_ICASE) != 0;
+ return (diff->opts.flags & GIT_DIFF_IGNORE_CASE) != 0;
}
int git_diff__paired_foreach(
* always sort by the old name in the i2w list.
*/
h2i_icase = head2idx != NULL &&
- (head2idx->opts.flags & GIT_DIFF_DELTAS_ARE_ICASE) != 0;
+ (head2idx->opts.flags & GIT_DIFF_IGNORE_CASE) != 0;
i2w_icase = idx2wd != NULL &&
- (idx2wd->opts.flags & GIT_DIFF_DELTAS_ARE_ICASE) != 0;
+ (idx2wd->opts.flags & GIT_DIFF_IGNORE_CASE) != 0;
icase_mismatch =
(head2idx != NULL && idx2wd != NULL && h2i_icase != i2w_icase);
has_data = use_old; break;
case GIT_DELTA_UNTRACKED:
has_data = !use_old &&
- (diff->opts.flags & GIT_DIFF_INCLUDE_UNTRACKED_CONTENT) != 0;
+ (diff->opts.flags & GIT_DIFF_SHOW_UNTRACKED_CONTENT) != 0;
break;
case GIT_DELTA_MODIFIED:
case GIT_DELTA_COPIED:
struct diff_patch_line {
const char *ptr;
size_t len;
- size_t lines, oldno, newno;
+ size_t lines;
+ size_t oldno;
+ size_t newno;
char origin;
};
}
static int diff_patch_alloc_from_diff(
- git_patch **out,
- git_diff *diff,
- size_t delta_index)
+ git_patch **out, git_diff *diff, size_t delta_index)
{
int error;
git_patch *patch = git__calloc(1, sizeof(git_patch));
}
int git_patch_from_diff(
- git_patch **patch_ptr,
- const git_diff_delta **delta_ptr,
- git_diff *diff,
- size_t idx)
+ git_patch **patch_ptr, git_diff *diff, size_t idx)
{
int error = 0;
git_xdiff_output xo;
git_patch *patch = NULL;
if (patch_ptr) *patch_ptr = NULL;
- if (delta_ptr) *delta_ptr = NULL;
if (diff_required(diff, "git_patch_from_diff") < 0)
return -1;
return GIT_ENOTFOUND;
}
- if (delta_ptr)
- *delta_ptr = delta;
-
if (git_diff_delta__should_skip(&diff->opts, delta))
return 0;
GIT_REFCOUNT_DEC(patch, diff_patch_free);
}
-const git_diff_delta *git_patch_delta(git_patch *patch)
+const git_diff_delta *git_patch_get_delta(git_patch *patch)
{
assert(patch);
return patch->delta;
typedef struct {
git_diff *diff;
+ git_diff_format_t format;
git_diff_line_cb print_cb;
void *payload;
git_buf *buf;
+ uint32_t flags;
int oid_strlen;
} diff_print_info;
static int diff_print_info_init(
diff_print_info *pi,
- git_buf *out, git_diff *diff, git_diff_line_cb cb, void *payload)
+ git_buf *out,
+ git_diff *diff,
+ git_diff_format_t format,
+ git_diff_line_cb cb,
+ void *payload)
{
pi->diff = diff;
+ pi->format = format;
pi->print_cb = cb;
pi->payload = payload;
pi->buf = out;
- if (!diff || !diff->repo)
+ if (diff)
+ pi->flags = diff->opts.flags;
+
+ if (diff && diff->opts.oid_abbrev != 0)
+ pi->oid_strlen = diff->opts.oid_abbrev;
+ else if (!diff || !diff->repo)
pi->oid_strlen = GIT_ABBREV_DEFAULT;
else if (git_repository__cvar(
&pi->oid_strlen, diff->repo, GIT_CVAR_ABBREV) < 0)
return GIT_EUSER;
}
-static int diff_print_one_compact(
+static int diff_print_one_name_only(
+ const git_diff_delta *delta, float progress, void *data)
+{
+ diff_print_info *pi = data;
+ git_buf *out = pi->buf;
+
+ GIT_UNUSED(progress);
+
+ if ((pi->flags & GIT_DIFF_SHOW_UNMODIFIED) == 0 &&
+ delta->status == GIT_DELTA_UNMODIFIED)
+ return 0;
+
+ git_buf_clear(out);
+
+ if (git_buf_puts(out, delta->new_file.path) < 0 ||
+ git_buf_putc(out, '\n'))
+ return -1;
+
+ if (pi->print_cb(delta, NULL, GIT_DIFF_LINE_FILE_HDR,
+ git_buf_cstr(out), git_buf_len(out), pi->payload))
+ return callback_error();
+
+ return 0;
+}
+
+static int diff_print_one_name_status(
const git_diff_delta *delta, float progress, void *data)
{
diff_print_info *pi = data;
GIT_UNUSED(progress);
- if (code == ' ')
+ if ((pi->flags & GIT_DIFF_SHOW_UNMODIFIED) == 0 && code == ' ')
return 0;
old_suffix = diff_pick_suffix(delta->old_file.mode);
return 0;
}
-/* print a git_diff to a print callback in compact format */
-int git_diff_print_compact(
- git_diff *diff,
- git_diff_line_cb print_cb,
- void *payload)
-{
- int error;
- git_buf buf = GIT_BUF_INIT;
- diff_print_info pi;
-
- if (!(error = diff_print_info_init(&pi, &buf, diff, print_cb, payload)))
- error = git_diff_foreach(diff, diff_print_one_compact, NULL, NULL, &pi);
-
- git_buf_free(&buf);
-
- return error;
-}
-
static int diff_print_one_raw(
const git_diff_delta *delta, float progress, void *data)
{
GIT_UNUSED(progress);
- if (code == ' ')
+ if ((pi->flags & GIT_DIFF_SHOW_UNMODIFIED) == 0 && code == ' ')
return 0;
git_buf_clear(out);
return 0;
}
-/* print a git_diff to a print callback in raw output format */
-int git_diff_print_raw(
- git_diff *diff,
- git_diff_line_cb print_cb,
- void *payload)
-{
- int error;
- git_buf buf = GIT_BUF_INIT;
- diff_print_info pi;
-
- if (!(error = diff_print_info_init(&pi, &buf, diff, print_cb, payload)))
- error = git_diff_foreach(diff, diff_print_one_raw, NULL, NULL, &pi);
-
- git_buf_free(&buf);
-
- return error;
-}
-
static int diff_print_oid_range(
git_buf *out, const git_diff_delta *delta, int oid_strlen)
{
pi->diff ? pi->diff->opts.old_prefix : DIFF_OLD_PREFIX_DEFAULT;
const char *newpfx =
pi->diff ? pi->diff->opts.new_prefix : DIFF_NEW_PREFIX_DEFAULT;
- uint32_t opts_flags = pi->diff ? pi->diff->opts.flags : GIT_DIFF_NORMAL;
GIT_UNUSED(progress);
delta->status == GIT_DELTA_UNMODIFIED ||
delta->status == GIT_DELTA_IGNORED ||
(delta->status == GIT_DELTA_UNTRACKED &&
- (opts_flags & GIT_DIFF_INCLUDE_UNTRACKED_CONTENT) == 0))
+ (pi->flags & GIT_DIFF_SHOW_UNTRACKED_CONTENT) == 0))
return 0;
if (git_diff_delta__format_file_header(
return 0;
}
-/* print a git_diff to an output callback in patch format */
-int git_diff_print_patch(
+/* print a git_diff to an output callback */
+int git_diff_print(
git_diff *diff,
+ git_diff_format_t format,
git_diff_line_cb print_cb,
void *payload)
{
int error;
git_buf buf = GIT_BUF_INIT;
diff_print_info pi;
+ git_diff_file_cb print_file = NULL;
+ git_diff_hunk_cb print_hunk = NULL;
+ git_diff_line_cb print_line = NULL;
+
+ switch (format) {
+ case GIT_DIFF_FORMAT_PATCH:
+ print_file = diff_print_patch_file;
+ print_hunk = diff_print_patch_hunk;
+ print_line = diff_print_patch_line;
+ break;
+ case GIT_DIFF_FORMAT_PATCH_HEADER:
+ print_file = diff_print_patch_file;
+ break;
+ case GIT_DIFF_FORMAT_RAW:
+ print_file = diff_print_one_raw;
+ break;
+ case GIT_DIFF_FORMAT_NAME_ONLY:
+ print_file = diff_print_one_name_only;
+ break;
+ case GIT_DIFF_FORMAT_NAME_STATUS:
+ print_file = diff_print_one_name_status;
+ break;
+ default:
+ giterr_set(GITERR_INVALID, "Unknown diff output format (%d)", format);
+ return -1;
+ }
- if (!(error = diff_print_info_init(&pi, &buf, diff, print_cb, payload)))
+ if (!(error = diff_print_info_init(
+ &pi, &buf, diff, format, print_cb, payload)))
error = git_diff_foreach(
- diff, diff_print_patch_file, diff_print_patch_hunk,
- diff_print_patch_line, &pi);
+ diff, print_file, print_hunk, print_line, &pi);
git_buf_free(&buf);
assert(patch && print_cb);
if (!(error = diff_print_info_init(
- &pi, &temp, git_patch__diff(patch), print_cb, payload)))
+ &pi, &temp, git_patch__diff(patch),
+ GIT_DIFF_FORMAT_PATCH, print_cb, payload)))
error = git_patch__invoke_callbacks(
patch, diff_print_patch_file, diff_print_patch_hunk,
diff_print_patch_line, &pi);
git_pool_init(&onto_pool, 1, 0) < 0)
return -1;
- if ((onto->opts.flags & GIT_DIFF_DELTAS_ARE_ICASE) != 0 ||
- (from->opts.flags & GIT_DIFF_DELTAS_ARE_ICASE) != 0)
+ if ((onto->opts.flags & GIT_DIFF_IGNORE_CASE) != 0 ||
+ (from->opts.flags & GIT_DIFF_IGNORE_CASE) != 0)
{
ignore_case = true;
/* This function currently only supports merging diff lists that
* are sorted identically. */
- assert((onto->opts.flags & GIT_DIFF_DELTAS_ARE_ICASE) != 0 &&
- (from->opts.flags & GIT_DIFF_DELTAS_ARE_ICASE) != 0);
+ assert((onto->opts.flags & GIT_DIFF_IGNORE_CASE) != 0 &&
+ (from->opts.flags & GIT_DIFF_IGNORE_CASE) != 0);
}
for (i = 0, j = 0; i < onto->deltas.length || j < from->deltas.length; ) {
static int normalize_find_opts(
git_diff *diff,
git_diff_find_options *opts,
- git_diff_find_options *given)
+ const git_diff_find_options *given)
{
git_config *cfg = NULL;
int git_diff_find_similar(
git_diff *diff,
- git_diff_find_options *given_opts)
+ const git_diff_find_options *given_opts)
{
size_t s, t;
int error = 0, similarity;
{
git_xdiff_info *info = priv;
git_patch *patch = info->patch;
- const git_diff_delta *delta = git_patch_delta(patch);
+ const git_diff_delta *delta = git_patch_get_delta(patch);
git_diff_output *output = &info->xo->output;
if (len == 1) {
void git_xdiff_init(git_xdiff_output *xo, const git_diff_options *opts)
{
- uint32_t flags = opts ? opts->flags : GIT_DIFF_NORMAL;
+ uint32_t flags = opts ? opts->flags : 0;
xo->output.diff_cb = git_xdiff;
git_tree *tree = NULL;
git_diff *diff = NULL;
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
- size_t i;
- git_diff_delta *delta;
+ size_t i, max_i;
git_index_entry entry;
int error;
git_index *index = NULL;
&diff, repo, tree, index, &opts)) < 0)
goto cleanup;
- git_vector_foreach(&diff->deltas, i, delta) {
+ for (i = 0, max_i = git_diff_num_deltas(diff); i < max_i; ++i) {
+ const git_diff_delta *delta = git_diff_get_delta(diff, i);
+
if ((error = git_index_conflict_remove(index, delta->old_file.path)) < 0)
goto cleanup;
return error;
}
-struct cb_data {
- git_index *index;
-
- int error;
-
+struct stash_update_rules {
bool include_changed;
bool include_untracked;
bool include_ignored;
};
-static int update_index_cb(
- const git_diff_delta *delta,
- float progress,
- void *payload)
+static int stash_update_index_from_diff(
+ git_index *index,
+ const git_diff *diff,
+ struct stash_update_rules *data)
{
- struct cb_data *data = (struct cb_data *)payload;
- const char *add_path = NULL;
-
- GIT_UNUSED(progress);
-
- switch (delta->status) {
- case GIT_DELTA_IGNORED:
- if (data->include_ignored)
- add_path = delta->new_file.path;
- break;
-
- case GIT_DELTA_UNTRACKED:
- if (data->include_untracked)
- add_path = delta->new_file.path;
- break;
-
- case GIT_DELTA_ADDED:
- case GIT_DELTA_MODIFIED:
- if (data->include_changed)
- add_path = delta->new_file.path;
- break;
-
- case GIT_DELTA_DELETED:
- if (!data->include_changed)
+ int error = 0;
+ size_t d, max_d = git_diff_num_deltas(diff);
+
+ for (d = 0; !error && d < max_d; ++d) {
+ const char *add_path = NULL;
+ const git_diff_delta *delta = git_diff_get_delta(diff, d);
+
+ switch (delta->status) {
+ case GIT_DELTA_IGNORED:
+ if (data->include_ignored)
+ add_path = delta->new_file.path;
+ break;
+
+ case GIT_DELTA_UNTRACKED:
+ if (data->include_untracked)
+ add_path = delta->new_file.path;
+ break;
+
+ case GIT_DELTA_ADDED:
+ case GIT_DELTA_MODIFIED:
+ if (data->include_changed)
+ add_path = delta->new_file.path;
+ break;
+
+ case GIT_DELTA_DELETED:
+ if (data->include_changed &&
+ !git_index_find(NULL, index, delta->old_file.path))
+ error = git_index_remove(index, delta->old_file.path, 0);
break;
- if (git_index_find(NULL, data->index, delta->old_file.path) == 0)
- data->error = git_index_remove(
- data->index, delta->old_file.path, 0);
- break;
-
- default:
- /* Unimplemented */
- giterr_set(
- GITERR_INVALID,
- "Cannot update index. Unimplemented status (%d)",
- delta->status);
- data->error = -1;
- break;
- }
- if (add_path != NULL)
- data->error = git_index_add_bypath(data->index, add_path);
+ default:
+ /* Unimplemented */
+ giterr_set(
+ GITERR_INVALID,
+ "Cannot update index. Unimplemented status (%d)",
+ delta->status);
+ return -1;
+ }
+
+ if (add_path != NULL)
+ error = git_index_add_bypath(index, add_path);
+ }
- return data->error;
+ return error;
}
static int build_untracked_tree(
git_tree *i_tree = NULL;
git_diff *diff = NULL;
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
- struct cb_data data = {0};
+ struct stash_update_rules data = {0};
int error;
git_index_clear(index);
- data.index = index;
-
if (flags & GIT_STASH_INCLUDE_UNTRACKED) {
opts.flags |= GIT_DIFF_INCLUDE_UNTRACKED |
GIT_DIFF_RECURSE_UNTRACKED_DIRS;
&diff, git_index_owner(index), i_tree, &opts)) < 0)
goto cleanup;
- if ((error = git_diff_foreach(
- diff, update_index_cb, NULL, NULL, &data)) < 0)
- {
- if (error == GIT_EUSER)
- error = data.error;
+ if ((error = stash_update_index_from_diff(index, diff, &data)) < 0)
goto cleanup;
- }
error = build_tree_from_index(tree_out, index);
{
git_repository *repo = git_index_owner(index);
git_tree *b_tree = NULL;
- git_diff *diff = NULL, *diff2 = NULL;
+ git_diff *diff = NULL;
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
- struct cb_data data = {0};
+ struct stash_update_rules data = {0};
int error;
opts.flags = GIT_DIFF_IGNORE_SUBMODULES;
if ((error = git_commit_tree(&b_tree, b_commit)) < 0)
goto cleanup;
- if ((error = git_diff_tree_to_index(&diff, repo, b_tree, NULL, &opts)) < 0)
+ if ((error = git_diff_tree_to_workdir_with_index(
+ &diff, repo, b_tree, &opts)) < 0)
goto cleanup;
- if ((error = git_diff_index_to_workdir(&diff2, repo, NULL, &opts)) < 0)
- goto cleanup;
-
- if ((error = git_diff_merge(diff, diff2)) < 0)
- goto cleanup;
-
- data.index = index;
data.include_changed = true;
- if ((error = git_diff_foreach(
- diff, update_index_cb, NULL, NULL, &data)) < 0)
- {
- if (error == GIT_EUSER)
- error = data.error;
+ if ((error = stash_update_index_from_diff(index, diff, &data)) < 0)
goto cleanup;
- }
-
- if ((error = build_tree_from_index(tree_out, index)) < 0)
- goto cleanup;
+ error = build_tree_from_index(tree_out, index);
cleanup:
git_diff_free(diff);
- git_diff_free(diff2);
git_tree_free(b_tree);
return error;
cl_assert(p != NULL);
- delta = git_patch_delta(p);
+ delta = git_patch_get_delta(p);
cl_assert(delta != NULL);
cl_assert_equal_i(GIT_DELTA_MODIFIED, delta->status);
cl_assert(git_oid_equal(git_blob_id(a), &delta->old_file.oid));
cl_assert(p != NULL);
- delta = git_patch_delta(p);
+ delta = git_patch_get_delta(p);
cl_assert(delta != NULL);
cl_assert_equal_i(GIT_DELTA_MODIFIED, delta->status);
cl_assert(git_oid_equal(git_blob_id(b), &delta->old_file.oid));
cl_assert(p != NULL);
- delta = git_patch_delta(p);
+ delta = git_patch_get_delta(p);
cl_assert(delta != NULL);
cl_assert_equal_i(GIT_DELTA_MODIFIED, delta->status);
cl_assert(git_oid_equal(git_blob_id(a), &delta->old_file.oid));
cl_assert(p != NULL);
- delta = git_patch_delta(p);
+ delta = git_patch_get_delta(p);
cl_assert(delta != NULL);
cl_assert_equal_i(GIT_DELTA_MODIFIED, delta->status);
cl_assert(git_oid_equal(git_blob_id(c), &delta->old_file.oid));
cl_assert(p != NULL);
- delta = git_patch_delta(p);
+ delta = git_patch_get_delta(p);
cl_assert(delta != NULL);
cl_assert_equal_i(GIT_DELTA_DELETED, delta->status);
cl_assert(git_oid_equal(git_blob_id(d), &delta->old_file.oid));
cl_assert(p != NULL);
- delta = git_patch_delta(p);
+ delta = git_patch_get_delta(p);
cl_assert(delta != NULL);
cl_assert_equal_i(GIT_DELTA_ADDED, delta->status);
cl_assert(git_oid_iszero(&delta->old_file.oid));
cl_assert(p != NULL);
- delta = git_patch_delta(p);
+ delta = git_patch_get_delta(p);
cl_assert(delta != NULL);
cl_assert_equal_i(GIT_DELTA_DELETED, delta->status);
cl_assert((delta->flags & GIT_DIFF_FLAG_BINARY) != 0);
cl_assert(p != NULL);
- delta = git_patch_delta(p);
+ delta = git_patch_get_delta(p);
cl_assert(delta != NULL);
cl_assert_equal_i(GIT_DELTA_ADDED, delta->status);
cl_assert((delta->flags & GIT_DIFF_FLAG_BINARY) != 0);
cl_git_pass(git_patch_from_blobs(&p, d, NULL, d, NULL, &opts));
cl_assert(p != NULL);
- delta = git_patch_delta(p);
+ delta = git_patch_get_delta(p);
cl_assert(delta != NULL);
cl_assert_equal_i(GIT_DELTA_UNMODIFIED, delta->status);
cl_assert_equal_sz(delta->old_file.size, git_blob_rawsize(d));
cl_git_pass(git_patch_from_blobs(&p, NULL, NULL, NULL, NULL, &opts));
cl_assert(p != NULL);
- delta = git_patch_delta(p);
+ delta = git_patch_get_delta(p);
cl_assert(delta != NULL);
cl_assert_equal_i(GIT_DELTA_UNMODIFIED, delta->status);
cl_assert_equal_sz(0, delta->old_file.size);
cl_git_pass(git_patch_from_blobs(&p, alien, NULL, alien, NULL, &opts));
cl_assert(p != NULL);
- cl_assert_equal_i(GIT_DELTA_UNMODIFIED, git_patch_delta(p)->status);
+ cl_assert_equal_i(GIT_DELTA_UNMODIFIED, git_patch_get_delta(p)->status);
cl_assert_equal_i(0, (int)git_patch_num_hunks(p));
git_patch_free(p);
}
&p, a, NULL, b_content, strlen(b_content), NULL, &opts));
cl_assert(p != NULL);
- cl_assert_equal_i(GIT_DELTA_MODIFIED, git_patch_delta(p)->status);
+ cl_assert_equal_i(GIT_DELTA_MODIFIED, git_patch_get_delta(p)->status);
cl_assert_equal_i(1, (int)git_patch_num_hunks(p));
cl_assert_equal_i(6, git_patch_num_lines_in_hunk(p, 0));
cl_git_pass(git_patch_from_blob_and_buffer(
&p, a, NULL, a_content, strlen(a_content), NULL, &opts));
cl_assert(p != NULL);
- cl_assert_equal_i(GIT_DELTA_UNMODIFIED, git_patch_delta(p)->status);
+ cl_assert_equal_i(GIT_DELTA_UNMODIFIED, git_patch_get_delta(p)->status);
cl_assert_equal_i(0, (int)git_patch_num_hunks(p));
git_patch_free(p);
cl_git_pass(git_patch_from_blob_and_buffer(
&p, NULL, NULL, a_content, strlen(a_content), NULL, &opts));
cl_assert(p != NULL);
- cl_assert_equal_i(GIT_DELTA_ADDED, git_patch_delta(p)->status);
+ cl_assert_equal_i(GIT_DELTA_ADDED, git_patch_get_delta(p)->status);
cl_assert_equal_i(1, (int)git_patch_num_hunks(p));
cl_assert_equal_i(1, git_patch_num_lines_in_hunk(p, 0));
git_patch_free(p);
cl_git_pass(git_patch_from_blob_and_buffer(
&p, a, NULL, NULL, 0, NULL, &opts));
cl_assert(p != NULL);
- cl_assert_equal_i(GIT_DELTA_DELETED, git_patch_delta(p)->status);
+ cl_assert_equal_i(GIT_DELTA_DELETED, git_patch_get_delta(p)->status);
cl_assert_equal_i(1, (int)git_patch_num_hunks(p));
cl_assert_equal_i(1, git_patch_num_lines_in_hunk(p, 0));
git_patch_free(p);
cl_git_pass(git_patch_from_blob_and_buffer(
&p, a, NULL, NULL, 0, NULL, &opts));
cl_assert(p != NULL);
- cl_assert_equal_i(GIT_DELTA_ADDED, git_patch_delta(p)->status);
+ cl_assert_equal_i(GIT_DELTA_ADDED, git_patch_get_delta(p)->status);
cl_assert_equal_i(1, (int)git_patch_num_hunks(p));
cl_assert_equal_i(1, git_patch_num_lines_in_hunk(p, 0));
git_patch_free(p);
const git_diff_delta *delta;
size_t h, num_h;
- cl_git_pass(git_patch_from_diff(&patch, &delta, diff, d));
- cl_assert(delta);
+ cl_git_pass(git_patch_from_diff(&patch, diff, d));
+ cl_assert((delta = git_patch_get_delta(patch)) != NULL);
/* call file_cb for this file */
if (file_cb != NULL && file_cb(delta, (float)d / num_d, data) != 0) {
void diff_print(FILE *fp, git_diff *diff)
{
- cl_git_pass(git_diff_print_patch(diff, diff_print_cb, fp ? fp : stderr));
+ cl_git_pass(git_diff_print(
+ diff, GIT_DIFF_FORMAT_PATCH, diff_print_cb, fp ? fp : stderr));
}
void diff_print_raw(FILE *fp, git_diff *diff)
{
- cl_git_pass(git_diff_print_raw(diff, diff_print_cb, fp ? fp : stderr));
+ cl_git_pass(git_diff_print(
+ diff, GIT_DIFF_FORMAT_RAW, diff_print_cb, fp ? fp : stderr));
}
num_d = git_diff_num_deltas(diff);
for (d = 0; d < num_d; ++d) {
- const git_diff_delta *delta;
- cl_git_pass(git_patch_from_diff(NULL, &delta, diff, d));
+ const git_diff_delta *delta = git_diff_get_delta(diff, d);
+ cl_assert(delta != NULL);
}
+ cl_assert(!git_diff_get_delta(diff, num_d));
+
git_diff_free(diff);
}
num_d = git_diff_num_deltas(diff);
for (d = 0; d < num_d; ++d) {
- const git_diff_delta *delta;
- cl_git_pass(git_patch_from_diff(NULL, &delta, diff, d));
+ const git_diff_delta *delta = git_diff_get_delta(diff, d);
cl_assert(delta != NULL);
diff_file_cb(delta, (float)d / (float)num_d, &exp);
cl_assert_equal_i(8, (int)num_d);
for (d = 0; d < num_d; ++d) {
- const git_diff_delta *delta;
- cl_git_pass(git_patch_from_diff(NULL, &delta, diff, d));
+ const git_diff_delta *delta = git_diff_get_delta(diff, d);
cl_assert(delta != NULL);
count++;
}
for (d = 0; d < num_d; ++d) {
git_patch *patch;
- const git_diff_delta *delta;
size_t h, num_h;
- cl_git_pass(git_patch_from_diff(&patch, &delta, diff, d));
-
- cl_assert(delta);
+ cl_git_pass(git_patch_from_diff(&patch, diff, d));
cl_assert(patch);
file_count++;
git_patch *patch;
const git_diff_delta *delta;
- cl_git_pass(git_patch_from_diff(&patch, &delta, diff, d));
- cl_assert(delta);
+ cl_git_pass(git_patch_from_diff(&patch, diff, d));
cl_assert(patch);
+ delta = git_patch_get_delta(patch);
+ cl_assert(delta);
file_count++;
hunk_count += (int)git_patch_num_hunks(patch);
git_patch *patch;
const git_diff_delta *delta;
- cl_git_pass(git_patch_from_diff(&patch, &delta, diff, d));
+ cl_git_pass(git_patch_from_diff(&patch, diff, d));
+ delta = git_patch_get_delta(patch);
file_count++;
hunk_count += (int)git_patch_num_hunks(patch);
num_d = git_diff_num_deltas(diff);
for (d = 0; d < num_d; ++d) {
git_patch *patch;
- const git_diff_delta *delta;
size_t h, num_h;
- cl_git_pass(git_patch_from_diff(&patch, &delta, diff, d));
- cl_assert(patch && delta);
+ cl_git_pass(git_patch_from_diff(&patch, diff, d));
+ cl_assert(patch);
exp.files++;
num_h = git_patch_num_hunks(patch);
patches[p] = NULL;
/* cache new patch */
- cl_git_pass(git_patch_from_diff(&patches[p], NULL, diff, d));
+ cl_git_pass(git_patch_from_diff(&patches[p], diff, d));
cl_assert(patches[p] != NULL);
/* process old patch if non-NULL */
git_patch *patch;
char *text;
- cl_git_pass(git_patch_from_diff(&patch, NULL, diff, d));
+ cl_git_pass(git_patch_from_diff(&patch, diff, d));
cl_assert(patch != NULL);
cl_git_pass(git_patch_to_str(&text, patch));
cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
- cl_git_pass(git_patch_from_diff(&patch, NULL, diff, 0));
+ cl_git_pass(git_patch_from_diff(&patch, diff, 0));
cl_git_pass(git_patch_to_str(&text, patch));
cl_assert_equal_s(expected0, text);
cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
- cl_git_pass(git_patch_from_diff(&patch, NULL, diff, 0));
+ cl_git_pass(git_patch_from_diff(&patch, diff, 0));
cl_git_pass(git_patch_to_str(&text, patch));
cl_assert_equal_s(expected1, text);
cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
- cl_git_pass(git_patch_from_diff(&patch, NULL, diff, 0));
+ cl_git_pass(git_patch_from_diff(&patch, diff, 0));
cl_git_pass(git_patch_to_str(&text, patch));
cl_assert_equal_s(expected0, text);
cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
- cl_git_pass(git_patch_from_diff(&patch, NULL, diff, 0));
+ cl_git_pass(git_patch_from_diff(&patch, diff, 0));
cl_git_pass(git_patch_to_str(&text, patch));
cl_assert_equal_s(expected1, text);
cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
- cl_git_pass(git_patch_from_diff(&patch, NULL, diff, 0));
+ cl_git_pass(git_patch_from_diff(&patch, diff, 0));
cl_git_pass(git_patch_to_str(&text, patch));
cl_assert_equal_s(expected2, text);
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, NULL));
cl_assert_equal_sz(1, git_diff_num_deltas(diff));
- cl_git_pass(git_patch_from_diff(&patch, NULL, diff, 0));
+ cl_git_pass(git_patch_from_diff(&patch, diff, 0));
cl_git_pass(git_patch_to_str(&actual, patch));
/* if chmod not supported, overwrite mode bits since anything is possible */
cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, one, another, NULL));
- cl_git_pass(git_diff_print_patch(diff, check_removal_cb, NULL));
+ cl_git_pass(git_diff_print(
+ diff, GIT_DIFF_FORMAT_PATCH, check_removal_cb, NULL));
git_diff_free(diff);
cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
- cl_git_pass(git_patch_from_diff(&patch, NULL, diff, 0));
+ cl_git_pass(git_patch_from_diff(&patch, diff, 0));
cl_git_pass(git_patch_to_str(&text, patch));
cl_git_pass(git_diff_tree_to_index(&diff, g_repo, one, NULL, &opts));
cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
- cl_git_pass(git_patch_from_diff(&patch, NULL, diff, 0));
+ cl_git_pass(git_patch_from_diff(&patch, diff, 0));
cl_git_pass(git_patch_to_str(&text, patch));
cl_assert_equal_s(expected1, text);
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
- cl_git_pass(git_patch_from_diff(&patch, NULL, diff, 0));
+ cl_git_pass(git_patch_from_diff(&patch, diff, 0));
cl_git_pass(git_patch_to_str(&text, patch));
cl_assert_equal_s(expected2, text);
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
- cl_git_pass(git_patch_from_diff(&patch, NULL, diff, 0));
+ cl_git_pass(git_patch_from_diff(&patch, diff, 0));
cl_git_pass(git_patch_to_str(&text, patch));
cl_assert_equal_s(expected3, text);
cl_git_pass(git_diff_tree_to_index(&diff, g_repo, one, NULL, &opts));
cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
- cl_git_pass(git_patch_from_diff(&patch, NULL, diff, 0));
+ cl_git_pass(git_patch_from_diff(&patch, diff, 0));
cl_git_pass(git_patch_to_str(&text, patch));
cl_assert_equal_s(expected4, text);
cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
- cl_git_pass(git_patch_from_diff(&patch, &delta, diff, 0));
+ cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+ cl_assert((delta = git_patch_get_delta(patch)) != NULL);
cl_assert_equal_i(GIT_DELTA_MODIFIED, (int)delta->status);
cl_assert_equal_i(2, (int)git_patch_num_hunks(patch));
cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
- cl_git_pass(git_patch_from_diff(&patch, &delta, diff, 0));
+ cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+ cl_assert((delta = git_patch_get_delta(patch)) != NULL);
cl_assert_equal_i(GIT_DELTA_MODIFIED, (int)delta->status);
cl_assert_equal_i(1, (int)git_patch_num_hunks(patch));
cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
- cl_git_pass(git_patch_from_diff(&patch, &delta, diff, 0));
+ cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+ cl_assert((delta = git_patch_get_delta(patch)) != NULL);
cl_assert_equal_i(GIT_DELTA_MODIFIED, (int)delta->status);
cl_assert_equal_i((int)hunks, (int)git_patch_num_hunks(patch));
cl_assert_equal_i(4, (int)git_diff_num_deltas(diff));
- cl_git_pass(git_patch_from_diff(&patch, &delta, diff, 0));
+ cl_git_pass(git_patch_from_diff(&patch, diff, 0));
+ cl_assert((delta = git_patch_get_delta(patch)) != NULL);
cl_assert_equal_i(GIT_DELTA_COPIED, (int)delta->status);
cl_git_pass(git_patch_to_str(&text, patch));
git_patch_free(patch);
- cl_git_pass(git_patch_from_diff(NULL, &delta, diff, 1));
+ cl_assert((delta = git_diff_get_delta(diff, 1)) != NULL);
cl_assert_equal_i(GIT_DELTA_UNMODIFIED, (int)delta->status);
- cl_git_pass(git_patch_from_diff(NULL, &delta, diff, 2));
+ cl_assert((delta = git_diff_get_delta(diff, 2)) != NULL);
cl_assert_equal_i(GIT_DELTA_MODIFIED, (int)delta->status);
- cl_git_pass(git_patch_from_diff(NULL, &delta, diff, 3));
+ cl_assert((delta = git_diff_get_delta(diff, 3)) != NULL);
cl_assert_equal_i(GIT_DELTA_MODIFIED, (int)delta->status);
git_diff_free(diff);
char *patch_text;
for (d = 0; d < num_d; ++d, git_patch_free(patch)) {
- cl_git_pass(git_patch_from_diff(&patch, &delta, diff, d));
+ cl_git_pass(git_patch_from_diff(&patch, diff, d));
+ cl_assert((delta = git_patch_get_delta(patch)) != NULL);
if (delta->status == GIT_DELTA_UNMODIFIED) {
cl_assert_at_line(expected[d] == NULL, file, line);
cl_git_pass(git_submodule_reload_all(g_repo));
opts.flags = GIT_DIFF_INCLUDE_UNTRACKED |
- GIT_DIFF_INCLUDE_UNTRACKED_CONTENT |
+ GIT_DIFF_SHOW_UNTRACKED_CONTENT |
GIT_DIFF_RECURSE_UNTRACKED_DIRS |
GIT_DIFF_DISABLE_PATHSPEC_MATCH;
opts.old_prefix = "a"; opts.new_prefix = "b";
git_tree_free(c);
}
+#define DIFF_OPTS(FLAGS, CTXT) \
+ {GIT_DIFF_OPTIONS_VERSION, (FLAGS), 0, {NULL,0}, NULL, NULL, (CTXT), 1}
+
void test_diff_tree__options(void)
{
/* grabbed a couple of commit oids from the history of the attr repo */
int test_ab_or_cd[] = { 0, 0, 0, 0, 1, 1, 1, 1, 1 };
git_diff_options test_options[] = {
/* a vs b tests */
- { 1, GIT_DIFF_NORMAL, 1, 1, NULL, NULL, {0} },
- { 1, GIT_DIFF_NORMAL, 3, 1, NULL, NULL, {0} },
- { 1, GIT_DIFF_REVERSE, 2, 1, NULL, NULL, {0} },
- { 1, GIT_DIFF_FORCE_TEXT, 2, 1, NULL, NULL, {0} },
+ DIFF_OPTS(GIT_DIFF_NORMAL, 1),
+ DIFF_OPTS(GIT_DIFF_NORMAL, 3),
+ DIFF_OPTS(GIT_DIFF_REVERSE, 2),
+ DIFF_OPTS(GIT_DIFF_FORCE_TEXT, 2),
/* c vs d tests */
- { 1, GIT_DIFF_NORMAL, 3, 1, NULL, NULL, {0} },
- { 1, GIT_DIFF_IGNORE_WHITESPACE, 3, 1, NULL, NULL, {0} },
- { 1, GIT_DIFF_IGNORE_WHITESPACE_CHANGE, 3, 1, NULL, NULL, {0} },
- { 1, GIT_DIFF_IGNORE_WHITESPACE_EOL, 3, 1, NULL, NULL, {0} },
- { 1, GIT_DIFF_IGNORE_WHITESPACE | GIT_DIFF_REVERSE, 1, 1, NULL, NULL, {0} },
+ DIFF_OPTS(GIT_DIFF_NORMAL, 3),
+ DIFF_OPTS(GIT_DIFF_IGNORE_WHITESPACE, 3),
+ DIFF_OPTS(GIT_DIFF_IGNORE_WHITESPACE_CHANGE, 3),
+ DIFF_OPTS(GIT_DIFF_IGNORE_WHITESPACE_EOL, 3),
+ DIFF_OPTS(GIT_DIFF_IGNORE_WHITESPACE | GIT_DIFF_REVERSE, 1),
};
/* to generate these values:
const char *a_commit = "d70d245ed97ed2aa596dd1af6536e4bfdb047b69";
const char *b_commit = "7a9e0b02e63179929fed24f0a3e0f19168114d10";
size_t d, num_d, h, num_h, l, num_l, header_len, line_len;
- const git_diff_delta *delta;
git_patch *patch;
const git_diff_hunk *range;
const char *header, *line;
num_d = git_diff_num_deltas(diff);
for (d = 0; d < num_d; ++d) {
- cl_git_pass(git_patch_from_diff(&patch, &delta, diff, d));
- cl_assert(patch && delta);
+ cl_git_pass(git_patch_from_diff(&patch, diff, d));
+ cl_assert(patch);
num_h = git_patch_num_hunks(patch);
for (h = 0; h < num_h; h++) {
git_patch_free(patch);
}
- cl_git_fail(git_patch_from_diff(&patch, &delta, diff, num_d));
+ cl_git_fail(git_patch_from_diff(&patch, diff, num_d));
cl_assert_equal_i(2, (int)num_d);
}
cl_assert_equal_i(2, (int)num_d);
for (d = 0; d < num_d; ++d) {
- cl_git_pass(git_patch_from_diff(&patch, NULL, diff, d));
+ cl_git_pass(git_patch_from_diff(&patch, diff, d));
cl_assert(patch);
num_h = git_patch_num_hunks(patch);
GIT_DIFF_INCLUDE_UNTRACKED |
GIT_DIFF_INCLUDE_IGNORED |
GIT_DIFF_RECURSE_UNTRACKED_DIRS |
- GIT_DIFF_INCLUDE_UNTRACKED_CONTENT;
+ GIT_DIFF_SHOW_UNTRACKED_CONTENT;
cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, a, &opts));
cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, tree, &opts));
cl_assert_equal_i(3, (int)git_diff_num_deltas(diff));
/* diffs are: .gitattributes, README.txt, sub/sub/.gitattributes */
- cl_git_pass(git_patch_from_diff(&patch, NULL, diff, 1));
+ cl_git_pass(git_patch_from_diff(&patch, diff, 1));
git_patch_free(patch);
git_diff_free(diff);
cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, tree, &opts));
cl_assert_equal_i(3, (int)git_diff_num_deltas(diff));
- cl_git_pass(git_patch_from_diff(&patch, NULL, diff, 1));
+ cl_git_pass(git_patch_from_diff(&patch, diff, 1));
git_patch_free(patch);
git_diff_free(diff);
/* quick version avoids directory scan */
- opts.flags = opts.flags | GIT_DIFF_FAST_UNTRACKED_DIRS;
+ opts.flags = opts.flags | GIT_DIFF_ENABLE_FAST_UNTRACKED_DIRS;
memset(&exp, 0, sizeof(exp));
exp.names = files1;
/* directory with nested non-ignored content */
- opts.flags = opts.flags & ~GIT_DIFF_FAST_UNTRACKED_DIRS;
+ opts.flags = opts.flags & ~GIT_DIFF_ENABLE_FAST_UNTRACKED_DIRS;
cl_git_mkfile("status/subdir/directory/more/notignored",
"not ignored deep under untracked\n");
"\xFF\xFE\x31\x00\x32\x00\x33\x00\x34\x00", 10, O_WRONLY|O_CREAT, 0664);
opts.flags =
- GIT_DIFF_INCLUDE_UNTRACKED | GIT_DIFF_INCLUDE_UNTRACKED_CONTENT;
+ GIT_DIFF_INCLUDE_UNTRACKED | GIT_DIFF_SHOW_UNTRACKED_CONTENT;
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
cl_assert_equal_i(1, git_diff_num_deltas(diff));
- cl_git_pass(git_patch_from_diff(NULL, &delta, diff, 0));
+ cl_assert((delta = git_diff_get_delta(diff, 0)) != NULL);
cl_assert_equal_i(GIT_DELTA_UNTRACKED, delta->status);
- cl_assert((delta->flags & GIT_DIFF_FLAG_BINARY) != 0);
+
+ /* not known at this point
+ * cl_assert((delta->flags & GIT_DIFF_FLAG_BINARY) != 0);
+ */
git_diff_free(diff);
}