commit - df3352425b599a7ca9e473a9024c6b5333778dc5
commit + 0cb83759ff5e9ca28c397bb04edb8e0629eba4bd
blob - f4f431a41a6b1d33399a3974a26880899d231b80
blob + 9963b821c1f57a0322e8913d88df883c8de53679
--- include/got_worktree.h
+++ include/got_worktree.h
/* Get the path to this work tree's histedit script file. */
const struct got_error *got_worktree_get_histedit_script_path(char **,
struct got_worktree *);
+
+/* Stage the specified paths for commit. */
+const struct got_error *got_worktree_stage_paths(struct got_worktree *,
+ struct got_pathlist_head *, struct got_repository *,
+ got_worktree_status_cb, void *,
+ got_worktree_cancel_cb , void *);
blob - 61af730e3e3e103061ccd973a5695d28529aff30
blob + dbf735c60f305ce21773733986a5a067e065d008
--- lib/fileindex.c
+++ lib/fileindex.c
}
uint32_t
-got_fileindex_entry_stage(const struct got_fileindex_entry *ie)
+got_fileindex_entry_stage_get(const struct got_fileindex_entry *ie)
{
return ((ie->flags & GOT_FILEIDX_F_STAGE) >> GOT_FILEIDX_F_STAGE_SHIFT);
+}
+
+void
+got_fileindex_entry_stage_set(struct got_fileindex_entry *ie, uint32_t stage)
+{
+ ie->flags &= ~GOT_FILEIDX_F_STAGE;
+ ie->flags |= ((stage << GOT_FILEIDX_F_STAGE_SHIFT) &
+ GOT_FILEIDX_F_STAGE);
}
int
if (err)
return err;
- stage = got_fileindex_entry_stage(ie);
+ stage = got_fileindex_entry_stage_get(ie);
if (stage == GOT_FILEIDX_STAGE_MODIFY ||
stage == GOT_FILEIDX_STAGE_ADD) {
SHA1Update(ctx, ie->staged_blob_sha1, SHA1_DIGEST_LENGTH);
goto done;
if (version >= 2) {
- uint32_t stage = got_fileindex_entry_stage(ie);
+ uint32_t stage = got_fileindex_entry_stage_get(ie);
if (stage == GOT_FILEIDX_STAGE_MODIFY ||
stage == GOT_FILEIDX_STAGE_ADD) {
n = fread(ie->staged_blob_sha1, 1, SHA1_DIGEST_LENGTH,
blob - 33b7f142cf74b87064731e83d2bfd65101294ff3
blob + 83e6be7d83308583c41892a51e5aa6a7f5bac56c
--- lib/got_lib_fileindex.h
+++ lib/got_lib_fileindex.h
int got_fileindex_entry_has_blob(struct got_fileindex_entry *);
int got_fileindex_entry_has_commit(struct got_fileindex_entry *);
int got_fileindex_entry_has_file_on_disk(struct got_fileindex_entry *);
+uint32_t got_fileindex_entry_stage_get(const struct got_fileindex_entry *);
+void got_fileindex_entry_stage_set(struct got_fileindex_entry *ie, uint32_t);
void got_fileindex_entry_mark_deleted_from_disk(struct got_fileindex_entry *);
blob - a64b0f8a733115f6aa705ad8e394e407b54590f8
blob + e2d15ef7a6c7d7222b3bcc4ffe515453b008c1f9
--- lib/worktree.c
+++ lib/worktree.c
err = delete_ref(commit_ref_name, repo);
done:
free(commit_ref_name);
+ return err;
+}
+
+static const struct got_error *
+stage_path(const char *path, size_t path_len, struct got_worktree *worktree,
+ struct got_fileindex *fileindex, struct got_repository *repo,
+ got_worktree_status_cb status_cb, void *status_arg)
+{
+ const struct got_error *err = NULL;
+ char *ondisk_path;
+ struct got_fileindex_entry *ie;
+ unsigned char status;
+ struct stat sb;
+ struct got_object_id *blob_id = NULL;
+ uint32_t stage;
+
+ if (asprintf(&ondisk_path, "%s/%s", worktree->root_path, path) == -1)
+ return got_error_from_errno("asprintf");
+
+ ie = got_fileindex_entry_get(fileindex, path, path_len);
+ if (ie == NULL) {
+ err = got_error_path(path, GOT_ERR_FILE_STATUS);
+ goto done;
+ }
+
+ err = get_file_status(&status, &sb, ie, ondisk_path, repo);
+ if (err)
+ goto done;
+
+ switch (status) {
+ case GOT_STATUS_ADD:
+ case GOT_STATUS_MODIFY:
+ err = got_object_blob_create(&blob_id, ondisk_path,
+ repo);
+ if (err)
+ goto done;
+ memcpy(ie->staged_blob_sha1, blob_id->sha1,
+ SHA1_DIGEST_LENGTH);
+ if (status == GOT_STATUS_ADD)
+ stage = GOT_FILEIDX_STAGE_ADD;
+ else
+ stage = GOT_FILEIDX_STAGE_MODIFY;
+ break;
+ case GOT_STATUS_DELETE:
+ stage = GOT_FILEIDX_STAGE_DELETE;
+ break;
+ default:
+ err = got_error_path(path, GOT_ERR_FILE_STATUS);
+ goto done;
+ }
+
+ got_fileindex_entry_stage_set(ie, stage);
+
+ /* XXX TODO pass 'staged' status separately */
+ err = (*status_cb)(status_arg, status, path, blob_id, NULL);
+done:
+ free(blob_id);
+ free(ondisk_path);
return err;
}
+
+const struct got_error *
+got_worktree_stage_paths(struct got_worktree *worktree,
+ struct got_pathlist_head *paths, struct got_repository *repo,
+ got_worktree_status_cb status_cb, void *status_arg,
+ got_worktree_cancel_cb cancel_cb, void *cancel_arg)
+{
+ const struct got_error *err = NULL, *sync_err, *unlockerr;
+ struct got_pathlist_entry *pe;
+ struct got_fileindex *fileindex = NULL;
+ char *fileindex_path = NULL;
+
+ err = lock_worktree(worktree, LOCK_EX);
+ if (err)
+ return err;
+
+ err = open_fileindex(&fileindex, &fileindex_path, worktree);
+ if (err)
+ goto done;
+
+ TAILQ_FOREACH(pe, paths, entry) {
+ if (cancel_cb) {
+ err = (*cancel_cb)(cancel_arg);
+ if (err)
+ break;
+ }
+ err = stage_path(pe->path, pe->path_len, worktree, fileindex,
+ repo, status_cb, status_arg);
+ if (err)
+ break;
+ }
+
+ sync_err = sync_fileindex(fileindex, fileindex_path);
+ if (sync_err && err == NULL)
+ err = sync_err;
+done:
+ free(fileindex_path);
+ if (fileindex)
+ got_fileindex_free(fileindex);
+ unlockerr = lock_worktree(worktree, LOCK_SH);
+ if (unlockerr && err == NULL)
+ err = unlockerr;
+ return err;
+}