// --numstat does numeric diffstat, and doesn't actually apply
// --index-info shows the old and new index info for paths if available.
//
+static const char *prefix;
+static int prefix_length = -1;
+
+static int p_value = 1;
static int allow_binary_replacement = 0;
static int check_index = 0;
static int write_index = 0;
static int show_index_info = 0;
static int line_termination = '\n';
static const char apply_usage[] =
-"git-apply [--stat] [--numstat] [--summary] [--check] [--index] [--apply] [--no-add] [--index-info] [--allow-binary-replacement] [-z] <patch>...";
+"git-apply [--stat] [--numstat] [--summary] [--check] [--index] [--apply] [--no-add] [--index-info] [--allow-binary-replacement] [-z] [-pNUM] <patch>...";
/*
* For "diff-stat" like behaviour, we keep track of the biggest change
buffer = xrealloc(buffer, alloc);
nr = alloc - size;
}
- nr = read(fd, buffer + size, nr);
+ nr = xread(fd, buffer + size, nr);
if (!nr)
break;
- if (nr < 0) {
- if (errno == EAGAIN)
- continue;
+ if (nr < 0)
die("git-apply: read returned %s", strerror(errno));
- }
size += nr;
}
*sizep = size;
*/
static void parse_traditional_patch(const char *first, const char *second, struct patch *patch)
{
- int p_value = 1;
char *name;
first += 4; // skip "--- "
return error("unable to open %s", path);
got = 0;
for (;;) {
- int ret = read(fd, buf + got, size - got);
- if (ret < 0) {
- if (errno == EAGAIN)
- continue;
- break;
- }
- if (!ret)
+ int ret = xread(fd, buf + got, size - got);
+ if (ret <= 0)
break;
got += ret;
}
return -1;
}
- changed = ce_match_stat(active_cache[pos], &st);
+ changed = ce_match_stat(active_cache[pos], &st, 1);
if (changed)
return error("%s: does not match index",
old_name);
die("unable to add cache entry for %s", path);
}
-static void create_subdirectories(const char *path)
-{
- int len = strlen(path);
- char *buf = xmalloc(len + 1);
- const char *slash = path;
-
- while ((slash = strchr(slash+1, '/')) != NULL) {
- len = slash - path;
- memcpy(buf, path, len);
- buf[len] = 0;
- if (mkdir(buf, 0777) < 0) {
- if (errno != EEXIST)
- break;
- }
- }
- free(buf);
-}
-
static int try_create_file(const char *path, unsigned int mode, const char *buf, unsigned long size)
{
int fd;
if (S_ISLNK(mode))
return symlink(buf, path);
- fd = open(path, O_CREAT | O_EXCL | O_WRONLY | O_TRUNC, (mode & 0100) ? 0777 : 0666);
+ fd = open(path, O_CREAT | O_EXCL | O_WRONLY, (mode & 0100) ? 0777 : 0666);
if (fd < 0)
return -1;
while (size) {
- int written = write(fd, buf, size);
- if (written < 0) {
- if (errno == EINTR || errno == EAGAIN)
- continue;
+ int written = xwrite(fd, buf, size);
+ if (written < 0)
die("writing file %s: %s", path, strerror(errno));
- }
if (!written)
die("out of space writing file %s", path);
buf += written;
* which is true 99% of the time anyway. If they don't,
* we create them and try again.
*/
-static void create_one_file(const char *path, unsigned mode, const char *buf, unsigned long size)
+static void create_one_file(char *path, unsigned mode, const char *buf, unsigned long size)
{
if (!try_create_file(path, mode, buf, size))
return;
if (errno == ENOENT) {
- create_subdirectories(path);
+ if (safe_create_leading_directories(path))
+ return;
if (!try_create_file(path, mode, buf, size))
return;
}
}
if (errno != EEXIST)
break;
- }
+ ++nr;
+ }
}
die("unable to write file %s mode %o", path, mode);
}
static void create_file(struct patch *patch)
{
- const char *path = patch->new_name;
+ char *path = patch->new_name;
unsigned mode = patch->new_mode;
unsigned long size = patch->resultsize;
char *buf = patch->result;
return 0;
x = x->next;
}
+ if (0 < prefix_length) {
+ int pathlen = strlen(pathname);
+ if (pathlen <= prefix_length ||
+ memcmp(prefix, pathname, prefix_length))
+ return 0;
+ }
return 1;
}
excludes = x;
continue;
}
+ if (!strncmp(arg, "-p", 2)) {
+ p_value = atoi(arg + 2);
+ continue;
+ }
if (!strcmp(arg, "--no-add")) {
no_add = 1;
continue;
line_termination = 0;
continue;
}
+
+ if (check_index && prefix_length < 0) {
+ prefix = setup_git_directory();
+ prefix_length = prefix ? strlen(prefix) : 0;
+ git_config(git_default_config);
+ }
+ if (0 < prefix_length)
+ arg = prefix_filename(prefix, prefix_length, arg);
+
fd = open(arg, O_RDONLY);
if (fd < 0)
usage(apply_usage);