Browse Source

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>
maint
Junio C Hamano 18 years ago
parent
commit
6716027108
  1. 34
      builtin-apply.c
  2. 19
      t/t0020-crlf.sh

34
builtin-apply.c

@ -1393,28 +1393,39 @@ static void show_stats(struct patch *patch) @@ -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 * @@ -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 @@ -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) @@ -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;

19
t/t0020-crlf.sh

@ -180,11 +180,8 @@ test_expect_success 'apply patch (autocrlf=true)' ' @@ -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)' ' @@ -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

Loading…
Cancel
Save