- default:
- return -1;
- }
-
- /* This is for '*' entries */
- while ((ch = *cp) && ('0' <= ch && ch <= '7'))
- cp++; /* skip mode bits */
- if (strncmp(cp, "->", 2))
- return -1;
- cp += 2;
- while ((ch = *cp) && ('0' <= ch && ch <= '7'))
- cp++; /* skip mode bits */
- if (strncmp(cp, "\tblob\t", 6))
- return -1;
- cp += 6;
- if (get_sha1_hex(cp, old_sha1))
- return -1;
- cp += 40;
- if (strncmp(cp, "->", 2))
- return -1;
- cp += 2;
- if (get_sha1_hex(cp, new_sha1))
- return -1;
- cp += 40;
- if (*cp++ != '\t')
- return -1;
- strcpy(path, cp);
- *old_status = (memcmp(old_sha1, null_sha, sizeof(null_sha)) ?
- STATUS_CACHED : STATUS_UNCACHED);
- *new_status = (memcmp(new_sha1, null_sha, sizeof(null_sha)) ?
- STATUS_CACHED : STATUS_UNCACHED);
- return 0;
-}
-
-static int sha1err(const char *path, const unsigned char *sha1)
-{
- return error("diff-tree-helper: unable to read sha1 file of %s (%s)",
- path, sha1_to_hex(sha1));
-}
-
-static int fserr(const char *path)
-{
- return error("diff-tree-helper: unable to read file %s", path);
-}
-
-static char *map_whole_file(const char *path, unsigned long *size) {
- int fd;
- struct stat st;
- void *buf;
-
- if ((fd = open(path, O_RDONLY)) < 0) {
- error("diff-tree-helper: unable to read file %s", path);
- return 0;
- }
- if (fstat(fd, &st) < 0) {
- close(fd);
- error("diff-tree-helper: unable to stat file %s", path);
- return 0;
- }
- *size = st.st_size;
- buf = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
- close(fd);
- return buf;
-}
-
-static int show_diff(const unsigned char *old_sha1, int old_status,
- const unsigned char *new_sha1, int new_status,
- const char *path, int reverse_diff)
-{
- char other[PATH_MAX];
- unsigned long size;
- char type[20];
- int fd;
- int reverse;
- void *blob = 0;
- const char *fs = 0;
- int need_unmap = 0;
- int need_unlink = 0;
-
-
- switch (old_status) {
- case STATUS_CACHED:
- blob = read_sha1_file(old_sha1, type, &size);
- if (! blob)
- return sha1err(path, old_sha1);
-
- switch (new_status) {
- case STATUS_CACHED:
- strcpy(other, ".diff_tree_helper_XXXXXX");
- fd = mkstemp(other);
- if (fd < 0)
- die("unable to create temp-file");
- if (write(fd, blob, size) != size)
- die("unable to write temp-file");
- close(fd);
- free(blob);
-
- blob = read_sha1_file(new_sha1, type, &size);
- if (! blob)
- return sha1err(path, new_sha1);
-
- need_unlink = 1;
- /* new = blob, old = fs */
- reverse = !reverse_diff;
- fs = other;
- break;
-
- case STATUS_ABSENT:
- case STATUS_UNCACHED:
- fs = ((new_status == STATUS_ABSENT) ?
- "/dev/null" : path);
- reverse = reverse_diff;
- break;
-
- default:
- reverse = reverse_diff;
- }