{"thread":{"id":"481","subject":"[PATCH] Prepare diff side for upcoming symlink work.","startedAt":"2005-05-05T00:00:40Z","lastAt":"2005-05-05T00:00:40Z","messageCount":1,"participants":["Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"2601","messageId":"7vd5s6mthz.fsf@assigned-by-dhcp.cox.net","threadId":"481","inReplyTo":null,"subject":"[PATCH] Prepare diff side for upcoming symlink work.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-05-05T00:00:40Z","receivedAt":"2005-05-05T00:00:40Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"This patch prepares the external diff interface engine for the\nchange to store the symbolic links in the cache, being worked on\nby Kay Sievers.\n\nThe main thing it does is when comparing with the work tree, it\nprepares the counterpart to the blob being compared by doing a\nreadlink followed by sending that result to a temporary file to\nbe diffed.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n\n--- a/diff.c\n+++ b/diff.c\n@@ -163,13 +163,35 @@ static int work_tree_matches(const char \n \tif (pos < 0)\n \t\treturn 0;\n \tce = active_cache[pos];\n-\tif ((stat(name, &st) < 0) ||\n+\tif ((lstat(name, &st) < 0) ||\n+\t    !S_ISREG(st.st_mode) ||\n \t    cache_match_stat(ce, &st) ||\n \t    memcmp(sha1, ce->sha1, 20))\n \t\treturn 0;\n \treturn 1;\n }\n \n+static void prep_temp_blob(struct diff_tempfile *temp,\n+\t\t\t   void *blob,\n+\t\t\t   unsigned long size,\n+\t\t\t   unsigned char *sha1,\n+\t\t\t   int mode)\n+{\n+\tint fd;\n+\n+\tstrcpy(temp->tmp_path, \".diff_XXXXXX\");\n+\tfd = mkstemp(temp->tmp_path);\n+\tif (fd < 0)\n+\t\tdie(\"unable to create temp-file\");\n+\tif (write(fd, blob, size) != size)\n+\t\tdie(\"unable to write temp-file\");\n+\tclose(fd);\n+\ttemp->name = temp->tmp_path;\n+\tstrcpy(temp->hex, sha1_to_hex(sha1));\n+\ttemp->hex[40] = 0;\n+\tsprintf(temp->mode, \"%06o\", mode);\n+}\n+\n static void prepare_temp_file(const char *name,\n \t\t\t      struct diff_tempfile *temp,\n \t\t\t      struct diff_spec *one)\n@@ -196,20 +218,35 @@ static void prepare_temp_file(const char\n \tif (!one->sha1_valid || use_work_tree) {\n \t\tstruct stat st;\n \t\ttemp->name = name;\n-\t\tif (stat(temp->name, &st) < 0) {\n+\t\tif (lstat(temp->name, &st) < 0) {\n \t\t\tif (errno == ENOENT)\n \t\t\t\tgoto not_a_valid_file;\n \t\t\tdie(\"stat(%s): %s\", temp->name, strerror(errno));\n \t\t}\n+\t\tif (S_ISLNK(st.st_mode)) {\n+\t\t\tint ret;\n+\t\t\tchar *buf, buf_[1024];\n+\t\t\tbuf = ((sizeof(buf_) < st.st_size) ?\n+\t\t\t       xmalloc(st.st_size) : buf_);\n+\t\t\tret = readlink(name, buf, st.st_size);\n+\t\t\tif (ret < 0)\n+\t\t\t\tdie(\"readlink(%s)\", name);\n+\t\t\tprep_temp_blob(temp, buf, st.st_size,\n+\t\t\t\t       (one->sha1_valid ?\n+\t\t\t\t\tone->blob_sha1 : null_sha1),\n+\t\t\t\t       (one->sha1_valid ?\n+\t\t\t\t\tone->mode : \n+\t\t\t\t\tS_IFREG|ce_permissions(st.st_mode)));\n+\t\t}\n \t\tif (!one->sha1_valid)\n \t\t\tstrcpy(temp->hex, sha1_to_hex(null_sha1));\n \t\telse\n \t\t\tstrcpy(temp->hex, sha1_to_hex(one->blob_sha1));\n \t\tsprintf(temp->mode, \"%06o\",\n-\t\t\tS_IFREG |ce_permissions(st.st_mode));\n+\t\t\tS_IFREG | ce_permissions(st.st_mode));\n+\t\treturn;\n \t}\n \telse {\n-\t\tint fd;\n \t\tvoid *blob;\n \t\tchar type[20];\n \t\tunsigned long size;\n@@ -218,19 +255,8 @@ static void prepare_temp_file(const char\n \t\tif (!blob || strcmp(type, \"blob\"))\n \t\t\tdie(\"unable to read blob object for %s (%s)\",\n \t\t\t    name, sha1_to_hex(one->blob_sha1));\n-\n-\t\tstrcpy(temp->tmp_path, \".diff_XXXXXX\");\n-\t\tfd = mkstemp(temp->tmp_path);\n-\t\tif (fd < 0)\n-\t\t\tdie(\"unable to create temp-file\");\n-\t\tif (write(fd, blob, size) != size)\n-\t\t\tdie(\"unable to write temp-file\");\n-\t\tclose(fd);\n+\t\tprep_temp_blob(temp, blob, size, one->blob_sha1, one->mode);\n \t\tfree(blob);\n-\t\ttemp->name = temp->tmp_path;\n-\t\tstrcpy(temp->hex, sha1_to_hex(one->blob_sha1));\n-\t\ttemp->hex[40] = 0;\n-\t\tsprintf(temp->mode, \"%06o\", one->mode);\n \t}\n }\n \n\n"}]}