commit - 24519714f578ad52690f1c7fd400a2e91655e685
commit + ed1754272216c57ee4359f0fc8d35279b9dfa381
blob - f0d9f81873ca7c0897120083789fce73b1b37638
blob + a69c3177ceaac290e56335f2ae5a77a248750f9a
--- lib/got_lib_object.h
+++ lib/got_lib_object.h
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
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
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
}
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
#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"
return err;
}
-struct committable {
+struct commitable {
char *path;
unsigned char status;
struct got_object_id *id;
};
static void
-free_committable(struct committable *ct)
+free_commitable(struct commitable *ct)
{
free(ct->path);
free(ct->id);
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;
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;
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 &&
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)
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);