commit - 697f44709c2931bab95cbbd208e73eb6fedcad5b
commit + 474b4f942340d76684764aab281f8f7efe1878b8
blob - 8ba8533eb28083cb75d8d29edc5f337c09d90382
blob + 78322cda13b90607e928a01b05c45a36e047d1c0
--- include/got_diff.h
+++ include/got_diff.h
const struct got_error *got_diff_blob(struct got_blob_object *,
struct got_blob_object *, const char *, const char *, FILE *);
+const struct got_error *got_diff_tree(struct got_tree_object *,
+ struct got_tree_object *, struct got_repository *);
blob - 0032f4298784982750880c425502ebe5c44bef82
blob + 5588ba08c282477959c088fffb7b1b90d1e71945
--- lib/diff.c
+++ lib/diff.c
const struct got_error *
got_diff_blob(struct got_blob_object *blob1, struct got_blob_object *blob2,
- const char *label1, const char *label2 ,FILE *outfile)
+ const char *label1, const char *label2, FILE *outfile)
{
struct got_diff_state ds;
struct got_diff_args args;
free(n2);
return err;
}
+
+static const struct got_error *
+match_entry_by_name(struct got_tree_entry **te, struct got_tree_entry *te1,
+ struct got_tree_object *tree2)
+{
+ *te = NULL;
+ return NULL;
+}
+
+static int
+same_id(struct got_object_id *id1, struct got_object_id *id2)
+{
+ return (memcmp(id1->sha1, id2->sha1, SHA1_DIGEST_LENGTH) == 0);
+}
+
+static const struct got_error *
+diff_added_blob(struct got_object_id *id)
+{
+ return NULL;
+}
+
+static const struct got_error *
+diff_modified_blob(struct got_object_id *id1, struct got_object_id *id2)
+{
+ return NULL;
+}
+
+static const struct got_error *
+diff_deleted_blob(struct got_object_id *id)
+{
+ return NULL;
+}
+
+static const struct got_error *
+diff_added_tree(struct got_object_id *id)
+{
+ return NULL;
+}
+
+static const struct got_error *
+diff_modified_tree(struct got_object_id *id1, struct got_object_id *id2)
+{
+ return NULL;
+}
+
+static const struct got_error *
+diff_deleted_tree(struct got_object_id *id)
+{
+ return NULL;
+}
+
+static const struct got_error *
+diff_kind_mismatch(struct got_object_id *id1, struct got_object_id *id2)
+{
+ return NULL;
+}
+
+static const struct got_error *
+diff_entry_old_new(struct got_tree_entry *te1, struct got_tree_object *tree2)
+{
+ const struct got_error *err;
+ struct got_tree_entry *te2;
+
+ err = match_entry_by_name(&te2, te1, tree2);
+ if (err)
+ return err;
+ if (te2 == NULL) {
+ if (S_ISDIR(te1->mode))
+ return diff_deleted_tree(&te1->id);
+ return diff_deleted_blob(&te1->id);
+ }
+
+ if (S_ISDIR(te1->mode) == S_ISDIR(te2->mode)) {
+ if (!same_id(&te1->id, &te2->id))
+ return diff_modified_tree(&te1->id, &te2->id);
+ } else if (S_ISREG(te1->mode) == S_ISREG(te2->mode)) {
+ if (!same_id(&te1->id, &te2->id))
+ return diff_modified_blob(&te1->id, &te2->id);
+ } else
+ return diff_kind_mismatch(&te1->id, &te2->id);
+
+ return NULL;
+}
+
+static const struct got_error *
+diff_entry_new_old(struct got_tree_entry *te2, struct got_tree_object *tree1)
+{
+ const struct got_error *err;
+ struct got_tree_entry *te1;
+
+ err = match_entry_by_name(&te1, te2, tree1);
+ if (err)
+ return err;
+ if (te1 != NULL) /* handled by diff_entry_old_new() */
+ return NULL;
+
+ if (S_ISDIR(te2->mode))
+ return diff_added_tree(&te2->id);
+ return diff_added_blob(&te2->id);
+}
+
+const struct got_error *
+got_diff_tree(struct got_tree_object *tree1, struct got_tree_object *tree2,
+ struct got_repository *repo)
+{
+ const struct got_error *err = NULL;
+ struct got_tree_entry *te1;
+ struct got_tree_entry *te2;
+
+ if (tree1->nentries == 0 && tree2->nentries == 0)
+ return NULL;
+
+ te1 = SIMPLEQ_FIRST(&tree1->entries);
+ te2 = SIMPLEQ_FIRST(&tree2->entries);
+
+ do {
+ if (te1) {
+ err = diff_entry_old_new(te1, tree2);
+ if (err)
+ break;
+ }
+
+ if (te2) {
+ err = diff_entry_new_old(te2, tree1);
+ if (err)
+ break;
+ }
+
+ if (te1)
+ te1 = SIMPLEQ_NEXT(te1, entry);
+ if (te2)
+ te2 = SIMPLEQ_NEXT(te2, entry);
+ } while (te1 || te2);
+
+ return err;
+}