summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Junio C Hamano <junkio@cox.net>2007-02-17 12:37:25 -0800
committerLibravatar Junio C Hamano <junkio@cox.net>2007-02-17 15:27:47 -0800
commit6716027108f426c83038b05baf3f20ceefe6fbd1 (patch)
tree0bc3ccc535c35dd30c1e003a8c759f5800c62122
parentt0020: add test for auto-crlf (diff)
downloadtgif-6716027108f426c83038b05baf3f20ceefe6fbd1.tar.xz
Teach core.autocrlf to 'git apply'
This teaches git-apply that the data read from and written to the filesystem might need to get converted to adjust for local line-ending convention. Signed-off-by: Junio C Hamano <junkio@cox.net>
-rw-r--r--builtin-apply.c34
-rwxr-xr-xt/t0020-crlf.sh19
2 files changed, 43 insertions, 10 deletions
diff --git a/builtin-apply.c b/builtin-apply.c
index 3fefdacd94..45c4acbd20 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -1393,28 +1393,39 @@ static void show_stats(struct patch *patch)
free(qname);
}
-static int read_old_data(struct stat *st, const char *path, void *buf, unsigned long size)
+static int read_old_data(struct stat *st, const char *path, char **buf_p, unsigned long *alloc_p, unsigned long *size_p)
{
int fd;
unsigned long got;
+ unsigned long nsize;
+ char *nbuf;
+ unsigned long size = *size_p;
+ char *buf = *buf_p;
switch (st->st_mode & S_IFMT) {
case S_IFLNK:
- return readlink(path, buf, size);
+ return readlink(path, buf, size) != size;
case S_IFREG:
fd = open(path, O_RDONLY);
if (fd < 0)
return error("unable to open %s", path);
got = 0;
for (;;) {
- int ret = xread(fd, (char *) buf + got, size - got);
+ int ret = xread(fd, buf + got, size - got);
if (ret <= 0)
break;
got += ret;
}
close(fd);
- return got;
-
+ nsize = got;
+ nbuf = buf;
+ if (convert_to_git(path, &nbuf, &nsize)) {
+ free(buf);
+ *buf_p = nbuf;
+ *alloc_p = nsize;
+ *size_p = nsize;
+ }
+ return got != size;
default:
return -1;
}
@@ -1910,7 +1921,7 @@ static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *
size = st->st_size;
alloc = size + 8192;
buf = xmalloc(alloc);
- if (read_old_data(st, patch->old_name, buf, alloc) != size)
+ if (read_old_data(st, patch->old_name, &buf, &alloc, &size))
return error("read of %s failed", patch->old_name);
}
@@ -2282,12 +2293,22 @@ static void add_index_file(const char *path, unsigned mode, void *buf, unsigned
static int try_create_file(const char *path, unsigned int mode, const char *buf, unsigned long size)
{
int fd;
+ char *nbuf;
+ unsigned long nsize;
if (S_ISLNK(mode))
/* Although buf:size is counted string, it also is NUL
* terminated.
*/
return symlink(buf, path);
+ nsize = size;
+ nbuf = (char *) buf;
+ if (convert_to_working_tree(path, &nbuf, &nsize)) {
+ free((char *) buf);
+ buf = nbuf;
+ size = nsize;
+ }
+
fd = open(path, O_CREAT | O_EXCL | O_WRONLY, (mode & 0100) ? 0777 : 0666);
if (fd < 0)
return -1;
@@ -2598,6 +2619,7 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
const char *whitespace_option = NULL;
+
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
char *end;
diff --git a/t/t0020-crlf.sh b/t/t0020-crlf.sh
index 58a4d86df3..723b29ad17 100755
--- a/t/t0020-crlf.sh
+++ b/t/t0020-crlf.sh
@@ -180,11 +180,8 @@ test_expect_success 'apply patch (autocrlf=true)' '
git repo-config core.autocrlf true &&
git read-tree --reset -u HEAD &&
- # Sore thumb
- remove_cr one >tmp && mv -f tmp one &&
-
git apply patch.file &&
- test "$patched" = "`git hash-object --stdin <one`" || {
+ test "$patched" = "`remove_cr one | git hash-object --stdin`" || {
echo "Eh? apply without index"
false
}
@@ -203,4 +200,18 @@ test_expect_success 'apply patch --cached (autocrlf=true)' '
}
'
+test_expect_success 'apply patch --index (autocrlf=true)' '
+
+ rm -f tmp one dir/two &&
+ git repo-config core.autocrlf true &&
+ git read-tree --reset -u HEAD &&
+
+ git apply --index patch.file &&
+ test "$patched" = `git rev-parse :one` &&
+ test "$patched" = "`remove_cr one | git hash-object --stdin`" || {
+ echo "Eh? apply with --index"
+ false
+ }
+'
+
test_done