commit - 523b8417c1fee8faa1a1732ffb036e97ae2ebb4a
commit + 46f68b205b4ab514846c5352c6d952720b9da365
blob - 5423c33764d81bfc3fd2c71dc7f9ca32f22bad4a
blob + 15002586c02db1d645ee8138c70c4fa191c0db37
--- got/got.c
+++ got/got.c
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
* 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
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
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;
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);
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 *
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);
}
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;
}
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;
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)
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;
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);
}
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;
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)
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))
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);
}
}
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
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
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
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
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
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