summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@microsoft.com>2015-03-31 16:29:35 -0400
committerEdward Thomson <ethomson@edwardthomson.com>2015-05-04 07:18:28 -0500
commit4beab1f8bbc29a0788ed7d5c1f6bc21741392565 (patch)
tree9108e6c355a1b0746cb6ed32a3a3bad4e42709c0
parent05f690122e9927eece61afb17c1595a136d119b2 (diff)
downloadlibgit2-4beab1f8bbc29a0788ed7d5c1f6bc21741392565.tar.gz
checkout: break case-changes into delete/add
When checking out with a case-insensitive working directory, we want to change the case of items in the working directory to reflect changes that occured in the checkout target. Diff now has an option to break case-changing renames into delete/add.
-rw-r--r--include/git2/diff.h7
-rw-r--r--src/checkout.c3
-rw-r--r--src/diff.c13
3 files changed, 21 insertions, 2 deletions
diff --git a/include/git2/diff.h b/include/git2/diff.h
index 9fcc3bb08..cac3b268a 100644
--- a/include/git2/diff.h
+++ b/include/git2/diff.h
@@ -124,6 +124,11 @@ typedef enum {
/** Use case insensitive filename comparisons */
GIT_DIFF_IGNORE_CASE = (1u << 10),
+ /** May be combined with `GIT_DIFF_IGNORE_CASE` to specify that a file
+ * that has changed case will be returned as an add/delete pair.
+ */
+ GIT_DIFF_INCLUDE_CASECHANGE = (1u << 11),
+
/** 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.
*/
@@ -220,7 +225,7 @@ typedef struct git_diff git_diff;
typedef enum {
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_ID = (1u << 2), /**< `id` value is known correct */
+ GIT_DIFF_FLAG_VALID_ID = (1u << 2), /**< `id` value is known correct */
} git_diff_flag_t;
/**
diff --git a/src/checkout.c b/src/checkout.c
index dd10732b5..a647ce0b9 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -2485,7 +2485,8 @@ int git_checkout_iterator(
GIT_DIFF_INCLUDE_IGNORED |
GIT_DIFF_INCLUDE_TYPECHANGE |
GIT_DIFF_INCLUDE_TYPECHANGE_TREES |
- GIT_DIFF_SKIP_BINARY_CHECK;
+ GIT_DIFF_SKIP_BINARY_CHECK |
+ GIT_DIFF_INCLUDE_CASECHANGE;
if (data.opts.checkout_strategy & GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH)
diff_opts.flags |= GIT_DIFF_DISABLE_PATHSPEC_MATCH;
if (data.opts.paths.count > 0)
diff --git a/src/diff.c b/src/diff.c
index 08e218cce..f7e1c8ee4 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -822,6 +822,19 @@ static int maybe_modified(
status = GIT_DELTA_UNMODIFIED;
}
+ /* If we want case changes, then break this into a delete of the old
+ * and an add of the new so that consumers can act accordingly (eg,
+ * checkout will update the case on disk.)
+ */
+ if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_IGNORE_CASE) &&
+ DIFF_FLAG_IS_SET(diff, GIT_DIFF_INCLUDE_CASECHANGE) &&
+ strcmp(oitem->path, nitem->path) != 0) {
+
+ if (!(error = diff_delta__from_one(diff, GIT_DELTA_DELETED, oitem)))
+ error = diff_delta__from_one(diff, GIT_DELTA_ADDED, nitem);
+ return error;
+ }
+
return diff_delta__from_two(
diff, status, oitem, omode, nitem, nmode,
git_oid_iszero(&noid) ? NULL : &noid, matched_pathspec);