commit - 85220b0e5b67f98aad2ec495f80d6c31f7abfc81
commit + c71da4f733c5d4c5d25de860ff717363522a105b
blob - 94933804bb4a90e421828948d134ea779bfd8861
blob + 1c02d96fb4e9d928b1d57ab019a1c00492bf4331
--- got/got.c
+++ got/got.c
}
static const struct got_error *
+patch_progress(void *arg, const char *old, const char *new, unsigned char mode)
+{
+ const char *path = new == NULL ? old : new;
+
+ while (*path == '/')
+ path++;
+ printf("%c %s\n", mode, path);
+ return NULL;
+}
+
+static const struct got_error *
cmd_patch(int argc, char *argv[])
{
const struct got_error *error = NULL, *close_error = NULL;
err(1, "pledge");
#endif
- error = got_patch(patchfd, worktree, repo, nop, &print_remove_status,
- NULL, &add_progress, NULL, check_cancelled, NULL);
+ error = got_patch(patchfd, worktree, repo, nop, &patch_progress,
+ NULL, check_cancelled, NULL);
done:
if (repo) {
blob - 5f28ffc619f1b4e32ba37ff8e5361c636009ba74
blob + 391c0cf0a69178e759d03ba7c752062f5752dfc6
--- include/got_patch.h
+++ include/got_patch.h
*/
/*
+ * A callback that gets invoked during the patch application.
+ *
+ * Receives the old and new path and a status code.
+ */
+typedef const struct got_error *(*got_patch_progress_cb)(void *,
+ const char *, const char *, unsigned char);
+
+/*
* Apply the (already opened) patch to the repository and register the
* status of the added and removed files.
*
*/
const struct got_error *
got_patch(int, struct got_worktree *, struct got_repository *, int,
- got_worktree_delete_cb, void *, got_worktree_checkout_cb, void *,
- got_cancel_cb, void *);
+ got_patch_progress_cb, void *, got_cancel_cb, void *);
blob - ea8b97c6a17bb7946eb5f67b37c2aefd994bf7cc
blob + d906c8c59ea5881a8801313236bdb6bc6966eac3
--- lib/patch.c
+++ lib/patch.c
};
struct got_patch {
- int nop;
char *old;
char *new;
STAILQ_HEAD(, got_patch_hunk) head;
+};
+
+struct patch_args {
+ got_patch_progress_cb progress_cb;
+ void *progress_arg;
};
static const struct got_error *
}
static const struct got_error *
-patch_file(struct got_patch *p, const char *path, FILE *tmp)
+patch_file(struct got_patch *p, const char *path, FILE *tmp, int nop)
{
const struct got_error *err = NULL;
struct got_patch_hunk *h;
h = STAILQ_FIRST(&p->head);
if (h == NULL || STAILQ_NEXT(h, entries) != NULL)
return got_error(GOT_ERR_PATCH_MALFORMED);
- if (p->nop)
+ if (nop)
return NULL;
for (i = 0; i < h->len; ++i) {
if (fprintf(tmp, "%s", h->lines[i]+1) < 0)
err = locate_hunk(orig, h, &pos, &lineno);
if (err != NULL)
goto done;
- if (!p->nop)
+ if (!nop)
err = copy(tmp, orig, copypos, pos);
if (err != NULL)
goto done;
if (err != NULL)
goto done;
- if (!p->nop)
+ if (!nop)
err = apply_hunk(tmp, h, &lineno);
if (err != NULL)
goto done;
err = got_error_from_errno("fstat");
else if (sb.st_size != copypos)
err = got_error(GOT_ERR_PATCH_DONT_APPLY);
- } else if (!p->nop && !feof(orig))
+ } else if (!nop && !feof(orig))
err = copy(tmp, orig, copypos, -1);
done:
}
static const struct got_error *
+patch_delete(void *arg, unsigned char status, unsigned char staged_status,
+ const char *path)
+{
+ struct patch_args *pa = arg;
+
+ return pa->progress_cb(pa->progress_arg, path, NULL, status);
+}
+
+static const struct got_error *
+patch_add(void *arg, unsigned char status, const char *path)
+{
+ struct patch_args *pa = arg;
+
+ return pa->progress_cb(pa->progress_arg, NULL, path, status);
+}
+
+static const struct got_error *
apply_patch(struct got_worktree *worktree, struct got_repository *repo,
- struct got_patch *p, got_worktree_delete_cb delete_cb, void *delete_arg,
- got_worktree_checkout_cb add_cb, void *add_arg, got_cancel_cb cancel_cb,
- void *cancel_arg)
+ struct got_patch *p, int nop, struct patch_args *pa,
+ got_cancel_cb cancel_cb, void *cancel_arg)
{
const struct got_error *err = NULL;
struct got_pathlist_head oldpaths, newpaths;
goto done;
}
- if (!p->nop)
+ if (!nop)
err = got_opentemp_named(&tmppath, &tmp, template);
if (err)
goto done;
- err = patch_file(p, oldpath, tmp);
+ err = patch_file(p, oldpath, tmp, nop);
if (err)
goto done;
- if (p->nop)
+ if (nop)
goto done;
if (p->old != NULL && p->new == NULL) {
err = got_worktree_schedule_delete(worktree, &oldpaths,
- 0, NULL, delete_cb, delete_arg, repo, 0, 0);
+ 0, NULL, patch_delete, pa, repo, 0, 0);
goto done;
}
if (file_renamed) {
err = got_worktree_schedule_delete(worktree, &oldpaths,
- 0, NULL, delete_cb, delete_arg, repo, 0, 0);
+ 0, NULL, patch_delete, pa, repo, 0, 0);
if (err == NULL)
err = got_worktree_schedule_add(worktree, &newpaths,
- add_cb, add_arg, repo, 1);
+ patch_add, pa, repo, 1);
} else if (p->old == NULL)
err = got_worktree_schedule_add(worktree, &newpaths,
- add_cb, add_arg, repo, 1);
+ patch_add, pa, repo, 1);
else
- printf("M %s\n", oldpath); /* XXX */
+ err = pa->progress_cb(pa->progress_arg, oldpath, newpath,
+ GOT_STATUS_MODIFY);
done:
if (err != NULL && newpath != NULL && (file_renamed || p->old == NULL))
const struct got_error *
got_patch(int fd, struct got_worktree *worktree, struct got_repository *repo,
- int nop, got_worktree_delete_cb delete_cb, void *delete_arg,
- got_worktree_checkout_cb add_cb, void *add_arg, got_cancel_cb cancel_cb,
- void *cancel_arg)
+ int nop, got_patch_progress_cb progress_cb, void *progress_arg,
+ got_cancel_cb cancel_cb, void *cancel_arg)
{
const struct got_error *err = NULL;
+ struct patch_args pa;
struct imsgbuf *ibuf;
int imsg_fds[2] = {-1, -1};
int done = 0;
pid_t pid;
+ pa.progress_cb = progress_cb;
+ pa.progress_arg = progress_arg;
+
ibuf = calloc(1, sizeof(*ibuf));
if (ibuf == NULL) {
err = got_error_from_errno("calloc");
if (err || done)
break;
- p.nop = nop;
- err = apply_patch(worktree, repo, &p, delete_cb, delete_arg,
- add_cb, add_arg, cancel_cb, cancel_arg);
+ err = apply_patch(worktree, repo, &p, nop, &pa,
+ cancel_cb, cancel_arg);
patch_free(&p);
if (err)
break;