sha1_file.c: cleanup hdr usage
[gitweb.git] / combine-diff.c
index a5f2c8dd4a414e513d0421f9a499d06c73ecaf5a..044633d1643a533498d3f5aba86a35a4611f6ca7 100644 (file)
@@ -678,11 +678,27 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
        else {
                /* Used by diff-tree to read from the working tree */
                struct stat st;
-               int fd;
-               if (0 <= (fd = open(elem->path, O_RDONLY)) &&
-                   !fstat(fd, &st)) {
-                       int len = st.st_size;
-                       int sz = 0;
+               int fd = -1;
+
+               if (lstat(elem->path, &st) < 0)
+                       goto deleted_file;
+
+               if (S_ISLNK(st.st_mode)) {
+                       size_t len = st.st_size;
+                       result_size = len;
+                       result = xmalloc(len + 1);
+                       if (result_size != readlink(elem->path, result, len)) {
+                               error("readlink(%s): %s", elem->path,
+                                     strerror(errno));
+                               return;
+                       }
+                       result[len] = 0;
+                       elem->mode = canon_mode(st.st_mode);
+               }
+               else if (0 <= (fd = open(elem->path, O_RDONLY)) &&
+                        !fstat(fd, &st)) {
+                       size_t len = st.st_size;
+                       size_t sz = 0;
 
                        elem->mode = canon_mode(st.st_mode);
                        result_size = len;
@@ -698,11 +714,12 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
                        result[len] = 0;
                }
                else {
-                       /* deleted file */
+               deleted_file:
                        result_size = 0;
                        elem->mode = 0;
                        result = xcalloc(1, 1);
                }
+
                if (0 <= fd)
                        close(fd);
        }