commit 0b5cc0d6bd15581b0ff9e234d342f193c9947e0a from: Stefan Sperling date: Thu May 09 19:36:10 2019 UTC more work on getting parent trees of commitables written commit - ed1754272216c57ee4359f0fc8d35279b9dfa381 commit + 0b5cc0d6bd15581b0ff9e234d342f193c9947e0a blob - 145be2b118c094240660fd62e2ca8fac4c428269 blob + b9e80b6b8b3840af153935f792463bd4507b225a --- lib/worktree.c +++ lib/worktree.c @@ -2238,7 +2238,7 @@ collect_commitables(void *arg, unsigned char status, c if (status != GOT_STATUS_MODIFY && status != GOT_STATUS_ADD && status != GOT_STATUS_DELETE) return NULL; - + err = got_path_dirname(&parent_path, path); if (err) goto done; @@ -2279,14 +2279,15 @@ write_tree(struct got_object_id *base_tree_id, void *d { 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_pathlist_head new_entries; + struct got_tree_entries new_tree_entries; struct got_tree_object *base_tree = NULL; struct got_tree_entry *te; struct got_pathlist_entry *pe; + struct got_object_id *new_tree_id = NULL; - new_entries.nentries = 0; - SIMPLEQ_INIT(&new_entries.head); + TAILQ_INIT(&new_entries); err = got_object_open_as_tree(&base_tree, a->repo, base_tree_id); if (err) @@ -2295,26 +2296,84 @@ write_tree(struct got_object_id *base_tree_id, void *d 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) { + struct commitable *ct = NULL; + struct got_tree_entry *new_te = NULL; + struct got_pathlist_entry *new_pe = NULL; + char *ct_name = NULL; - 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 (got_object_id_cmp(ct->tree_id, te->id) != 0) + continue; /* not part of this tree */ + + ct_name = basename(pe->path); + if (ct_name == NULL) { + err = got_error_from_errno(); + goto done; + } + /* Commitable and tree entry must correspond. */ + if (strcmp(te->name, ct_name) != 0) + continue; + + if (ct->status == GOT_STATUS_DELETE) { + /* Deleted entries disappear. */ + continue; + } + + /* Modified entries get updated mode and ID. */ + if (ct->status == GOT_STATUS_MODIFY) { + err = got_object_tree_entry_dup(&new_te, te); + if (err) + goto done; + new_te->mode = GOT_DEFAULT_FILE_MODE; /* XXX */ + free(new_te->id); + } else if (ct->status == GOT_STATUS_ADD) { + /* Added entries get... well, added. */ + new_te = calloc(1, sizeof(*new_te)); + if (new_te == NULL) { + err = got_error_from_errno(); + goto done; + } + new_te->mode = GOT_DEFAULT_FILE_MODE; /* XXX */ + new_te->name = strdup(ct_name); + if (new_te->name == NULL) { + err = got_error_from_errno(); + goto done; + } + } + new_te->id = got_object_id_dup(ct->id); + if (new_te->id == NULL) { + err = got_error_from_errno(); + goto done; + } + + err = got_pathlist_insert(&new_pe, &new_entries, + te->name, new_te); if (err) goto done; + if (new_pe == NULL) { + err = got_error(GOT_ERR_TREE_DUP_ENTRY); + goto done; + } } } + + new_tree_entries.nentries = 0; + SIMPLEQ_INIT(&new_tree_entries.head); + TAILQ_FOREACH(pe, &new_entries, entry) { + struct got_tree_entry *te = pe->data; + new_tree_entries.nentries++; + SIMPLEQ_INSERT_TAIL(&new_tree_entries.head, te, entry); + } + + err = got_object_tree_create(&new_tree_id, &new_tree_entries, a->repo); done: - got_object_tree_close(base_tree); - if (err) - got_object_tree_entries_close(&new_entries); + free(new_tree_id); + if (base_tree) + got_object_tree_close(base_tree); + got_pathlist_free(&new_entries); + got_object_tree_entries_close(&new_tree_entries); return err; }