commit ed1754272216c57ee4359f0fc8d35279b9dfa381 from: Stefan Sperling date: Thu May 09 19:36:10 2019 UTC more progress on generating new tree entries commit - 24519714f578ad52690f1c7fd400a2e91655e685 commit + ed1754272216c57ee4359f0fc8d35279b9dfa381 blob - f0d9f81873ca7c0897120083789fce73b1b37638 blob + a69c3177ceaac290e56335f2ae5a77a248750f9a --- lib/got_lib_object.h +++ lib/got_lib_object.h @@ -108,3 +108,5 @@ const struct got_error *got_object_blob_open(struct go char *got_object_blob_id_str(struct got_blob_object*, char *, size_t); const struct got_error *got_object_tag_open(struct got_tag_object **, struct got_repository *, struct got_object *); +const struct got_error *got_object_tree_entry_dup(struct got_tree_entry **, + struct got_tree_entry *); blob - 488140ca0bcbd4ebafc5dbb6d1676e4d938567ca blob + cc4f1837befaa2cccdec42ad171967f789314e22 --- lib/got_lib_object_parse.h +++ lib/got_lib_object_parse.h @@ -27,6 +27,7 @@ const struct got_error *got_object_parse_tag(struct go const struct got_error *got_read_file_to_mem(uint8_t **, size_t *, FILE *); void got_object_tree_entry_close(struct got_tree_entry *); +void got_object_tree_entries_close(struct got_tree_entries *); struct got_pack; struct got_packidx; blob - 96343bed081edc52541ab337665a7d2e1ba37286 blob + d111b34e06b915085e9da4644248bb97c9b3973d --- lib/object.c +++ lib/object.c @@ -1538,3 +1538,32 @@ done: got_object_tree_close(tree2); return err; } + +const struct got_error * +got_object_tree_entry_dup(struct got_tree_entry **new_te, + struct got_tree_entry *te) +{ + const struct got_error *err = NULL; + + *new_te = calloc(1, sizeof(**new_te)); + if (*new_te == NULL) + return got_error_from_errno(); + + (*new_te)->mode = te->mode; + (*new_te)->name = strdup(te->name); + if ((*new_te)->name == NULL) { + err = got_error_from_errno(); + got_object_tree_entry_close(*new_te); + return err; + } + + (*new_te)->id = got_object_id_dup(te->id); + if ((*new_te)->id == NULL) { + err = got_error_from_errno(); + got_object_tree_entry_close(*new_te); + return err; + } + + return NULL; +} + blob - 0fe7cbd09118fad59fdb3a386a21b4f6883aefd7 blob + 2f081c6a67da579464a6d640538662e44fa480d9 --- lib/object_parse.c +++ lib/object_parse.c @@ -555,22 +555,27 @@ got_object_tree_entry_close(struct got_tree_entry *te) } void -got_object_tree_close(struct got_tree_object *tree) +got_object_tree_entries_close(struct got_tree_entries *entries) { struct got_tree_entry *te; + while (!SIMPLEQ_EMPTY(&entries->head)) { + te = SIMPLEQ_FIRST(&entries->head); + SIMPLEQ_REMOVE_HEAD(&entries->head, entry); + got_object_tree_entry_close(te); + } +} + +void +got_object_tree_close(struct got_tree_object *tree) +{ if (tree->refcnt > 0) { tree->refcnt--; if (tree->refcnt > 0) return; } - while (!SIMPLEQ_EMPTY(&tree->entries.head)) { - te = SIMPLEQ_FIRST(&tree->entries.head); - SIMPLEQ_REMOVE_HEAD(&tree->entries.head, entry); - got_object_tree_entry_close(te); - } - + got_object_tree_entries_close(&tree->entries); free(tree); } blob - f2a2c29ccaac5ac5f2b9488dd1f097338fa541a4 blob + 145be2b118c094240660fd62e2ca8fac4c428269 --- lib/worktree.c +++ lib/worktree.c @@ -48,6 +48,7 @@ #include "got_lib_inflate.h" #include "got_lib_delta.h" #include "got_lib_object.h" +#include "got_lib_object_parse.h" #include "got_lib_object_create.h" #include "got_lib_object_idset.h" #include "got_lib_diff.h" @@ -2199,7 +2200,7 @@ done: return err; } -struct committable { +struct commitable { char *path; unsigned char status; struct got_object_id *id; @@ -2207,7 +2208,7 @@ struct committable { }; static void -free_committable(struct committable *ct) +free_commitable(struct commitable *ct) { free(ct->path); free(ct->id); @@ -2215,19 +2216,19 @@ free_committable(struct committable *ct) free(ct); } -struct collect_committables_arg { +struct collect_commitables_arg { struct got_pathlist_head *paths; struct got_repository *repo; struct got_worktree *worktree; }; static const struct got_error * -collect_committables(void *arg, unsigned char status, const char *path, +collect_commitables(void *arg, unsigned char status, const char *path, struct got_object_id *id) { - struct collect_committables_arg *a = arg; + struct collect_commitables_arg *a = arg; const struct got_error *err = NULL; - struct committable *ct = NULL; + struct commitable *ct = NULL; struct got_pathlist_entry *new = NULL; char *parent_path = NULL; @@ -2262,18 +2263,69 @@ collect_committables(void *arg, unsigned char status, err = got_pathlist_insert(&new, a->paths, ct->path, ct); done: if (err || new == NULL) - free_committable(ct); + free_commitable(ct); free(parent_path); return err; } +struct write_tree_arg { + struct got_pathlist_head *commitable_paths; + struct got_object_idset *affected_trees; + struct got_repository *repo; +}; + +static const struct got_error * +write_tree(struct got_object_id *base_tree_id, void *data, void *arg) +{ + const struct got_error *err = NULL; + struct write_tree_arg *a = arg; + struct got_tree_entries new_entries; + const struct got_tree_entries *base_entries = NULL; + struct got_tree_object *base_tree = NULL; + struct got_tree_entry *te; + struct got_pathlist_entry *pe; + + new_entries.nentries = 0; + SIMPLEQ_INIT(&new_entries.head); + + err = got_object_open_as_tree(&base_tree, a->repo, base_tree_id); + if (err) + return err; + + base_entries = got_object_tree_get_entries(base_tree); + + SIMPLEQ_FOREACH(te, &base_entries->head, entry) { + struct commitable *ct = NULL; + struct got_tree_entry *new_te; + + TAILQ_FOREACH(pe, a->commitable_paths, entry) { + ct = pe->data; + if (got_object_id_cmp(ct->tree_id, te->id) == 0) + break; + } + + if (ct) { + } else { + err = got_object_tree_entry_dup(&new_te, te); + if (err) + goto done; + } + } +done: + got_object_tree_close(base_tree); + if (err) + got_object_tree_entries_close(&new_entries); + return err; +} + const struct got_error * got_worktree_commit(struct got_object_id **new_commit_id, struct got_worktree *worktree, const char *ondisk_path, const char *logmsg, struct got_repository *repo) { const struct got_error *err = NULL, *unlockerr = NULL; - struct collect_committables_arg cc_arg; + struct collect_commitables_arg cc_arg; + struct write_tree_arg wt_arg; struct got_pathlist_head paths; struct got_pathlist_entry *pe; char *relpath = NULL; @@ -2304,15 +2356,27 @@ got_worktree_commit(struct got_object_id **new_commit_ cc_arg.worktree = worktree; cc_arg.repo = repo; err = got_worktree_status(worktree, relpath ? relpath : "", - repo, collect_committables, &cc_arg, NULL, NULL); + repo, collect_commitables, &cc_arg, NULL, NULL); if (err) goto done; /* TODO: collect commit message if not specified */ + /* Collect IDs of affected leaf trees. */ + TAILQ_FOREACH(pe, &paths, entry) { + struct commitable *ct = pe->data; + + if (got_object_idset_contains(tree_ids, ct->tree_id)) + continue; + + err = got_object_idset_add(tree_ids, ct->tree_id, NULL); + if (err) + goto done; + } + /* Create blobs from added and modified files and record their IDs. */ TAILQ_FOREACH(pe, &paths, entry) { - struct committable *ct = pe->data; + struct commitable *ct = pe->data; char *ondisk_path; if (ct->status != GOT_STATUS_ADD && @@ -2330,21 +2394,18 @@ got_worktree_commit(struct got_object_id **new_commit_ goto done; } - /* Collect IDs of affected leaf trees. */ - TAILQ_FOREACH(pe, &paths, entry) { - struct committable *ct = pe->data; - - if (got_object_idset_contains(tree_ids, ct->tree_id)) - continue; - - err = got_object_idset_add(tree_ids, ct->tree_id, NULL); - if (err) - goto done; + /* Write new leaf tree objects. */ + wt_arg.commitable_paths = &paths; + wt_arg.affected_trees = got_object_idset_alloc(); + if (wt_arg.affected_trees == NULL) { + err = got_error_from_errno(); + goto done; } + wt_arg.repo = repo; + err = got_object_idset_for_each(tree_ids, write_tree, &wt_arg); + if (err) + goto done; - /* Write new leaf tree objects. */ - /* err = got_object_idset_for_each(tree_ids, write_tree, &wt_arg); */ - err = got_object_open_as_commit(&base_commit, repo, worktree->base_commit_id); if (err) @@ -2358,8 +2419,8 @@ done: if (unlockerr && err == NULL) err = unlockerr; TAILQ_FOREACH(pe, &paths, entry) { - struct committable *ct = pe->data; - free_committable(ct); + struct commitable *ct = pe->data; + free_commitable(ct); } got_object_idset_free(tree_ids); got_pathlist_free(&paths);