summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTorsten Bögershausen <tboegi@web.de>2016-04-29 17:02:06 +0200
committerJunio C Hamano <gitster@pobox.com>2016-04-29 11:18:40 -0700
commit75f4a99f7e244e75774841ec83c37c0aa2d3c989 (patch)
treec7e91638cea5e2b093424793813d64da0a2fc3fd
parenta533b706ec2d2e14fba0b320b8b75ee441db604e (diff)
downloadgit-tb/convert-eol-autocrlf.tar.gz
ce_compare_data() did not respect conversiontb/convert-eol-autocrlf
We define the working tree file is clean if either: * the result of running convert_to_git() on the working tree contents matches what is in the index (because that would mean doing another "git add" on the path is a no-op); OR * the result of running convert_to_working_tree() on the content in the index matches what is in the working tree (because that would mean doing another "git checkout -f" on the path is a no-op). Add an extra check in ce_compare_data() in read_cache.c. Helped-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Torsten Bögershausen <tboegi@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--read-cache.c61
-rwxr-xr-xt/t6038-merge-text-auto.sh14
2 files changed, 68 insertions, 7 deletions
diff --git a/read-cache.c b/read-cache.c
index a3ef967411..48c4b31312 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -156,17 +156,78 @@ void fill_stat_cache_info(struct cache_entry *ce, struct stat *st)
ce_mark_uptodate(ce);
}
+/*
+ * Compare the data in buf with the data in the file pointed by fd and
+ * return 0 if they are identical, and non-zero if they differ.
+ */
+static int compare_with_fd(const char *input, ssize_t len, int fd)
+{
+ for (;;) {
+ char buf[1024 * 16];
+ ssize_t chunk_len, read_len;
+
+ chunk_len = sizeof(buf) < len ? sizeof(buf) : len;
+ read_len = xread(fd, buf, chunk_len ? chunk_len : 1);
+
+ if (!read_len)
+ /* EOF on the working tree file */
+ return !len ? 0 : -1;
+
+ if (!len)
+ /* we expected there is nothing left */
+ return -1;
+
+ if (memcmp(buf, input, read_len))
+ return -1;
+ input += read_len;
+ len -= read_len;
+ }
+}
+
static int ce_compare_data(const struct cache_entry *ce, struct stat *st)
{
int match = -1;
int fd = open(ce->name, O_RDONLY);
+ /*
+ * Would another "git add" on the path change what is in the
+ * index for the path?
+ */
if (fd >= 0) {
unsigned char sha1[20];
if (!index_fd(sha1, fd, st, OBJ_BLOB, ce->name, 0))
match = hashcmp(sha1, ce->sha1);
/* index_fd() closed the file descriptor already */
}
+ if (!match)
+ return match;
+
+ /*
+ * Would another "git checkout -f" out of the index change
+ * what is in the working tree file?
+ */
+ fd = open(ce->name, O_RDONLY);
+ if (fd >= 0) {
+ enum object_type type;
+ unsigned long size_long;
+ void *data = read_sha1_file(ce->sha1, &type, &size_long);
+
+ if (type == OBJ_BLOB) {
+ struct strbuf worktree = STRBUF_INIT;
+ if (convert_to_working_tree(ce->name, data,
+ size_long,
+ &worktree)) {
+ size_t size;
+ free(data);
+ data = strbuf_detach(&worktree, &size);
+ size_long = size;
+ }
+ if (!compare_with_fd(data, size_long, fd))
+ match = 0;
+ }
+ free(data);
+ close(fd);
+ }
return match;
}
diff --git a/t/t6038-merge-text-auto.sh b/t/t6038-merge-text-auto.sh
index 0108eaded8..565daf395c 100755
--- a/t/t6038-merge-text-auto.sh
+++ b/t/t6038-merge-text-auto.sh
@@ -108,9 +108,9 @@ test_expect_success 'Merge addition of text=auto' '
test_expect_success 'Detect CRLF/LF conflict after setting text=auto' '
echo "<<<<<<<" >expected &&
- echo first line | append_cr >>expected &&
- echo same line | append_cr >>expected &&
- echo ======= | append_cr >>expected &&
+ echo first line >>expected &&
+ echo same line >>expected &&
+ echo ======= >>expected &&
echo first line | append_cr >>expected &&
echo same line | append_cr >>expected &&
echo ">>>>>>>" >>expected &&
@@ -121,14 +121,13 @@ test_expect_success 'Detect CRLF/LF conflict after setting text=auto' '
fuzz_conflict file >file.fuzzy &&
compare_files expected file.fuzzy
'
-
test_expect_success 'Detect LF/CRLF conflict from addition of text=auto' '
echo "<<<<<<<" >expected &&
echo first line | append_cr >>expected &&
echo same line | append_cr >>expected &&
- echo ======= | append_cr >>expected &&
- echo first line | append_cr >>expected &&
- echo same line | append_cr >>expected &&
+ echo ======= >>expected &&
+ echo first line >>expected &&
+ echo same line >>expected &&
echo ">>>>>>>" >>expected &&
git config merge.renormalize false &&
rm -f .gitattributes &&
@@ -138,6 +137,7 @@ test_expect_success 'Detect LF/CRLF conflict from addition of text=auto' '
compare_files expected file.fuzzy
'
+
test_expect_failure 'checkout -m after setting text=auto' '
cat <<-\EOF >expected &&
first line