commit 46f68b205b4ab514846c5352c6d952720b9da365 from: Stefan Sperling date: Sat Oct 19 11:06:56 2019 UTC show file mode differences when diffing trees commit - 523b8417c1fee8faa1a1732ffb036e97ae2ebb4a commit + 46f68b205b4ab514846c5352c6d952720b9da365 blob - 5423c33764d81bfc3fd2c71dc7f9ca32f22bad4a blob + 15002586c02db1d645ee8138c70c4fa191c0db37 --- got/got.c +++ got/got.c @@ -5024,7 +5024,7 @@ static const struct got_error * check_path_prefix_in_diff(void *arg, struct got_blob_object *blob1, struct got_blob_object *blob2, struct got_object_id *id1, struct got_object_id *id2, const char *path1, const char *path2, - struct got_repository *repo) + mode_t mode1, mode_t mode2, struct got_repository *repo) { struct check_path_prefix_arg *a = arg; blob - 2cbdb362bbc46817c1d3e664247b978b73e7f02c blob + d7f3479403b5d8286740e682f101b99f5f2782b4 --- include/got_diff.h +++ include/got_diff.h @@ -44,11 +44,13 @@ const struct got_error *got_diff_blob_file(struct got_ * the second blob contains content on the new side of the diff. * The set of arguments relating to either blob may be NULL to indicate * that no content is present on its respective side of the diff. + * File modes from relevant tree objects which contain the blobs may + * also be passed. These will be zero if not available. */ typedef const struct got_error *(*got_diff_blob_cb)(void *, struct got_blob_object *, struct got_blob_object *, struct got_object_id *, struct got_object_id *, - const char *, const char *, struct got_repository *); + const char *, const char *, mode_t, mode_t, struct got_repository *); /* * A pre-defined implementation of got_diff_blob_cb() which appends unidiff @@ -63,7 +65,7 @@ struct got_diff_blob_output_unidiff_arg { const struct got_error *got_diff_blob_output_unidiff(void *, struct got_blob_object *, struct got_blob_object *, struct got_object_id *, struct got_object_id *, - const char *, const char *, struct got_repository *); + const char *, const char *, mode_t, mode_t, struct got_repository *); /* * Compute the differences between two trees and invoke the provided blob - c100c664ee6266b7d278ba0176da2648da0f1053 blob + c98502c82d7d8b1ed38dfe6ab2fbf0b1fbb5d095 --- lib/diff.c +++ lib/diff.c @@ -38,8 +38,9 @@ static const struct got_error * diff_blobs(struct got_blob_object *blob1, struct got_blob_object *blob2, - const char *label1, const char *label2, int diff_context, - int ignore_whitespace, FILE *outfile, struct got_diff_changes *changes) + const char *label1, const char *label2, mode_t mode1, mode_t mode2, + int diff_context, int ignore_whitespace, FILE *outfile, + struct got_diff_changes *changes) { struct got_diff_state ds; struct got_diff_args args; @@ -110,8 +111,27 @@ diff_blobs(struct got_blob_object *blob1, struct got_b flags |= D_IGNOREBLANKS; if (outfile) { - fprintf(outfile, "blob - %s\n", idstr1); - fprintf(outfile, "blob + %s\n", idstr2); + char *modestr1 = NULL, *modestr2 = NULL; + if (mode1 && mode1 != mode2) { + if (asprintf(&modestr1, " (mode %o)", + mode1 & (S_IRWXU | S_IRWXG | S_IRWXO)) == -1) { + err = got_error_from_errno("asprintf"); + goto done; + } + } + if (mode2 && mode1 != mode2) { + if (asprintf(&modestr2, " (mode %o)", + mode2 & (S_IRWXU | S_IRWXG | S_IRWXO)) == -1) { + err = got_error_from_errno("asprintf"); + goto done; + } + } + fprintf(outfile, "blob - %s%s\n", idstr1, + modestr1 ? modestr1 : ""); + fprintf(outfile, "blob + %s%s\n", idstr2, + modestr2 ? modestr2 : ""); + free(modestr1); + free(modestr2); } err = got_diffreg(&res, f1, f2, flags, &args, &ds, outfile, changes); got_diff_state_free(&ds); @@ -127,12 +147,12 @@ const struct got_error * got_diff_blob_output_unidiff(void *arg, struct got_blob_object *blob1, struct got_blob_object *blob2, struct got_object_id *id1, struct got_object_id *id2, const char *label1, const char *label2, - struct got_repository *repo) + mode_t mode1, mode_t mode2, struct got_repository *repo) { struct got_diff_blob_output_unidiff_arg *a = arg; - return diff_blobs(blob1, blob2, label1, label2, a->diff_context, - a->ignore_whitespace, a->outfile, NULL); + return diff_blobs(blob1, blob2, label1, label2, mode1, mode2, + a->diff_context, a->ignore_whitespace, a->outfile, NULL); } const struct got_error * @@ -140,7 +160,7 @@ got_diff_blob(struct got_blob_object *blob1, struct go const char *label1, const char *label2, int diff_context, int ignore_whitespace, FILE *outfile) { - return diff_blobs(blob1, blob2, label1, label2, diff_context, + return diff_blobs(blob1, blob2, label1, label2, 0, 0, diff_context, ignore_whitespace, outfile, NULL); } @@ -255,7 +275,7 @@ got_diff_blob_lines_changed(struct got_diff_changes ** if (err) return err; - err = diff_blobs(blob1, blob2, NULL, NULL, 3, 0, NULL, *changes); + err = diff_blobs(blob1, blob2, NULL, NULL, 0, 0, 3, 0, NULL, *changes); if (err) { got_diff_free_changes(*changes); *changes = NULL; @@ -276,7 +296,7 @@ got_diff_free_changes(struct got_diff_changes *changes } static const struct got_error * -diff_added_blob(struct got_object_id *id, const char *label, +diff_added_blob(struct got_object_id *id, const char *label, mode_t mode, struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg) { const struct got_error *err; @@ -290,7 +310,7 @@ diff_added_blob(struct got_object_id *id, const char * err = got_object_blob_open(&blob, repo, obj, 8192); if (err) goto done; - err = cb(cb_arg, NULL, blob, NULL, id, NULL, label, repo); + err = cb(cb_arg, NULL, blob, NULL, id, NULL, label, 0, mode, repo); done: got_object_close(obj); if (blob) @@ -300,8 +320,8 @@ done: static const struct got_error * diff_modified_blob(struct got_object_id *id1, struct got_object_id *id2, - const char *label1, const char *label2, struct got_repository *repo, - got_diff_blob_cb cb, void *cb_arg) + const char *label1, const char *label2, mode_t mode1, mode_t mode2, + struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg) { const struct got_error *err; struct got_object *obj1 = NULL; @@ -333,7 +353,8 @@ diff_modified_blob(struct got_object_id *id1, struct g if (err) goto done; - err = cb(cb_arg, blob1, blob2, id1, id2, label1, label2, repo); + err = cb(cb_arg, blob1, blob2, id1, id2, label1, label2, mode1, mode2, + repo); done: if (obj1) got_object_close(obj1); @@ -347,7 +368,7 @@ done: } static const struct got_error * -diff_deleted_blob(struct got_object_id *id, const char *label, +diff_deleted_blob(struct got_object_id *id, const char *label, mode_t mode, struct got_repository *repo, got_diff_blob_cb cb, void *cb_arg) { const struct got_error *err; @@ -361,7 +382,7 @@ diff_deleted_blob(struct got_object_id *id, const char err = got_object_blob_open(&blob, repo, obj, 8192); if (err) goto done; - err = cb(cb_arg, blob, NULL, id, NULL, label, NULL, repo); + err = cb(cb_arg, blob, NULL, id, NULL, label, NULL, mode, 0, repo); done: got_object_close(obj); if (blob) @@ -512,11 +533,11 @@ diff_entry_old_new(const struct got_tree_entry *te1, cb, cb_arg, diff_content); else { if (diff_content) - err = diff_deleted_blob(te1->id, label1, repo, - cb, cb_arg); + err = diff_deleted_blob(te1->id, label1, + te1->mode, repo, cb, cb_arg); else err = cb(cb_arg, NULL, NULL, te1->id, NULL, - label1, NULL, repo); + label1, NULL, te1->mode, 0, repo); } return err; } else if (got_object_tree_entry_is_submodule(te2)) @@ -528,13 +549,16 @@ diff_entry_old_new(const struct got_tree_entry *te1, return diff_modified_tree(te1->id, te2->id, label1, label2, repo, cb, cb_arg, diff_content); } else if (S_ISREG(te1->mode) && S_ISREG(te2->mode)) { - if (!id_match) { + if (!id_match || + (te1->mode & S_IXUSR) != (te2->mode & S_IXUSR)) { if (diff_content) return diff_modified_blob(te1->id, te2->id, - label1, label2, repo, cb, cb_arg); + label1, label2, te1->mode, te2->mode, + repo, cb, cb_arg); else return cb(cb_arg, NULL, NULL, te1->id, - te2->id, label1, label2, repo); + te2->id, label1, label2, te1->mode, + te2->mode, repo); } } @@ -562,9 +586,11 @@ diff_entry_new_old(const struct got_tree_entry *te2, diff_content); if (diff_content) - return diff_added_blob(te2->id, label2, repo, cb, cb_arg); + return diff_added_blob(te2->id, label2, te2->mode, repo, cb, + cb_arg); - return cb(cb_arg, NULL, NULL, NULL, te2->id, NULL, label2, repo); + return cb(cb_arg, NULL, NULL, NULL, te2->id, NULL, label2, 0, + te2->mode, repo); } const struct got_error * blob - edb81fa00de43c1b50eba8f7ba30d5959593e344 blob + e289542324a5a24dba52bcccb0d657378875d631 --- lib/worktree.c +++ lib/worktree.c @@ -1986,7 +1986,7 @@ static const struct got_error * merge_file_cb(void *arg, struct got_blob_object *blob1, struct got_blob_object *blob2, struct got_object_id *id1, struct got_object_id *id2, const char *path1, const char *path2, - struct got_repository *repo) + mode_t mode1, mode_t mode2, struct got_repository *repo) { static const struct got_error *err = NULL; struct merge_file_cb_arg *a = arg; blob - 0454b55efa3ced59507448a4ccee518a3a29f74e (mode 744) blob + 31587c10a62466ca183a27d0985a8816a43d7053 (mode 755) --- regress/cmdline/diff.sh +++ regress/cmdline/diff.sh @@ -217,7 +217,8 @@ function test_diff_tag { echo "blob - /dev/null" >> $testroot/stdout.expected echo -n 'blob + ' >> $testroot/stdout.expected got tree -r $testroot/repo -i -c $commit_id2 | grep 'new$' | \ - cut -d' ' -f 1 >> $testroot/stdout.expected + cut -d' ' -f 1 | tr -d '\n' >> $testroot/stdout.expected + echo " (mode 644)" >> $testroot/stdout.expected echo '--- /dev/null' >> $testroot/stdout.expected echo '+++ new' >> $testroot/stdout.expected echo '@@ -0,0 +1 @@' >> $testroot/stdout.expected blob - 42ff36721b7a4349961e76289fca5eca64b2a559 blob + a7b1c1d2ee078473b35a60b0ba9068fdac25b9d7 --- regress/cmdline/import.sh +++ regress/cmdline/import.sh @@ -67,25 +67,25 @@ function test_import_basic { echo " " >> $testroot/stdout.expected echo "diff /dev/null $tree_id" >> $testroot/stdout.expected echo "blob - /dev/null" >> $testroot/stdout.expected - echo "blob + $id_alpha" >> $testroot/stdout.expected + echo "blob + $id_alpha (mode 644)" >> $testroot/stdout.expected echo "--- /dev/null" >> $testroot/stdout.expected echo "+++ alpha" >> $testroot/stdout.expected echo "@@ -0,0 +1 @@" >> $testroot/stdout.expected echo "+alpha" >> $testroot/stdout.expected echo "blob - /dev/null" >> $testroot/stdout.expected - echo "blob + $id_beta" >> $testroot/stdout.expected + echo "blob + $id_beta (mode 644)" >> $testroot/stdout.expected echo "--- /dev/null" >> $testroot/stdout.expected echo "+++ beta" >> $testroot/stdout.expected echo "@@ -0,0 +1 @@" >> $testroot/stdout.expected echo "+beta" >> $testroot/stdout.expected echo "blob - /dev/null" >> $testroot/stdout.expected - echo "blob + $id_zeta" >> $testroot/stdout.expected + echo "blob + $id_zeta (mode 644)" >> $testroot/stdout.expected echo "--- /dev/null" >> $testroot/stdout.expected echo "+++ epsilon/zeta" >> $testroot/stdout.expected echo "@@ -0,0 +1 @@" >> $testroot/stdout.expected echo "+zeta" >> $testroot/stdout.expected echo "blob - /dev/null" >> $testroot/stdout.expected - echo "blob + $id_delta" >> $testroot/stdout.expected + echo "blob + $id_delta (mode 644)" >> $testroot/stdout.expected echo "--- /dev/null" >> $testroot/stdout.expected echo "+++ gamma/delta" >> $testroot/stdout.expected echo "@@ -0,0 +1 @@" >> $testroot/stdout.expected blob - c847136cca4bae60bd72b654eb15593e7739fc09 blob + ba1b5eaaf04bac104befb9a8defef1522ad1de37 --- regress/cmdline/stage.sh +++ regress/cmdline/stage.sh @@ -1359,8 +1359,9 @@ function test_stage_commit { echo '+modified file' >> $testroot/stdout.expected echo -n 'blob - ' >> $testroot/stdout.expected got tree -r $testroot/repo -i -c $first_commit \ - | grep 'beta$' | cut -d' ' -f 1 \ + | grep 'beta$' | cut -d' ' -f 1 | tr -d '\n' \ >> $testroot/stdout.expected + echo " (mode 644)" >> $testroot/stdout.expected echo 'blob + /dev/null' >> $testroot/stdout.expected echo '--- beta' >> $testroot/stdout.expected echo '+++ /dev/null' >> $testroot/stdout.expected @@ -1368,7 +1369,8 @@ function test_stage_commit { echo '-beta' >> $testroot/stdout.expected echo 'blob - /dev/null' >> $testroot/stdout.expected echo -n 'blob + ' >> $testroot/stdout.expected - cat $testroot/blob_id_foo >> $testroot/stdout.expected + cat $testroot/blob_id_foo | tr -d '\n' >> $testroot/stdout.expected + echo " (mode 644)" >> $testroot/stdout.expected echo '--- /dev/null' >> $testroot/stdout.expected echo '+++ foo' >> $testroot/stdout.expected echo '@@ -0,0 +1 @@' >> $testroot/stdout.expected