]> git.proxmox.com Git - libgit2.git/blobdiff - src/diff_print.c
diff: treat binary patches with no data special
[libgit2.git] / src / diff_print.c
index 5a5a70b6fd4896bb3da0a0cce4e85432310c710b..fd1a186c12d51acd2d8c389e55a56bc3ac58719c 100644 (file)
@@ -331,11 +331,12 @@ static int diff_delta_format_with_paths(
        return git_buf_printf(out, template, oldpath, newpath);
 }
 
-int diff_delta_format_rename_header(
+int diff_delta_format_similarity_header(
        git_buf *out,
        const git_diff_delta *delta)
 {
        git_buf old_path = GIT_BUF_INIT, new_path = GIT_BUF_INIT;
+       const char *type;
        int error = 0;
 
        if (delta->similarity > 100) {
@@ -344,6 +345,13 @@ int diff_delta_format_rename_header(
                goto done;
        }
 
+       if (delta->status == GIT_DELTA_RENAMED)
+               type = "rename";
+       else if (delta->status == GIT_DELTA_COPIED)
+               type = "copy";
+       else
+               abort();
+
        if ((error = git_buf_puts(&old_path, delta->old_file.path)) < 0 ||
                (error = git_buf_puts(&new_path, delta->new_file.path)) < 0 ||
                (error = git_buf_quote(&old_path)) < 0 ||
@@ -352,11 +360,11 @@ int diff_delta_format_rename_header(
 
        git_buf_printf(out,
                "similarity index %d%%\n"
-               "rename from %s\n"
-               "rename to %s\n",
+               "%s from %s\n"
+               "%s to %s\n",
                delta->similarity,
-               old_path.ptr,
-               new_path.ptr);
+               type, old_path.ptr,
+               type, new_path.ptr);
 
        if (git_buf_oom(out))
                error = -1;
@@ -368,6 +376,22 @@ done:
        return error;
 }
 
+static bool delta_is_unchanged(const git_diff_delta *delta)
+{
+       if (git_oid_iszero(&delta->old_file.id) &&
+               git_oid_iszero(&delta->new_file.id))
+               return true;
+
+       if (delta->old_file.mode == GIT_FILEMODE_COMMIT ||
+               delta->new_file.mode == GIT_FILEMODE_COMMIT)
+               return false;
+
+       if (git_oid_equal(&delta->old_file.id, &delta->new_file.id))
+               return true;
+
+       return false;
+}
+
 int git_diff_delta__format_file_header(
        git_buf *out,
        const git_diff_delta *delta,
@@ -376,7 +400,7 @@ int git_diff_delta__format_file_header(
        int id_strlen)
 {
        git_buf old_path = GIT_BUF_INIT, new_path = GIT_BUF_INIT;
-       bool unchanged;
+       bool unchanged = delta_is_unchanged(delta);
        int error = 0;
 
        if (!oldpfx)
@@ -397,14 +421,12 @@ int git_diff_delta__format_file_header(
        git_buf_printf(out, "diff --git %s %s\n",
                old_path.ptr, new_path.ptr);
 
-       if (delta->status == GIT_DELTA_RENAMED) {
-               if ((error = diff_delta_format_rename_header(out, delta)) < 0)
+       if (delta->status == GIT_DELTA_RENAMED ||
+               (delta->status == GIT_DELTA_COPIED && unchanged)) {
+               if ((error = diff_delta_format_similarity_header(out, delta)) < 0)
                        goto done;
        }
 
-       unchanged = (git_oid_iszero(&delta->old_file.id) &&
-               git_oid_iszero(&delta->new_file.id));
-
        if (!unchanged) {
                if ((error = diff_print_oid_range(out, delta, id_strlen)) < 0)
                        goto done;
@@ -478,7 +500,6 @@ static int diff_print_patch_file_binary_noshow(
                        &new_path, new_pfx, delta->new_file.path)) < 0)
                goto done;
 
-
        pi->line.num_lines = 1;
        error = diff_delta_format_with_paths(
                pi->buf, delta, "Binary files %s and %s differ\n",
@@ -499,13 +520,13 @@ static int diff_print_patch_file_binary(
        size_t pre_binary_size;
        int error;
 
-       if ((pi->flags & GIT_DIFF_SHOW_BINARY) == 0)
+       if (delta->status == GIT_DELTA_UNMODIFIED)
+               return 0;
+
+       if ((pi->flags & GIT_DIFF_SHOW_BINARY) == 0 || !binary->contains_data)
                return diff_print_patch_file_binary_noshow(
                        pi, delta, old_pfx, new_pfx);
 
-       if (binary->new_file.datalen == 0 && binary->old_file.datalen == 0)
-               return 0;
-
        pre_binary_size = pi->buf->size;
        git_buf_printf(pi->buf, "GIT binary patch\n");
        pi->line.num_lines++;
@@ -541,8 +562,11 @@ static int diff_print_patch_file(
        bool binary = (delta->flags & GIT_DIFF_FLAG_BINARY) ||
                (pi->flags & GIT_DIFF_FORCE_BINARY);
        bool show_binary = !!(pi->flags & GIT_DIFF_SHOW_BINARY);
-       int id_strlen = binary && show_binary ?
-               GIT_OID_HEXSZ : pi->id_strlen;
+       int id_strlen = pi->id_strlen;
+
+       if (binary && show_binary)
+               id_strlen = delta->old_file.id_abbrev ? delta->old_file.id_abbrev :
+                       delta->new_file.id_abbrev;
 
        GIT_UNUSED(progress);