2 * Copyright (c) 2018, 2019, 2020 Stefan Sperling <stsp@openbsd.org>
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 #include <sys/queue.h>
34 #include "got_compat.h"
36 #include "got_error.h"
37 #include "got_repository.h"
38 #include "got_reference.h"
39 #include "got_object.h"
41 #include "got_cancel.h"
42 #include "got_worktree.h"
43 #include "got_opentemp.h"
46 #include "got_lib_worktree.h"
47 #include "got_lib_sha1.h"
48 #include "got_lib_fileindex.h"
49 #include "got_lib_inflate.h"
50 #include "got_lib_delta.h"
51 #include "got_lib_object.h"
52 #include "got_lib_object_parse.h"
53 #include "got_lib_object_create.h"
54 #include "got_lib_object_idset.h"
55 #include "got_lib_diff.h"
56 #include "got_lib_gotconfig.h"
59 #define MIN(_a,_b) ((_a) < (_b) ? (_a) : (_b))
62 #define GOT_MERGE_LABEL_MERGED "merged change"
63 #define GOT_MERGE_LABEL_BASE "3-way merge base"
65 static const struct got_error
*
66 create_meta_file(const char *path_got
, const char *name
, const char *content
)
68 const struct got_error
*err
= NULL
;
71 if (asprintf(&path
, "%s/%s", path_got
, name
) == -1)
72 return got_error_from_errno("asprintf");
74 err
= got_path_create_file(path
, content
);
79 static const struct got_error
*
80 update_meta_file(const char *path_got
, const char *name
, const char *content
)
82 const struct got_error
*err
= NULL
;
87 if (asprintf(&path
, "%s/%s", path_got
, name
) == -1) {
88 err
= got_error_from_errno("asprintf");
93 err
= got_opentemp_named(&tmppath
, &tmpfile
, path
);
98 int len
= fprintf(tmpfile
, "%s\n", content
);
99 if (len
!= strlen(content
) + 1) {
100 err
= got_error_from_errno2("fprintf", tmppath
);
105 if (rename(tmppath
, path
) != 0) {
106 err
= got_error_from_errno3("rename", tmppath
, path
);
112 if (fclose(tmpfile
) == EOF
&& err
== NULL
)
113 err
= got_error_from_errno2("fclose", tmppath
);
118 static const struct got_error
*
119 write_head_ref(const char *path_got
, struct got_reference
*head_ref
)
121 const struct got_error
*err
= NULL
;
124 if (got_ref_is_symbolic(head_ref
)) {
125 refstr
= got_ref_to_str(head_ref
);
127 return got_error_from_errno("got_ref_to_str");
129 refstr
= strdup(got_ref_get_name(head_ref
));
131 return got_error_from_errno("strdup");
133 err
= update_meta_file(path_got
, GOT_WORKTREE_HEAD_REF
, refstr
);
138 const struct got_error
*
139 got_worktree_init(const char *path
, struct got_reference
*head_ref
,
140 const char *prefix
, struct got_repository
*repo
)
142 const struct got_error
*err
= NULL
;
143 struct got_object_id
*commit_id
= NULL
;
145 uint32_t uuid_status
;
147 char *path_got
= NULL
;
148 char *formatstr
= NULL
;
149 char *absprefix
= NULL
;
150 char *basestr
= NULL
;
151 char *uuidstr
= NULL
;
153 if (strcmp(path
, got_repo_get_path(repo
)) == 0) {
154 err
= got_error(GOT_ERR_WORKTREE_REPO
);
158 err
= got_ref_resolve(&commit_id
, repo
, head_ref
);
161 err
= got_object_get_type(&obj_type
, repo
, commit_id
);
164 if (obj_type
!= GOT_OBJ_TYPE_COMMIT
)
165 return got_error(GOT_ERR_OBJ_TYPE
);
167 if (!got_path_is_absolute(prefix
)) {
168 if (asprintf(&absprefix
, "/%s", prefix
) == -1)
169 return got_error_from_errno("asprintf");
172 /* Create top-level directory (may already exist). */
173 if (mkdir(path
, GOT_DEFAULT_DIR_MODE
) == -1 && errno
!= EEXIST
) {
174 err
= got_error_from_errno2("mkdir", path
);
178 /* Create .got directory (may already exist). */
179 if (asprintf(&path_got
, "%s/%s", path
, GOT_WORKTREE_GOT_DIR
) == -1) {
180 err
= got_error_from_errno("asprintf");
183 if (mkdir(path_got
, GOT_DEFAULT_DIR_MODE
) == -1 && errno
!= EEXIST
) {
184 err
= got_error_from_errno2("mkdir", path_got
);
188 /* Create an empty lock file. */
189 err
= create_meta_file(path_got
, GOT_WORKTREE_LOCK
, NULL
);
193 /* Create an empty file index. */
194 err
= create_meta_file(path_got
, GOT_WORKTREE_FILE_INDEX
, NULL
);
198 /* Write the HEAD reference. */
199 err
= write_head_ref(path_got
, head_ref
);
203 /* Record our base commit. */
204 err
= got_object_id_str(&basestr
, commit_id
);
207 err
= create_meta_file(path_got
, GOT_WORKTREE_BASE_COMMIT
, basestr
);
211 /* Store path to repository. */
212 err
= create_meta_file(path_got
, GOT_WORKTREE_REPOSITORY
,
213 got_repo_get_path(repo
));
217 /* Store in-repository path prefix. */
218 err
= create_meta_file(path_got
, GOT_WORKTREE_PATH_PREFIX
,
219 absprefix
? absprefix
: prefix
);
224 uuid_create(&uuid
, &uuid_status
);
225 if (uuid_status
!= uuid_s_ok
) {
226 err
= got_error_uuid(uuid_status
, "uuid_create");
229 uuid_to_string(&uuid
, &uuidstr
, &uuid_status
);
230 if (uuid_status
!= uuid_s_ok
) {
231 err
= got_error_uuid(uuid_status
, "uuid_to_string");
234 err
= create_meta_file(path_got
, GOT_WORKTREE_UUID
, uuidstr
);
238 /* Stamp work tree with format file. */
239 if (asprintf(&formatstr
, "%d", GOT_WORKTREE_FORMAT_VERSION
) == -1) {
240 err
= got_error_from_errno("asprintf");
243 err
= create_meta_file(path_got
, GOT_WORKTREE_FORMAT
, formatstr
);
257 const struct got_error
*
258 got_worktree_match_path_prefix(int *match
, struct got_worktree
*worktree
,
259 const char *path_prefix
)
261 char *absprefix
= NULL
;
263 if (!got_path_is_absolute(path_prefix
)) {
264 if (asprintf(&absprefix
, "/%s", path_prefix
) == -1)
265 return got_error_from_errno("asprintf");
267 *match
= (strcmp(absprefix
? absprefix
: path_prefix
,
268 worktree
->path_prefix
) == 0);
274 got_worktree_get_head_ref_name(struct got_worktree
*worktree
)
276 return worktree
->head_ref_name
;
279 const struct got_error
*
280 got_worktree_set_head_ref(struct got_worktree
*worktree
,
281 struct got_reference
*head_ref
)
283 const struct got_error
*err
= NULL
;
284 char *path_got
= NULL
, *head_ref_name
= NULL
;
286 if (asprintf(&path_got
, "%s/%s", worktree
->root_path
,
287 GOT_WORKTREE_GOT_DIR
) == -1) {
288 err
= got_error_from_errno("asprintf");
293 head_ref_name
= strdup(got_ref_get_name(head_ref
));
294 if (head_ref_name
== NULL
) {
295 err
= got_error_from_errno("strdup");
299 err
= write_head_ref(path_got
, head_ref
);
303 free(worktree
->head_ref_name
);
304 worktree
->head_ref_name
= head_ref_name
;
312 struct got_object_id
*
313 got_worktree_get_base_commit_id(struct got_worktree
*worktree
)
315 return worktree
->base_commit_id
;
318 const struct got_error
*
319 got_worktree_set_base_commit_id(struct got_worktree
*worktree
,
320 struct got_repository
*repo
, struct got_object_id
*commit_id
)
322 const struct got_error
*err
;
323 struct got_object
*obj
= NULL
;
325 char *path_got
= NULL
;
327 if (asprintf(&path_got
, "%s/%s", worktree
->root_path
,
328 GOT_WORKTREE_GOT_DIR
) == -1) {
329 err
= got_error_from_errno("asprintf");
334 err
= got_object_open(&obj
, repo
, commit_id
);
338 if (obj
->type
!= GOT_OBJ_TYPE_COMMIT
) {
339 err
= got_error(GOT_ERR_OBJ_TYPE
);
343 /* Record our base commit. */
344 err
= got_object_id_str(&id_str
, commit_id
);
347 err
= update_meta_file(path_got
, GOT_WORKTREE_BASE_COMMIT
, id_str
);
351 free(worktree
->base_commit_id
);
352 worktree
->base_commit_id
= got_object_id_dup(commit_id
);
353 if (worktree
->base_commit_id
== NULL
) {
354 err
= got_error_from_errno("got_object_id_dup");
359 got_object_close(obj
);
365 const struct got_gotconfig
*
366 got_worktree_get_gotconfig(struct got_worktree
*worktree
)
368 return worktree
->gotconfig
;
371 static const struct got_error
*
372 lock_worktree(struct got_worktree
*worktree
, int operation
)
374 if (flock(worktree
->lockfd
, operation
| LOCK_NB
) == -1)
375 return (errno
== EWOULDBLOCK
? got_error(GOT_ERR_WORKTREE_BUSY
)
376 : got_error_from_errno2("flock",
377 got_worktree_get_root_path(worktree
)));
381 static const struct got_error
*
382 add_dir_on_disk(struct got_worktree
*worktree
, const char *path
)
384 const struct got_error
*err
= NULL
;
387 if (asprintf(&abspath
, "%s/%s", worktree
->root_path
, path
) == -1)
388 return got_error_from_errno("asprintf");
390 err
= got_path_mkdir(abspath
);
391 if (err
&& err
->code
== GOT_ERR_ERRNO
&& errno
== EEXIST
) {
394 if (lstat(abspath
, &sb
) == -1) {
395 err
= got_error_from_errno2("lstat", abspath
);
396 } else if (!S_ISDIR(sb
.st_mode
)) {
397 /* TODO directory is obstructed; do something */
398 err
= got_error_path(abspath
, GOT_ERR_FILE_OBSTRUCTED
);
405 static const struct got_error
*
406 check_file_contents_equal(int *same
, FILE *f1
, FILE *f2
)
408 const struct got_error
*err
= NULL
;
411 size_t flen1
= 0, flen2
= 0;
416 flen1
= fread(fbuf1
, 1, sizeof(fbuf1
), f1
);
417 if (flen1
== 0 && ferror(f1
)) {
418 err
= got_error_from_errno("fread");
421 flen2
= fread(fbuf2
, 1, sizeof(fbuf2
), f2
);
422 if (flen2
== 0 && ferror(f2
)) {
423 err
= got_error_from_errno("fread");
430 } else if (flen2
== 0) {
434 } else if (flen1
== flen2
) {
435 if (memcmp(fbuf1
, fbuf2
, flen2
) != 0) {
448 static const struct got_error
*
449 check_files_equal(int *same
, FILE *f1
, FILE *f2
)
456 if (fstat(fileno(f1
), &sb
) != 0)
457 return got_error_from_errno("fstat");
460 if (fstat(fileno(f2
), &sb
) != 0)
461 return got_error_from_errno("fstat");
464 if (size1
!= size2
) {
469 if (fseek(f1
, 0L, SEEK_SET
) == -1)
470 return got_ferror(f1
, GOT_ERR_IO
);
471 if (fseek(f2
, 0L, SEEK_SET
) == -1)
472 return got_ferror(f2
, GOT_ERR_IO
);
474 return check_file_contents_equal(same
, f1
, f2
);
477 static const struct got_error
*
478 copy_file_to_fd(off_t
*outsize
, FILE *f
, int outfd
)
486 if (fseek(f
, 0L, SEEK_SET
) == -1)
487 return got_ferror(f
, GOT_ERR_IO
);
490 flen
= fread(fbuf
, 1, sizeof(fbuf
), f
);
493 return got_error_from_errno("fread");
497 outlen
= write(outfd
, fbuf
, flen
);
499 return got_error_from_errno("write");
501 return got_error(GOT_ERR_IO
);
508 static const struct got_error
*
509 merge_binary_file(int *overlapcnt
, int merged_fd
,
510 FILE *f_deriv
, FILE *f_orig
, FILE *f_deriv2
,
511 const char *label_deriv
, const char *label_orig
, const char *label_deriv2
,
512 const char *ondisk_path
)
514 const struct got_error
*err
= NULL
;
515 int same_content
, changed_deriv
, changed_deriv2
;
516 int fd_orig
= -1, fd_deriv
= -1, fd_deriv2
= -1;
517 off_t size_orig
= 0, size_deriv
= 0, size_deriv2
= 0;
518 char *path_orig
= NULL
, *path_deriv
= NULL
, *path_deriv2
= NULL
;
519 char *base_path_orig
= NULL
, *base_path_deriv
= NULL
;
520 char *base_path_deriv2
= NULL
;
524 err
= check_files_equal(&same_content
, f_deriv
, f_deriv2
);
529 return copy_file_to_fd(&size_deriv
, f_deriv
, merged_fd
);
531 err
= check_files_equal(&same_content
, f_deriv
, f_orig
);
534 changed_deriv
= !same_content
;
535 err
= check_files_equal(&same_content
, f_deriv2
, f_orig
);
538 changed_deriv2
= !same_content
;
540 if (changed_deriv
&& changed_deriv2
) {
542 if (asprintf(&base_path_orig
, "%s-orig", ondisk_path
) == -1) {
543 err
= got_error_from_errno("asprintf");
546 if (asprintf(&base_path_deriv
, "%s-1", ondisk_path
) == -1) {
547 err
= got_error_from_errno("asprintf");
550 if (asprintf(&base_path_deriv2
, "%s-2", ondisk_path
) == -1) {
551 err
= got_error_from_errno("asprintf");
554 err
= got_opentemp_named_fd(&path_orig
, &fd_orig
,
558 err
= got_opentemp_named_fd(&path_deriv
, &fd_deriv
,
562 err
= got_opentemp_named_fd(&path_deriv2
, &fd_deriv2
,
566 err
= copy_file_to_fd(&size_orig
, f_orig
, fd_orig
);
569 err
= copy_file_to_fd(&size_deriv
, f_deriv
, fd_deriv
);
572 err
= copy_file_to_fd(&size_deriv2
, f_deriv2
, fd_deriv2
);
575 if (dprintf(merged_fd
, "Binary files differ and cannot be "
576 "merged automatically:\n") < 0) {
577 err
= got_error_from_errno("dprintf");
580 if (dprintf(merged_fd
, "%s%s%s\nfile %s\n",
581 GOT_DIFF_CONFLICT_MARKER_BEGIN
,
582 label_deriv
? " " : "",
583 label_deriv
? label_deriv
: "",
585 err
= got_error_from_errno("dprintf");
589 if (dprintf(merged_fd
, "%s%s%s\nfile %s\n",
590 GOT_DIFF_CONFLICT_MARKER_ORIG
,
591 label_orig
? " " : "",
592 label_orig
? label_orig
: "",
594 err
= got_error_from_errno("dprintf");
598 if (dprintf(merged_fd
, "%s\nfile %s\n%s%s%s\n",
599 GOT_DIFF_CONFLICT_MARKER_SEP
,
601 GOT_DIFF_CONFLICT_MARKER_END
,
602 label_deriv2
? " " : "",
603 label_deriv2
? label_deriv2
: "") < 0) {
604 err
= got_error_from_errno("dprintf");
607 } else if (changed_deriv
)
608 err
= copy_file_to_fd(&size_deriv
, f_deriv
, merged_fd
);
609 else if (changed_deriv2
)
610 err
= copy_file_to_fd(&size_deriv2
, f_deriv2
, merged_fd
);
612 if (size_orig
== 0 && path_orig
&& unlink(path_orig
) == -1 &&
614 err
= got_error_from_errno2("unlink", path_orig
);
615 if (fd_orig
!= -1 && close(fd_orig
) == -1 && err
== NULL
)
616 err
= got_error_from_errno2("close", path_orig
);
617 if (fd_deriv
!= -1 && close(fd_deriv
) == -1 && err
== NULL
)
618 err
= got_error_from_errno2("close", path_deriv
);
619 if (fd_deriv2
!= -1 && close(fd_deriv2
) == -1 && err
== NULL
)
620 err
= got_error_from_errno2("close", path_deriv2
);
624 free(base_path_orig
);
625 free(base_path_deriv
);
626 free(base_path_deriv2
);
631 * Perform a 3-way merge where the file f_orig acts as the common
632 * ancestor, the file f_deriv acts as the first derived version,
633 * and the file f_deriv2 acts as the second derived version.
634 * The merge result will be written to a new file at ondisk_path; any
635 * existing file at this path will be replaced.
637 static const struct got_error
*
638 merge_file(int *local_changes_subsumed
, struct got_worktree
*worktree
,
639 FILE *f_orig
, FILE *f_deriv
, FILE *f_deriv2
, const char *ondisk_path
,
640 const char *path
, uint16_t st_mode
,
641 const char *label_orig
, const char *label_deriv
, const char *label_deriv2
,
642 enum got_diff_algorithm diff_algo
, struct got_repository
*repo
,
643 got_worktree_checkout_cb progress_cb
, void *progress_arg
)
645 const struct got_error
*err
= NULL
;
647 FILE *f_merged
= NULL
;
648 char *merged_path
= NULL
, *base_path
= NULL
;
652 *local_changes_subsumed
= 0;
654 err
= got_path_dirname(&parent
, ondisk_path
);
658 if (asprintf(&base_path
, "%s/got-merged", parent
) == -1) {
659 err
= got_error_from_errno("asprintf");
663 err
= got_opentemp_named_fd(&merged_path
, &merged_fd
, base_path
);
667 err
= got_merge_diff3(&overlapcnt
, merged_fd
, f_deriv
, f_orig
,
668 f_deriv2
, label_deriv
, label_orig
, label_deriv2
, diff_algo
);
670 if (err
->code
!= GOT_ERR_FILE_BINARY
)
672 err
= merge_binary_file(&overlapcnt
, merged_fd
, f_deriv
,
673 f_orig
, f_deriv2
, label_deriv
, label_orig
, label_deriv2
,
679 err
= (*progress_cb
)(progress_arg
,
680 overlapcnt
> 0 ? GOT_STATUS_CONFLICT
: GOT_STATUS_MERGE
, path
);
684 if (fsync(merged_fd
) != 0) {
685 err
= got_error_from_errno("fsync");
689 f_merged
= fdopen(merged_fd
, "r");
690 if (f_merged
== NULL
) {
691 err
= got_error_from_errno("fdopen");
696 /* Check if a clean merge has subsumed all local changes. */
697 if (overlapcnt
== 0) {
698 err
= check_files_equal(local_changes_subsumed
, f_deriv
,
704 if (fchmod(fileno(f_merged
), st_mode
) != 0) {
705 err
= got_error_from_errno2("fchmod", merged_path
);
709 if (rename(merged_path
, ondisk_path
) != 0) {
710 err
= got_error_from_errno3("rename", merged_path
,
719 if (merged_fd
!= -1 && close(merged_fd
) == -1 && err
== NULL
)
720 err
= got_error_from_errno("close");
721 if (f_merged
&& fclose(f_merged
) == EOF
&& err
== NULL
)
722 err
= got_error_from_errno("fclose");
729 static const struct got_error
*
730 update_symlink(const char *ondisk_path
, const char *target_path
,
733 /* This is not atomic but matches what 'ln -sf' does. */
734 if (unlink(ondisk_path
) == -1)
735 return got_error_from_errno2("unlink", ondisk_path
);
736 if (symlink(target_path
, ondisk_path
) == -1)
737 return got_error_from_errno3("symlink", target_path
,
743 * Overwrite a symlink (or a regular file in case there was a "bad" symlink)
744 * in the work tree with a file that contains conflict markers and the
745 * conflicting target paths of the original version, a "derived version"
746 * of a symlink from an incoming change, and a local version of the symlink.
748 * The original versions's target path can be NULL if it is not available,
749 * such as if both derived versions added a new symlink at the same path.
751 * The incoming derived symlink target is NULL in case the incoming change
752 * has deleted this symlink.
754 static const struct got_error
*
755 install_symlink_conflict(const char *deriv_target
,
756 struct got_object_id
*deriv_base_commit_id
, const char *orig_target
,
757 const char *label_orig
, const char *local_target
, const char *ondisk_path
)
759 const struct got_error
*err
;
760 char *id_str
= NULL
, *label_deriv
= NULL
, *path
= NULL
;
763 err
= got_object_id_str(&id_str
, deriv_base_commit_id
);
765 return got_error_from_errno("asprintf");
767 if (asprintf(&label_deriv
, "%s: commit %s",
768 GOT_MERGE_LABEL_MERGED
, id_str
) == -1) {
769 err
= got_error_from_errno("asprintf");
773 err
= got_opentemp_named(&path
, &f
, "got-symlink-conflict");
777 if (fchmod(fileno(f
), GOT_DEFAULT_FILE_MODE
) == -1) {
778 err
= got_error_from_errno2("fchmod", path
);
782 if (fprintf(f
, "%s %s\n%s\n%s%s%s%s%s\n%s\n%s\n",
783 GOT_DIFF_CONFLICT_MARKER_BEGIN
, label_deriv
,
784 deriv_target
? deriv_target
: "(symlink was deleted)",
785 orig_target
? label_orig
: "",
786 orig_target
? "\n" : "",
787 orig_target
? orig_target
: "",
788 orig_target
? "\n" : "",
789 GOT_DIFF_CONFLICT_MARKER_SEP
,
790 local_target
, GOT_DIFF_CONFLICT_MARKER_END
) < 0) {
791 err
= got_error_from_errno2("fprintf", path
);
795 if (unlink(ondisk_path
) == -1) {
796 err
= got_error_from_errno2("unlink", ondisk_path
);
799 if (rename(path
, ondisk_path
) == -1) {
800 err
= got_error_from_errno3("rename", path
, ondisk_path
);
804 if (f
!= NULL
&& fclose(f
) == EOF
&& err
== NULL
)
805 err
= got_error_from_errno2("fclose", path
);
812 /* forward declaration */
813 static const struct got_error
*
814 merge_blob(int *, struct got_worktree
*, struct got_blob_object
*,
815 const char *, const char *, uint16_t, const char *,
816 struct got_blob_object
*, struct got_object_id
*,
817 struct got_repository
*, got_worktree_checkout_cb
, void *);
820 * Merge a symlink into the work tree, where blob_orig acts as the common
821 * ancestor, deriv_target is the link target of the first derived version,
822 * and the symlink on disk acts as the second derived version.
823 * Assume that contents of both blobs represent symlinks.
825 static const struct got_error
*
826 merge_symlink(struct got_worktree
*worktree
,
827 struct got_blob_object
*blob_orig
, const char *ondisk_path
,
828 const char *path
, const char *label_orig
, const char *deriv_target
,
829 struct got_object_id
*deriv_base_commit_id
, struct got_repository
*repo
,
830 got_worktree_checkout_cb progress_cb
, void *progress_arg
)
832 const struct got_error
*err
= NULL
;
833 char *ancestor_target
= NULL
;
835 ssize_t ondisk_len
, deriv_len
;
836 char ondisk_target
[PATH_MAX
];
837 int have_local_change
= 0;
838 int have_incoming_change
= 0;
840 if (lstat(ondisk_path
, &sb
) == -1)
841 return got_error_from_errno2("lstat", ondisk_path
);
843 ondisk_len
= readlink(ondisk_path
, ondisk_target
,
844 sizeof(ondisk_target
));
845 if (ondisk_len
== -1) {
846 err
= got_error_from_errno2("readlink",
850 ondisk_target
[ondisk_len
] = '\0';
853 err
= got_object_blob_read_to_str(&ancestor_target
, blob_orig
);
858 if (ancestor_target
== NULL
||
859 (ondisk_len
!= strlen(ancestor_target
) ||
860 memcmp(ondisk_target
, ancestor_target
, ondisk_len
) != 0))
861 have_local_change
= 1;
863 deriv_len
= strlen(deriv_target
);
864 if (ancestor_target
== NULL
||
865 (deriv_len
!= strlen(ancestor_target
) ||
866 memcmp(deriv_target
, ancestor_target
, deriv_len
) != 0))
867 have_incoming_change
= 1;
869 if (!have_local_change
&& !have_incoming_change
) {
870 if (ancestor_target
) {
871 /* Both sides made the same change. */
872 err
= (*progress_cb
)(progress_arg
, GOT_STATUS_MERGE
,
874 } else if (deriv_len
== ondisk_len
&&
875 memcmp(ondisk_target
, deriv_target
, deriv_len
) == 0) {
876 /* Both sides added the same symlink. */
877 err
= (*progress_cb
)(progress_arg
, GOT_STATUS_MERGE
,
880 /* Both sides added symlinks which don't match. */
881 err
= install_symlink_conflict(deriv_target
,
882 deriv_base_commit_id
, ancestor_target
,
883 label_orig
, ondisk_target
, ondisk_path
);
886 err
= (*progress_cb
)(progress_arg
, GOT_STATUS_CONFLICT
,
889 } else if (!have_local_change
&& have_incoming_change
) {
890 /* Apply the incoming change. */
891 err
= update_symlink(ondisk_path
, deriv_target
,
892 strlen(deriv_target
));
895 err
= (*progress_cb
)(progress_arg
, GOT_STATUS_MERGE
, path
);
896 } else if (have_local_change
&& have_incoming_change
) {
897 if (deriv_len
== ondisk_len
&&
898 memcmp(deriv_target
, ondisk_target
, deriv_len
) == 0) {
899 /* Both sides made the same change. */
900 err
= (*progress_cb
)(progress_arg
, GOT_STATUS_MERGE
,
903 err
= install_symlink_conflict(deriv_target
,
904 deriv_base_commit_id
, ancestor_target
, label_orig
,
905 ondisk_target
, ondisk_path
);
908 err
= (*progress_cb
)(progress_arg
, GOT_STATUS_CONFLICT
,
914 free(ancestor_target
);
918 static const struct got_error
*
919 dump_symlink_target_path_to_file(FILE **outfile
, const char *ondisk_path
)
921 const struct got_error
*err
= NULL
;
922 char target_path
[PATH_MAX
];
931 return got_error_from_errno("got_opentemp");
932 target_len
= readlink(ondisk_path
, target_path
, sizeof(target_path
));
933 if (target_len
== -1) {
934 err
= got_error_from_errno2("readlink", ondisk_path
);
937 n
= fwrite(target_path
, 1, target_len
, f
);
938 if (n
!= target_len
) {
939 err
= got_ferror(f
, GOT_ERR_IO
);
942 if (fflush(f
) == EOF
) {
943 err
= got_error_from_errno("fflush");
946 if (fseek(f
, 0L, SEEK_SET
) == -1) {
947 err
= got_ferror(f
, GOT_ERR_IO
);
959 * Perform a 3-way merge where blob_orig acts as the common ancestor,
960 * blob_deriv acts as the first derived version, and the file on disk
961 * acts as the second derived version.
963 static const struct got_error
*
964 merge_blob(int *local_changes_subsumed
, struct got_worktree
*worktree
,
965 struct got_blob_object
*blob_orig
, const char *ondisk_path
,
966 const char *path
, uint16_t st_mode
, const char *label_orig
,
967 struct got_blob_object
*blob_deriv
,
968 struct got_object_id
*deriv_base_commit_id
, struct got_repository
*repo
,
969 got_worktree_checkout_cb progress_cb
, void *progress_arg
)
971 const struct got_error
*err
= NULL
;
972 FILE *f_orig
= NULL
, *f_deriv
= NULL
, *f_deriv2
= NULL
;
973 char *blob_orig_path
= NULL
;
974 char *blob_deriv_path
= NULL
, *base_path
= NULL
, *id_str
= NULL
;
975 char *label_deriv
= NULL
, *parent
= NULL
;
977 *local_changes_subsumed
= 0;
979 err
= got_path_dirname(&parent
, ondisk_path
);
984 if (asprintf(&base_path
, "%s/got-merge-blob-orig",
986 err
= got_error_from_errno("asprintf");
991 err
= got_opentemp_named(&blob_orig_path
, &f_orig
, base_path
);
994 err
= got_object_blob_dump_to_file(NULL
, NULL
, NULL
, f_orig
,
1001 * No common ancestor exists. This is an "add vs add" conflict
1002 * and we simply use an empty ancestor file to make both files
1003 * appear in the merged result in their entirety.
1005 f_orig
= got_opentemp();
1006 if (f_orig
== NULL
) {
1007 err
= got_error_from_errno("got_opentemp");
1012 if (asprintf(&base_path
, "%s/got-merge-blob-deriv", parent
) == -1) {
1013 err
= got_error_from_errno("asprintf");
1018 err
= got_opentemp_named(&blob_deriv_path
, &f_deriv
, base_path
);
1021 err
= got_object_blob_dump_to_file(NULL
, NULL
, NULL
, f_deriv
,
1026 err
= got_object_id_str(&id_str
, deriv_base_commit_id
);
1029 if (asprintf(&label_deriv
, "%s: commit %s",
1030 GOT_MERGE_LABEL_MERGED
, id_str
) == -1) {
1031 err
= got_error_from_errno("asprintf");
1036 * In order the run a 3-way merge with a symlink we copy the symlink's
1037 * target path into a temporary file and use that file with diff3.
1039 if (S_ISLNK(st_mode
)) {
1040 err
= dump_symlink_target_path_to_file(&f_deriv2
, ondisk_path
);
1045 fd
= open(ondisk_path
, O_RDONLY
| O_NOFOLLOW
| O_CLOEXEC
);
1047 err
= got_error_from_errno2("open", ondisk_path
);
1050 f_deriv2
= fdopen(fd
, "r");
1051 if (f_deriv2
== NULL
) {
1052 err
= got_error_from_errno2("fdopen", ondisk_path
);
1058 err
= merge_file(local_changes_subsumed
, worktree
, f_orig
, f_deriv
,
1059 f_deriv2
, ondisk_path
, path
, st_mode
, label_orig
, label_deriv
,
1060 NULL
, GOT_DIFF_ALGORITHM_MYERS
, repo
, progress_cb
, progress_arg
);
1062 if (f_orig
&& fclose(f_orig
) == EOF
&& err
== NULL
)
1063 err
= got_error_from_errno("fclose");
1064 if (f_deriv
&& fclose(f_deriv
) == EOF
&& err
== NULL
)
1065 err
= got_error_from_errno("fclose");
1066 if (f_deriv2
&& fclose(f_deriv2
) == EOF
&& err
== NULL
)
1067 err
= got_error_from_errno("fclose");
1069 if (blob_orig_path
) {
1070 unlink(blob_orig_path
);
1071 free(blob_orig_path
);
1073 if (blob_deriv_path
) {
1074 unlink(blob_deriv_path
);
1075 free(blob_deriv_path
);
1083 static const struct got_error
*
1084 create_fileindex_entry(struct got_fileindex_entry
**new_iep
,
1085 struct got_fileindex
*fileindex
, struct got_object_id
*base_commit_id
,
1086 int wt_fd
, const char *path
, struct got_object_id
*blob_id
)
1088 const struct got_error
*err
= NULL
;
1089 struct got_fileindex_entry
*new_ie
;
1093 err
= got_fileindex_entry_alloc(&new_ie
, path
);
1097 err
= got_fileindex_entry_update(new_ie
, wt_fd
, path
,
1098 blob_id
->sha1
, base_commit_id
->sha1
, 1);
1102 err
= got_fileindex_entry_add(fileindex
, new_ie
);
1105 got_fileindex_entry_free(new_ie
);
1112 get_ondisk_perms(int executable
, mode_t st_mode
)
1114 mode_t xbits
= S_IXUSR
;
1117 /* Map read bits to execute bits. */
1118 if (st_mode
& S_IRGRP
)
1120 if (st_mode
& S_IROTH
)
1122 return st_mode
| xbits
;
1125 return (st_mode
& ~(S_IXUSR
| S_IXGRP
| S_IXOTH
));
1128 /* forward declaration */
1129 static const struct got_error
*
1130 install_blob(struct got_worktree
*worktree
, const char *ondisk_path
,
1131 const char *path
, mode_t te_mode
, mode_t st_mode
,
1132 struct got_blob_object
*blob
, int restoring_missing_file
,
1133 int reverting_versioned_file
, int installing_bad_symlink
,
1134 int path_is_unversioned
, struct got_repository
*repo
,
1135 got_worktree_checkout_cb progress_cb
, void *progress_arg
);
1138 * This function assumes that the provided symlink target points at a
1139 * safe location in the work tree!
1141 static const struct got_error
*
1142 replace_existing_symlink(int *did_something
, const char *ondisk_path
,
1143 const char *target_path
, size_t target_len
)
1145 const struct got_error
*err
= NULL
;
1147 char etarget
[PATH_MAX
];
1153 * "Bad" symlinks (those pointing outside the work tree or into the
1154 * .got directory) are installed in the work tree as a regular file
1155 * which contains the bad symlink target path.
1156 * The new symlink target has already been checked for safety by our
1157 * caller. If we can successfully open a regular file then we simply
1158 * replace this file with a symlink below.
1160 fd
= open(ondisk_path
, O_RDWR
| O_EXCL
| O_NOFOLLOW
| O_CLOEXEC
);
1162 if (!got_err_open_nofollow_on_symlink())
1163 return got_error_from_errno2("open", ondisk_path
);
1165 /* We are updating an existing on-disk symlink. */
1166 elen
= readlink(ondisk_path
, etarget
, sizeof(etarget
));
1168 return got_error_from_errno2("readlink", ondisk_path
);
1170 if (elen
== target_len
&&
1171 memcmp(etarget
, target_path
, target_len
) == 0)
1172 return NULL
; /* nothing to do */
1176 err
= update_symlink(ondisk_path
, target_path
, target_len
);
1177 if (fd
!= -1 && close(fd
) == -1 && err
== NULL
)
1178 err
= got_error_from_errno2("close", ondisk_path
);
1182 static const struct got_error
*
1183 is_bad_symlink_target(int *is_bad_symlink
, const char *target_path
,
1184 size_t target_len
, const char *ondisk_path
, const char *wtroot_path
)
1186 const struct got_error
*err
= NULL
;
1187 char canonpath
[PATH_MAX
];
1188 char *path_got
= NULL
;
1190 *is_bad_symlink
= 0;
1192 if (target_len
>= sizeof(canonpath
)) {
1193 *is_bad_symlink
= 1;
1198 * We do not use realpath(3) to resolve the symlink's target
1199 * path because we don't want to resolve symlinks recursively.
1200 * Instead we make the path absolute and then canonicalize it.
1201 * Relative symlink target lookup should begin at the directory
1202 * in which the blob object is being installed.
1204 if (!got_path_is_absolute(target_path
)) {
1205 char *abspath
, *parent
;
1206 err
= got_path_dirname(&parent
, ondisk_path
);
1209 if (asprintf(&abspath
, "%s/%s", parent
, target_path
) == -1) {
1211 return got_error_from_errno("asprintf");
1214 if (strlen(abspath
) >= sizeof(canonpath
)) {
1215 err
= got_error_path(abspath
, GOT_ERR_BAD_PATH
);
1219 err
= got_canonpath(abspath
, canonpath
, sizeof(canonpath
));
1224 err
= got_canonpath(target_path
, canonpath
, sizeof(canonpath
));
1229 /* Only allow symlinks pointing at paths within the work tree. */
1230 if (!got_path_is_child(canonpath
, wtroot_path
, strlen(wtroot_path
))) {
1231 *is_bad_symlink
= 1;
1235 /* Do not allow symlinks pointing into the .got directory. */
1236 if (asprintf(&path_got
, "%s/%s", wtroot_path
,
1237 GOT_WORKTREE_GOT_DIR
) == -1)
1238 return got_error_from_errno("asprintf");
1239 if (got_path_is_child(canonpath
, path_got
, strlen(path_got
)))
1240 *is_bad_symlink
= 1;
1246 static const struct got_error
*
1247 install_symlink(int *is_bad_symlink
, struct got_worktree
*worktree
,
1248 const char *ondisk_path
, const char *path
, struct got_blob_object
*blob
,
1249 int restoring_missing_file
, int reverting_versioned_file
,
1250 int path_is_unversioned
, int allow_bad_symlinks
,
1251 struct got_repository
*repo
,
1252 got_worktree_checkout_cb progress_cb
, void *progress_arg
)
1254 const struct got_error
*err
= NULL
;
1255 char target_path
[PATH_MAX
];
1256 size_t len
, target_len
= 0;
1257 char *path_got
= NULL
;
1258 const uint8_t *buf
= got_object_blob_get_read_buf(blob
);
1259 size_t hdrlen
= got_object_blob_get_hdrlen(blob
);
1261 *is_bad_symlink
= 0;
1264 * Blob object content specifies the target path of the link.
1265 * If a symbolic link cannot be installed we instead create
1266 * a regular file which contains the link target path stored
1267 * in the blob object.
1270 err
= got_object_blob_read_block(&len
, blob
);
1271 if (len
+ target_len
>= sizeof(target_path
)) {
1272 /* Path too long; install as a regular file. */
1273 *is_bad_symlink
= 1;
1274 got_object_blob_rewind(blob
);
1275 return install_blob(worktree
, ondisk_path
, path
,
1276 GOT_DEFAULT_FILE_MODE
, GOT_DEFAULT_FILE_MODE
, blob
,
1277 restoring_missing_file
, reverting_versioned_file
,
1278 1, path_is_unversioned
, repo
, progress_cb
,
1282 /* Skip blob object header first time around. */
1283 memcpy(target_path
+ target_len
, buf
+ hdrlen
,
1285 target_len
+= len
- hdrlen
;
1289 target_path
[target_len
] = '\0';
1291 err
= is_bad_symlink_target(is_bad_symlink
, target_path
, target_len
,
1292 ondisk_path
, worktree
->root_path
);
1296 if (*is_bad_symlink
&& !allow_bad_symlinks
) {
1297 /* install as a regular file */
1298 got_object_blob_rewind(blob
);
1299 err
= install_blob(worktree
, ondisk_path
, path
,
1300 GOT_DEFAULT_FILE_MODE
, GOT_DEFAULT_FILE_MODE
, blob
,
1301 restoring_missing_file
, reverting_versioned_file
, 1,
1302 path_is_unversioned
, repo
, progress_cb
, progress_arg
);
1306 if (symlink(target_path
, ondisk_path
) == -1) {
1307 if (errno
== EEXIST
) {
1308 int symlink_replaced
;
1309 if (path_is_unversioned
) {
1310 err
= (*progress_cb
)(progress_arg
,
1311 GOT_STATUS_UNVERSIONED
, path
);
1314 err
= replace_existing_symlink(&symlink_replaced
,
1315 ondisk_path
, target_path
, target_len
);
1319 if (symlink_replaced
) {
1320 err
= (*progress_cb
)(progress_arg
,
1321 reverting_versioned_file
?
1323 GOT_STATUS_UPDATE
, path
);
1325 err
= (*progress_cb
)(progress_arg
,
1326 GOT_STATUS_EXISTS
, path
);
1329 goto done
; /* Nothing else to do. */
1332 if (errno
== ENOENT
) {
1334 err
= got_path_dirname(&parent
, ondisk_path
);
1337 err
= add_dir_on_disk(worktree
, parent
);
1342 * Retry, and fall through to error handling
1343 * below if this second attempt fails.
1345 if (symlink(target_path
, ondisk_path
) != -1) {
1346 err
= NULL
; /* success */
1351 /* Handle errors from first or second creation attempt. */
1352 if (errno
== ENAMETOOLONG
) {
1353 /* bad target path; install as a regular file */
1354 *is_bad_symlink
= 1;
1355 got_object_blob_rewind(blob
);
1356 err
= install_blob(worktree
, ondisk_path
, path
,
1357 GOT_DEFAULT_FILE_MODE
, GOT_DEFAULT_FILE_MODE
, blob
,
1358 restoring_missing_file
, reverting_versioned_file
, 1,
1359 path_is_unversioned
, repo
,
1360 progress_cb
, progress_arg
);
1361 } else if (errno
== ENOTDIR
) {
1362 err
= got_error_path(ondisk_path
,
1363 GOT_ERR_FILE_OBSTRUCTED
);
1365 err
= got_error_from_errno3("symlink",
1366 target_path
, ondisk_path
);
1368 } else if (progress_cb
)
1369 err
= (*progress_cb
)(progress_arg
, reverting_versioned_file
?
1370 GOT_STATUS_REVERT
: GOT_STATUS_ADD
, path
);
1376 static const struct got_error
*
1377 install_blob(struct got_worktree
*worktree
, const char *ondisk_path
,
1378 const char *path
, mode_t te_mode
, mode_t st_mode
,
1379 struct got_blob_object
*blob
, int restoring_missing_file
,
1380 int reverting_versioned_file
, int installing_bad_symlink
,
1381 int path_is_unversioned
, struct got_repository
*repo
,
1382 got_worktree_checkout_cb progress_cb
, void *progress_arg
)
1384 const struct got_error
*err
= NULL
;
1388 char *tmppath
= NULL
;
1390 fd
= open(ondisk_path
, O_RDWR
| O_CREAT
| O_EXCL
| O_NOFOLLOW
|
1391 O_CLOEXEC
, GOT_DEFAULT_FILE_MODE
);
1393 if (errno
== ENOENT
) {
1395 err
= got_path_dirname(&parent
, path
);
1398 err
= add_dir_on_disk(worktree
, parent
);
1402 fd
= open(ondisk_path
,
1403 O_RDWR
| O_CREAT
| O_EXCL
| O_NOFOLLOW
| O_CLOEXEC
,
1404 GOT_DEFAULT_FILE_MODE
);
1406 return got_error_from_errno2("open",
1408 } else if (errno
== EEXIST
) {
1409 if (path_is_unversioned
) {
1410 err
= (*progress_cb
)(progress_arg
,
1411 GOT_STATUS_UNVERSIONED
, path
);
1414 if (!(S_ISLNK(st_mode
) && S_ISREG(te_mode
)) &&
1415 !S_ISREG(st_mode
) && !installing_bad_symlink
) {
1416 /* TODO file is obstructed; do something */
1417 err
= got_error_path(ondisk_path
,
1418 GOT_ERR_FILE_OBSTRUCTED
);
1421 err
= got_opentemp_named_fd(&tmppath
, &fd
,
1428 return got_error_from_errno2("open", ondisk_path
);
1431 if (fchmod(fd
, get_ondisk_perms(te_mode
& S_IXUSR
, st_mode
)) == -1) {
1432 err
= got_error_from_errno2("fchmod",
1433 update
? tmppath
: ondisk_path
);
1438 if (restoring_missing_file
)
1439 err
= (*progress_cb
)(progress_arg
, GOT_STATUS_MISSING
,
1441 else if (reverting_versioned_file
)
1442 err
= (*progress_cb
)(progress_arg
, GOT_STATUS_REVERT
,
1445 err
= (*progress_cb
)(progress_arg
,
1446 update
? GOT_STATUS_UPDATE
: GOT_STATUS_ADD
, path
);
1451 hdrlen
= got_object_blob_get_hdrlen(blob
);
1453 const uint8_t *buf
= got_object_blob_get_read_buf(blob
);
1454 err
= got_object_blob_read_block(&len
, blob
);
1458 /* Skip blob object header first time around. */
1459 ssize_t outlen
= write(fd
, buf
+ hdrlen
, len
- hdrlen
);
1461 err
= got_error_from_errno("write");
1463 } else if (outlen
!= len
- hdrlen
) {
1464 err
= got_error(GOT_ERR_IO
);
1471 if (fsync(fd
) != 0) {
1472 err
= got_error_from_errno("fsync");
1477 if (S_ISLNK(st_mode
) && unlink(ondisk_path
) == -1) {
1478 err
= got_error_from_errno2("unlink", ondisk_path
);
1481 if (rename(tmppath
, ondisk_path
) != 0) {
1482 err
= got_error_from_errno3("rename", tmppath
,
1491 if (fd
!= -1 && close(fd
) == -1 && err
== NULL
)
1492 err
= got_error_from_errno("close");
1493 if (tmppath
!= NULL
&& unlink(tmppath
) == -1 && err
== NULL
)
1494 err
= got_error_from_errno2("unlink", tmppath
);
1499 /* Upgrade STATUS_MODIFY to STATUS_CONFLICT if a conflict marker is found. */
1500 static const struct got_error
*
1501 get_modified_file_content_status(unsigned char *status
, FILE *f
)
1503 const struct got_error
*err
= NULL
;
1504 const char *markers
[3] = {
1505 GOT_DIFF_CONFLICT_MARKER_BEGIN
,
1506 GOT_DIFF_CONFLICT_MARKER_SEP
,
1507 GOT_DIFF_CONFLICT_MARKER_END
1511 size_t linesize
= 0;
1514 while (*status
== GOT_STATUS_MODIFY
) {
1515 linelen
= getline(&line
, &linesize
, f
);
1516 if (linelen
== -1) {
1519 err
= got_ferror(f
, GOT_ERR_IO
);
1523 if (strncmp(line
, markers
[i
], strlen(markers
[i
])) == 0) {
1524 if (strcmp(markers
[i
], GOT_DIFF_CONFLICT_MARKER_END
)
1526 *status
= GOT_STATUS_CONFLICT
;
1537 xbit_differs(struct got_fileindex_entry
*ie
, uint16_t st_mode
)
1539 mode_t ie_mode
= got_fileindex_perms_to_st(ie
);
1540 return ((ie_mode
& S_IXUSR
) != (st_mode
& S_IXUSR
));
1544 stat_info_differs(struct got_fileindex_entry
*ie
, struct stat
*sb
)
1546 return !(ie
->ctime_sec
== sb
->st_ctim
.tv_sec
&&
1547 ie
->ctime_nsec
== sb
->st_ctim
.tv_nsec
&&
1548 ie
->mtime_sec
== sb
->st_mtim
.tv_sec
&&
1549 ie
->mtime_nsec
== sb
->st_mtim
.tv_nsec
&&
1550 ie
->size
== (sb
->st_size
& 0xffffffff) &&
1551 !xbit_differs(ie
, sb
->st_mode
));
1554 static unsigned char
1555 get_staged_status(struct got_fileindex_entry
*ie
)
1557 switch (got_fileindex_entry_stage_get(ie
)) {
1558 case GOT_FILEIDX_STAGE_ADD
:
1559 return GOT_STATUS_ADD
;
1560 case GOT_FILEIDX_STAGE_DELETE
:
1561 return GOT_STATUS_DELETE
;
1562 case GOT_FILEIDX_STAGE_MODIFY
:
1563 return GOT_STATUS_MODIFY
;
1565 return GOT_STATUS_NO_CHANGE
;
1569 static const struct got_error
*
1570 get_symlink_modification_status(unsigned char *status
,
1571 struct got_fileindex_entry
*ie
, const char *abspath
,
1572 int dirfd
, const char *de_name
, struct got_blob_object
*blob
)
1574 const struct got_error
*err
= NULL
;
1575 char target_path
[PATH_MAX
];
1576 char etarget
[PATH_MAX
];
1578 size_t len
, target_len
= 0;
1579 const uint8_t *buf
= got_object_blob_get_read_buf(blob
);
1580 size_t hdrlen
= got_object_blob_get_hdrlen(blob
);
1582 *status
= GOT_STATUS_NO_CHANGE
;
1584 /* Blob object content specifies the target path of the link. */
1586 err
= got_object_blob_read_block(&len
, blob
);
1589 if (len
+ target_len
>= sizeof(target_path
)) {
1591 * Should not happen. The blob contents were OK
1592 * when this symlink was installed.
1594 return got_error(GOT_ERR_NO_SPACE
);
1597 /* Skip blob object header first time around. */
1598 memcpy(target_path
+ target_len
, buf
+ hdrlen
,
1600 target_len
+= len
- hdrlen
;
1604 target_path
[target_len
] = '\0';
1607 elen
= readlinkat(dirfd
, de_name
, etarget
, sizeof(etarget
));
1609 return got_error_from_errno2("readlinkat", abspath
);
1611 elen
= readlink(abspath
, etarget
, sizeof(etarget
));
1613 return got_error_from_errno2("readlink", abspath
);
1616 if (elen
!= target_len
|| memcmp(etarget
, target_path
, target_len
) != 0)
1617 *status
= GOT_STATUS_MODIFY
;
1622 static const struct got_error
*
1623 get_file_status(unsigned char *status
, struct stat
*sb
,
1624 struct got_fileindex_entry
*ie
, const char *abspath
,
1625 int dirfd
, const char *de_name
, struct got_repository
*repo
)
1627 const struct got_error
*err
= NULL
;
1628 struct got_object_id id
;
1630 int fd
= -1, fd1
= -1;
1633 struct got_blob_object
*blob
= NULL
;
1635 unsigned char staged_status
= get_staged_status(ie
);
1637 *status
= GOT_STATUS_NO_CHANGE
;
1638 memset(sb
, 0, sizeof(*sb
));
1641 * Whenever the caller provides a directory descriptor and a
1642 * directory entry name for the file, use them! This prevents
1643 * race conditions if filesystem paths change beneath our feet.
1646 if (fstatat(dirfd
, de_name
, sb
, AT_SYMLINK_NOFOLLOW
) == -1) {
1647 if (errno
== ENOENT
) {
1648 if (got_fileindex_entry_has_file_on_disk(ie
))
1649 *status
= GOT_STATUS_MISSING
;
1651 *status
= GOT_STATUS_DELETE
;
1654 err
= got_error_from_errno2("fstatat", abspath
);
1658 fd
= open(abspath
, O_RDONLY
| O_NOFOLLOW
| O_CLOEXEC
);
1659 if (fd
== -1 && errno
!= ENOENT
&&
1660 !got_err_open_nofollow_on_symlink())
1661 return got_error_from_errno2("open", abspath
);
1662 else if (fd
== -1 && got_err_open_nofollow_on_symlink()) {
1663 if (lstat(abspath
, sb
) == -1)
1664 return got_error_from_errno2("lstat", abspath
);
1665 } else if (fd
== -1 || fstat(fd
, sb
) == -1) {
1666 if (errno
== ENOENT
) {
1667 if (got_fileindex_entry_has_file_on_disk(ie
))
1668 *status
= GOT_STATUS_MISSING
;
1670 *status
= GOT_STATUS_DELETE
;
1673 err
= got_error_from_errno2("fstat", abspath
);
1678 if (!S_ISREG(sb
->st_mode
) && !S_ISLNK(sb
->st_mode
)) {
1679 *status
= GOT_STATUS_OBSTRUCTED
;
1683 if (!got_fileindex_entry_has_file_on_disk(ie
)) {
1684 *status
= GOT_STATUS_DELETE
;
1686 } else if (!got_fileindex_entry_has_blob(ie
) &&
1687 staged_status
!= GOT_STATUS_ADD
) {
1688 *status
= GOT_STATUS_ADD
;
1692 if (!stat_info_differs(ie
, sb
))
1695 if (S_ISLNK(sb
->st_mode
) &&
1696 got_fileindex_entry_filetype_get(ie
) != GOT_FILEIDX_MODE_SYMLINK
) {
1697 *status
= GOT_STATUS_MODIFY
;
1701 if (staged_status
== GOT_STATUS_MODIFY
||
1702 staged_status
== GOT_STATUS_ADD
)
1703 memcpy(id
.sha1
, ie
->staged_blob_sha1
, sizeof(id
.sha1
));
1705 memcpy(id
.sha1
, ie
->blob_sha1
, sizeof(id
.sha1
));
1707 fd1
= got_opentempfd();
1709 err
= got_error_from_errno("got_opentempfd");
1712 err
= got_object_open_as_blob(&blob
, repo
, &id
, sizeof(fbuf
), fd1
);
1716 if (S_ISLNK(sb
->st_mode
)) {
1717 err
= get_symlink_modification_status(status
, ie
,
1718 abspath
, dirfd
, de_name
, blob
);
1723 fd
= openat(dirfd
, de_name
, O_RDONLY
| O_NOFOLLOW
| O_CLOEXEC
);
1725 err
= got_error_from_errno2("openat", abspath
);
1730 f
= fdopen(fd
, "r");
1732 err
= got_error_from_errno2("fdopen", abspath
);
1736 hdrlen
= got_object_blob_get_hdrlen(blob
);
1738 const uint8_t *bbuf
= got_object_blob_get_read_buf(blob
);
1739 err
= got_object_blob_read_block(&blen
, blob
);
1742 /* Skip length of blob object header first time around. */
1743 flen
= fread(fbuf
, 1, sizeof(fbuf
) - hdrlen
, f
);
1744 if (flen
== 0 && ferror(f
)) {
1745 err
= got_error_from_errno("fread");
1748 if (blen
- hdrlen
== 0) {
1750 *status
= GOT_STATUS_MODIFY
;
1752 } else if (flen
== 0) {
1753 if (blen
- hdrlen
!= 0)
1754 *status
= GOT_STATUS_MODIFY
;
1756 } else if (blen
- hdrlen
== flen
) {
1757 /* Skip blob object header first time around. */
1758 if (memcmp(bbuf
+ hdrlen
, fbuf
, flen
) != 0) {
1759 *status
= GOT_STATUS_MODIFY
;
1763 *status
= GOT_STATUS_MODIFY
;
1769 if (*status
== GOT_STATUS_MODIFY
) {
1771 err
= get_modified_file_content_status(status
, f
);
1772 } else if (xbit_differs(ie
, sb
->st_mode
))
1773 *status
= GOT_STATUS_MODE_CHANGE
;
1775 if (fd1
!= -1 && close(fd1
) == -1 && err
== NULL
)
1776 err
= got_error_from_errno("close");
1778 got_object_blob_close(blob
);
1779 if (f
!= NULL
&& fclose(f
) == EOF
&& err
== NULL
)
1780 err
= got_error_from_errno2("fclose", abspath
);
1781 if (fd
!= -1 && close(fd
) == -1 && err
== NULL
)
1782 err
= got_error_from_errno2("close", abspath
);
1787 * Update timestamps in the file index if a file is unmodified and
1788 * we had to run a full content comparison to find out.
1790 static const struct got_error
*
1791 sync_timestamps(int wt_fd
, const char *path
, unsigned char status
,
1792 struct got_fileindex_entry
*ie
, struct stat
*sb
)
1794 if (status
== GOT_STATUS_NO_CHANGE
&& stat_info_differs(ie
, sb
))
1795 return got_fileindex_entry_update(ie
, wt_fd
, path
,
1796 ie
->blob_sha1
, ie
->commit_sha1
, 1);
1801 static const struct got_error
*
1802 update_blob(struct got_worktree
*worktree
,
1803 struct got_fileindex
*fileindex
, struct got_fileindex_entry
*ie
,
1804 struct got_tree_entry
*te
, const char *path
,
1805 struct got_repository
*repo
, got_worktree_checkout_cb progress_cb
,
1808 const struct got_error
*err
= NULL
;
1809 struct got_blob_object
*blob
= NULL
;
1810 char *ondisk_path
= NULL
;
1811 unsigned char status
= GOT_STATUS_NO_CHANGE
;
1813 int fd1
= -1, fd2
= -1;
1815 if (asprintf(&ondisk_path
, "%s/%s", worktree
->root_path
, path
) == -1)
1816 return got_error_from_errno("asprintf");
1819 if (get_staged_status(ie
) != GOT_STATUS_NO_CHANGE
) {
1820 err
= got_error_path(ie
->path
, GOT_ERR_FILE_STAGED
);
1823 err
= get_file_status(&status
, &sb
, ie
, ondisk_path
, -1, NULL
,
1827 if (status
== GOT_STATUS_MISSING
|| status
== GOT_STATUS_DELETE
)
1828 sb
.st_mode
= got_fileindex_perms_to_st(ie
);
1830 if (stat(ondisk_path
, &sb
) == -1) {
1831 if (errno
!= ENOENT
) {
1832 err
= got_error_from_errno2("stat",
1836 sb
.st_mode
= GOT_DEFAULT_FILE_MODE
;
1837 status
= GOT_STATUS_UNVERSIONED
;
1839 if (S_ISREG(sb
.st_mode
) || S_ISLNK(sb
.st_mode
))
1840 status
= GOT_STATUS_UNVERSIONED
;
1842 status
= GOT_STATUS_OBSTRUCTED
;
1846 if (status
== GOT_STATUS_OBSTRUCTED
) {
1848 got_fileindex_entry_mark_skipped(ie
);
1849 err
= (*progress_cb
)(progress_arg
, status
, path
);
1852 if (status
== GOT_STATUS_CONFLICT
) {
1854 got_fileindex_entry_mark_skipped(ie
);
1855 err
= (*progress_cb
)(progress_arg
, GOT_STATUS_CANNOT_UPDATE
,
1860 if (ie
&& status
!= GOT_STATUS_MISSING
&& S_ISREG(sb
.st_mode
) &&
1861 (S_ISLNK(te
->mode
) ||
1862 (te
->mode
& S_IXUSR
) == (sb
.st_mode
& S_IXUSR
))) {
1864 * This is a regular file or an installed bad symlink.
1865 * If the file index indicates that this file is already
1866 * up-to-date with respect to the repository we can skip
1867 * updating contents of this file.
1869 if (got_fileindex_entry_has_commit(ie
) &&
1870 memcmp(ie
->commit_sha1
, worktree
->base_commit_id
->sha1
,
1871 SHA1_DIGEST_LENGTH
) == 0) {
1873 err
= sync_timestamps(worktree
->root_fd
,
1874 path
, status
, ie
, &sb
);
1877 err
= (*progress_cb
)(progress_arg
, GOT_STATUS_EXISTS
,
1881 if (got_fileindex_entry_has_blob(ie
) &&
1882 memcmp(ie
->blob_sha1
, te
->id
.sha1
,
1883 SHA1_DIGEST_LENGTH
) == 0) {
1884 /* Different commit but the same blob. */
1885 err
= sync_timestamps(worktree
->root_fd
,
1886 path
, status
, ie
, &sb
);
1889 err
= (*progress_cb
)(progress_arg
, GOT_STATUS_EXISTS
,
1895 fd1
= got_opentempfd();
1897 err
= got_error_from_errno("got_opentempfd");
1900 err
= got_object_open_as_blob(&blob
, repo
, &te
->id
, 8192, fd1
);
1904 if (status
== GOT_STATUS_MODIFY
|| status
== GOT_STATUS_ADD
) {
1905 int update_timestamps
;
1906 struct got_blob_object
*blob2
= NULL
;
1907 char *label_orig
= NULL
;
1908 if (got_fileindex_entry_has_blob(ie
)) {
1909 fd2
= got_opentempfd();
1911 err
= got_error_from_errno("got_opentempfd");
1914 struct got_object_id id2
;
1915 memcpy(id2
.sha1
, ie
->blob_sha1
, SHA1_DIGEST_LENGTH
);
1916 err
= got_object_open_as_blob(&blob2
, repo
, &id2
, 8192,
1921 if (got_fileindex_entry_has_commit(ie
)) {
1922 char id_str
[SHA1_DIGEST_STRING_LENGTH
];
1923 if (got_sha1_digest_to_str(ie
->commit_sha1
, id_str
,
1924 sizeof(id_str
)) == NULL
) {
1925 err
= got_error_path(id_str
,
1926 GOT_ERR_BAD_OBJ_ID_STR
);
1929 if (asprintf(&label_orig
, "%s: commit %s",
1930 GOT_MERGE_LABEL_BASE
, id_str
) == -1) {
1931 err
= got_error_from_errno("asprintf");
1935 if (S_ISLNK(te
->mode
) && S_ISLNK(sb
.st_mode
)) {
1937 err
= got_object_blob_read_to_str(&link_target
, blob
);
1940 err
= merge_symlink(worktree
, blob2
, ondisk_path
, path
,
1941 label_orig
, link_target
, worktree
->base_commit_id
,
1942 repo
, progress_cb
, progress_arg
);
1945 err
= merge_blob(&update_timestamps
, worktree
, blob2
,
1946 ondisk_path
, path
, sb
.st_mode
, label_orig
, blob
,
1947 worktree
->base_commit_id
, repo
,
1948 progress_cb
, progress_arg
);
1951 if (fd2
!= -1 && close(fd2
) == -1 && err
== NULL
) {
1952 err
= got_error_from_errno("close");
1956 got_object_blob_close(blob2
);
1960 * Do not update timestamps of files with local changes.
1961 * Otherwise, a future status walk would treat them as
1962 * unmodified files again.
1964 err
= got_fileindex_entry_update(ie
, worktree
->root_fd
, path
,
1965 blob
->id
.sha1
, worktree
->base_commit_id
->sha1
,
1967 } else if (status
== GOT_STATUS_MODE_CHANGE
) {
1968 err
= got_fileindex_entry_update(ie
, worktree
->root_fd
, path
,
1969 blob
->id
.sha1
, worktree
->base_commit_id
->sha1
, 0);
1970 } else if (status
== GOT_STATUS_DELETE
) {
1971 err
= (*progress_cb
)(progress_arg
, GOT_STATUS_MERGE
, path
);
1974 err
= got_fileindex_entry_update(ie
, worktree
->root_fd
, path
,
1975 blob
->id
.sha1
, worktree
->base_commit_id
->sha1
, 0);
1979 int is_bad_symlink
= 0;
1980 if (S_ISLNK(te
->mode
)) {
1981 err
= install_symlink(&is_bad_symlink
, worktree
,
1982 ondisk_path
, path
, blob
,
1983 status
== GOT_STATUS_MISSING
, 0,
1984 status
== GOT_STATUS_UNVERSIONED
, 0,
1985 repo
, progress_cb
, progress_arg
);
1987 err
= install_blob(worktree
, ondisk_path
, path
,
1988 te
->mode
, sb
.st_mode
, blob
,
1989 status
== GOT_STATUS_MISSING
, 0, 0,
1990 status
== GOT_STATUS_UNVERSIONED
, repo
,
1991 progress_cb
, progress_arg
);
1997 err
= got_fileindex_entry_update(ie
,
1998 worktree
->root_fd
, path
, blob
->id
.sha1
,
1999 worktree
->base_commit_id
->sha1
, 1);
2001 err
= create_fileindex_entry(&ie
, fileindex
,
2002 worktree
->base_commit_id
, worktree
->root_fd
, path
,
2008 if (is_bad_symlink
) {
2009 got_fileindex_entry_filetype_set(ie
,
2010 GOT_FILEIDX_MODE_BAD_SYMLINK
);
2014 if (fd1
!= -1 && close(fd1
) == -1 && err
== NULL
) {
2015 err
= got_error_from_errno("close");
2018 got_object_blob_close(blob
);
2024 static const struct got_error
*
2025 remove_ondisk_file(const char *root_path
, const char *path
)
2027 const struct got_error
*err
= NULL
;
2028 char *ondisk_path
= NULL
, *parent
= NULL
;
2030 if (asprintf(&ondisk_path
, "%s/%s", root_path
, path
) == -1)
2031 return got_error_from_errno("asprintf");
2033 if (unlink(ondisk_path
) == -1) {
2034 if (errno
!= ENOENT
)
2035 err
= got_error_from_errno2("unlink", ondisk_path
);
2037 size_t root_len
= strlen(root_path
);
2038 err
= got_path_dirname(&parent
, ondisk_path
);
2041 while (got_path_cmp(parent
, root_path
,
2042 strlen(parent
), root_len
) != 0) {
2044 ondisk_path
= parent
;
2046 if (rmdir(ondisk_path
) == -1) {
2047 if (errno
!= ENOTEMPTY
)
2048 err
= got_error_from_errno2("rmdir",
2052 err
= got_path_dirname(&parent
, ondisk_path
);
2063 static const struct got_error
*
2064 delete_blob(struct got_worktree
*worktree
, struct got_fileindex
*fileindex
,
2065 struct got_fileindex_entry
*ie
, struct got_repository
*repo
,
2066 got_worktree_checkout_cb progress_cb
, void *progress_arg
)
2068 const struct got_error
*err
= NULL
;
2069 unsigned char status
;
2073 if (get_staged_status(ie
) != GOT_STATUS_NO_CHANGE
)
2074 return got_error_path(ie
->path
, GOT_ERR_FILE_STAGED
);
2076 if (asprintf(&ondisk_path
, "%s/%s", worktree
->root_path
, ie
->path
)
2078 return got_error_from_errno("asprintf");
2080 err
= get_file_status(&status
, &sb
, ie
, ondisk_path
, -1, NULL
, repo
);
2084 if (S_ISLNK(sb
.st_mode
) && status
!= GOT_STATUS_NO_CHANGE
) {
2085 char ondisk_target
[PATH_MAX
];
2086 ssize_t ondisk_len
= readlink(ondisk_path
, ondisk_target
,
2087 sizeof(ondisk_target
));
2088 if (ondisk_len
== -1) {
2089 err
= got_error_from_errno2("readlink", ondisk_path
);
2092 ondisk_target
[ondisk_len
] = '\0';
2093 err
= install_symlink_conflict(NULL
, worktree
->base_commit_id
,
2094 NULL
, NULL
, /* XXX pass common ancestor info? */
2095 ondisk_target
, ondisk_path
);
2098 err
= (*progress_cb
)(progress_arg
, GOT_STATUS_CONFLICT
,
2103 if (status
== GOT_STATUS_MODIFY
|| status
== GOT_STATUS_CONFLICT
||
2104 status
== GOT_STATUS_ADD
) {
2105 err
= (*progress_cb
)(progress_arg
, GOT_STATUS_MERGE
, ie
->path
);
2109 * Preserve the working file and change the deleted blob's
2110 * entry into a schedule-add entry.
2112 err
= got_fileindex_entry_update(ie
, worktree
->root_fd
,
2113 ie
->path
, NULL
, NULL
, 0);
2115 err
= (*progress_cb
)(progress_arg
, GOT_STATUS_DELETE
, ie
->path
);
2118 if (status
== GOT_STATUS_NO_CHANGE
) {
2119 err
= remove_ondisk_file(worktree
->root_path
, ie
->path
);
2123 got_fileindex_entry_remove(fileindex
, ie
);
2130 struct diff_cb_arg
{
2131 struct got_fileindex
*fileindex
;
2132 struct got_worktree
*worktree
;
2133 struct got_repository
*repo
;
2134 got_worktree_checkout_cb progress_cb
;
2136 got_cancel_cb cancel_cb
;
2140 static const struct got_error
*
2141 diff_old_new(void *arg
, struct got_fileindex_entry
*ie
,
2142 struct got_tree_entry
*te
, const char *parent_path
)
2144 struct diff_cb_arg
*a
= arg
;
2146 if (a
->cancel_cb
&& a
->cancel_cb(a
->cancel_arg
))
2147 return got_error(GOT_ERR_CANCELLED
);
2149 return update_blob(a
->worktree
, a
->fileindex
, ie
, te
,
2150 ie
->path
, a
->repo
, a
->progress_cb
, a
->progress_arg
);
2153 static const struct got_error
*
2154 diff_old(void *arg
, struct got_fileindex_entry
*ie
, const char *parent_path
)
2156 struct diff_cb_arg
*a
= arg
;
2158 if (a
->cancel_cb
&& a
->cancel_cb(a
->cancel_arg
))
2159 return got_error(GOT_ERR_CANCELLED
);
2161 return delete_blob(a
->worktree
, a
->fileindex
, ie
,
2162 a
->repo
, a
->progress_cb
, a
->progress_arg
);
2165 static const struct got_error
*
2166 diff_new(void *arg
, struct got_tree_entry
*te
, const char *parent_path
)
2168 struct diff_cb_arg
*a
= arg
;
2169 const struct got_error
*err
;
2172 if (a
->cancel_cb
&& a
->cancel_cb(a
->cancel_arg
))
2173 return got_error(GOT_ERR_CANCELLED
);
2175 if (got_object_tree_entry_is_submodule(te
))
2178 if (asprintf(&path
, "%s%s%s", parent_path
,
2179 parent_path
[0] ? "/" : "", te
->name
)
2181 return got_error_from_errno("asprintf");
2183 if (S_ISDIR(te
->mode
))
2184 err
= add_dir_on_disk(a
->worktree
, path
);
2186 err
= update_blob(a
->worktree
, a
->fileindex
, NULL
, te
, path
,
2187 a
->repo
, a
->progress_cb
, a
->progress_arg
);
2193 const struct got_error
*
2194 got_worktree_get_uuid(char **uuidstr
, struct got_worktree
*worktree
)
2196 uint32_t uuid_status
;
2198 uuid_to_string(&worktree
->uuid
, uuidstr
, &uuid_status
);
2199 if (uuid_status
!= uuid_s_ok
) {
2201 return got_error_uuid(uuid_status
, "uuid_to_string");
2207 static const struct got_error
*
2208 get_ref_name(char **refname
, struct got_worktree
*worktree
, const char *prefix
)
2210 const struct got_error
*err
= NULL
;
2211 char *uuidstr
= NULL
;
2215 err
= got_worktree_get_uuid(&uuidstr
, worktree
);
2219 if (asprintf(refname
, "%s-%s", prefix
, uuidstr
) == -1) {
2220 err
= got_error_from_errno("asprintf");
2227 const struct got_error
*
2228 got_worktree_get_base_ref_name(char **refname
, struct got_worktree
*worktree
)
2230 return get_ref_name(refname
, worktree
, GOT_WORKTREE_BASE_REF_PREFIX
);
2233 static const struct got_error
*
2234 get_rebase_tmp_ref_name(char **refname
, struct got_worktree
*worktree
)
2236 return get_ref_name(refname
, worktree
,
2237 GOT_WORKTREE_REBASE_TMP_REF_PREFIX
);
2240 static const struct got_error
*
2241 get_newbase_symref_name(char **refname
, struct got_worktree
*worktree
)
2243 return get_ref_name(refname
, worktree
, GOT_WORKTREE_NEWBASE_REF_PREFIX
);
2246 static const struct got_error
*
2247 get_rebase_branch_symref_name(char **refname
, struct got_worktree
*worktree
)
2249 return get_ref_name(refname
, worktree
,
2250 GOT_WORKTREE_REBASE_BRANCH_REF_PREFIX
);
2253 static const struct got_error
*
2254 get_rebase_commit_ref_name(char **refname
, struct got_worktree
*worktree
)
2256 return get_ref_name(refname
, worktree
,
2257 GOT_WORKTREE_REBASE_COMMIT_REF_PREFIX
);
2260 static const struct got_error
*
2261 get_histedit_tmp_ref_name(char **refname
, struct got_worktree
*worktree
)
2263 return get_ref_name(refname
, worktree
,
2264 GOT_WORKTREE_HISTEDIT_TMP_REF_PREFIX
);
2267 static const struct got_error
*
2268 get_histedit_branch_symref_name(char **refname
, struct got_worktree
*worktree
)
2270 return get_ref_name(refname
, worktree
,
2271 GOT_WORKTREE_HISTEDIT_BRANCH_REF_PREFIX
);
2274 static const struct got_error
*
2275 get_histedit_base_commit_ref_name(char **refname
, struct got_worktree
*worktree
)
2277 return get_ref_name(refname
, worktree
,
2278 GOT_WORKTREE_HISTEDIT_BASE_COMMIT_REF_PREFIX
);
2281 static const struct got_error
*
2282 get_histedit_commit_ref_name(char **refname
, struct got_worktree
*worktree
)
2284 return get_ref_name(refname
, worktree
,
2285 GOT_WORKTREE_HISTEDIT_COMMIT_REF_PREFIX
);
2288 const struct got_error
*
2289 got_worktree_get_histedit_script_path(char **path
,
2290 struct got_worktree
*worktree
)
2292 if (asprintf(path
, "%s/%s/%s", worktree
->root_path
,
2293 GOT_WORKTREE_GOT_DIR
, GOT_WORKTREE_HISTEDIT_SCRIPT
) == -1) {
2295 return got_error_from_errno("asprintf");
2300 static const struct got_error
*
2301 get_merge_branch_ref_name(char **refname
, struct got_worktree
*worktree
)
2303 return get_ref_name(refname
, worktree
,
2304 GOT_WORKTREE_MERGE_BRANCH_REF_PREFIX
);
2307 static const struct got_error
*
2308 get_merge_commit_ref_name(char **refname
, struct got_worktree
*worktree
)
2310 return get_ref_name(refname
, worktree
,
2311 GOT_WORKTREE_MERGE_COMMIT_REF_PREFIX
);
2315 * Prevent Git's garbage collector from deleting our base commit by
2316 * setting a reference to our base commit's ID.
2318 static const struct got_error
*
2319 ref_base_commit(struct got_worktree
*worktree
, struct got_repository
*repo
)
2321 const struct got_error
*err
= NULL
;
2322 struct got_reference
*ref
= NULL
;
2325 err
= got_worktree_get_base_ref_name(&refname
, worktree
);
2329 err
= got_ref_alloc(&ref
, refname
, worktree
->base_commit_id
);
2333 err
= got_ref_write(ref
, repo
);
2341 static const struct got_error
*
2342 get_fileindex_path(char **fileindex_path
, struct got_worktree
*worktree
)
2344 const struct got_error
*err
= NULL
;
2346 if (asprintf(fileindex_path
, "%s/%s/%s", worktree
->root_path
,
2347 GOT_WORKTREE_GOT_DIR
, GOT_WORKTREE_FILE_INDEX
) == -1) {
2348 err
= got_error_from_errno("asprintf");
2349 *fileindex_path
= NULL
;
2355 static const struct got_error
*
2356 open_fileindex(struct got_fileindex
**fileindex
, char **fileindex_path
,
2357 struct got_worktree
*worktree
)
2359 const struct got_error
*err
= NULL
;
2362 *fileindex_path
= NULL
;
2363 *fileindex
= got_fileindex_alloc();
2364 if (*fileindex
== NULL
)
2365 return got_error_from_errno("got_fileindex_alloc");
2367 err
= get_fileindex_path(fileindex_path
, worktree
);
2371 index
= fopen(*fileindex_path
, "rbe");
2372 if (index
== NULL
) {
2373 if (errno
!= ENOENT
)
2374 err
= got_error_from_errno2("fopen", *fileindex_path
);
2376 err
= got_fileindex_read(*fileindex
, index
);
2377 if (fclose(index
) == EOF
&& err
== NULL
)
2378 err
= got_error_from_errno("fclose");
2382 free(*fileindex_path
);
2383 *fileindex_path
= NULL
;
2384 got_fileindex_free(*fileindex
);
2390 struct bump_base_commit_id_arg
{
2391 struct got_object_id
*base_commit_id
;
2394 const char *entry_name
;
2395 got_worktree_checkout_cb progress_cb
;
2399 /* Bump base commit ID of all files within an updated part of the work tree. */
2400 static const struct got_error
*
2401 bump_base_commit_id(void *arg
, struct got_fileindex_entry
*ie
)
2403 const struct got_error
*err
;
2404 struct bump_base_commit_id_arg
*a
= arg
;
2406 if (a
->entry_name
) {
2407 if (strcmp(ie
->path
, a
->path
) != 0)
2409 } else if (!got_path_is_child(ie
->path
, a
->path
, a
->path_len
))
2412 if (got_fileindex_entry_was_skipped(ie
))
2415 if (memcmp(ie
->commit_sha1
, a
->base_commit_id
->sha1
,
2416 SHA1_DIGEST_LENGTH
) == 0)
2419 if (a
->progress_cb
) {
2420 err
= (*a
->progress_cb
)(a
->progress_arg
, GOT_STATUS_BUMP_BASE
,
2425 memcpy(ie
->commit_sha1
, a
->base_commit_id
->sha1
, SHA1_DIGEST_LENGTH
);
2429 static const struct got_error
*
2430 bump_base_commit_id_everywhere(struct got_worktree
*worktree
,
2431 struct got_fileindex
*fileindex
,
2432 got_worktree_checkout_cb progress_cb
, void *progress_arg
)
2434 struct bump_base_commit_id_arg bbc_arg
;
2436 bbc_arg
.base_commit_id
= worktree
->base_commit_id
;
2437 bbc_arg
.entry_name
= NULL
;
2439 bbc_arg
.path_len
= 0;
2440 bbc_arg
.progress_cb
= progress_cb
;
2441 bbc_arg
.progress_arg
= progress_arg
;
2443 return got_fileindex_for_each_entry_safe(fileindex
,
2444 bump_base_commit_id
, &bbc_arg
);
2447 static const struct got_error
*
2448 sync_fileindex(struct got_fileindex
*fileindex
, const char *fileindex_path
)
2450 const struct got_error
*err
= NULL
;
2451 char *new_fileindex_path
= NULL
;
2452 FILE *new_index
= NULL
;
2453 struct timespec timeout
;
2455 err
= got_opentemp_named(&new_fileindex_path
, &new_index
,
2460 err
= got_fileindex_write(fileindex
, new_index
);
2464 if (rename(new_fileindex_path
, fileindex_path
) != 0) {
2465 err
= got_error_from_errno3("rename", new_fileindex_path
,
2467 unlink(new_fileindex_path
);
2471 * Sleep for a short amount of time to ensure that files modified after
2472 * this program exits have a different time stamp from the one which
2473 * was recorded in the file index.
2476 timeout
.tv_nsec
= 1;
2477 nanosleep(&timeout
, NULL
);
2481 free(new_fileindex_path
);
2485 static const struct got_error
*
2486 find_tree_entry_for_checkout(int *entry_type
, char **tree_relpath
,
2487 struct got_object_id
**tree_id
, const char *wt_relpath
,
2488 struct got_commit_object
*base_commit
, struct got_worktree
*worktree
,
2489 struct got_repository
*repo
)
2491 const struct got_error
*err
= NULL
;
2492 struct got_object_id
*id
= NULL
;
2493 char *in_repo_path
= NULL
;
2494 int is_root_wt
= got_path_is_root_dir(worktree
->path_prefix
);
2496 *entry_type
= GOT_OBJ_TYPE_ANY
;
2497 *tree_relpath
= NULL
;
2500 if (wt_relpath
[0] == '\0') {
2501 /* Check out all files within the work tree. */
2502 *entry_type
= GOT_OBJ_TYPE_TREE
;
2503 *tree_relpath
= strdup("");
2504 if (*tree_relpath
== NULL
) {
2505 err
= got_error_from_errno("strdup");
2508 err
= got_object_id_by_path(tree_id
, repo
, base_commit
,
2509 worktree
->path_prefix
);
2515 /* Check out a subset of files in the work tree. */
2517 if (asprintf(&in_repo_path
, "%s%s%s", worktree
->path_prefix
,
2518 is_root_wt
? "" : "/", wt_relpath
) == -1) {
2519 err
= got_error_from_errno("asprintf");
2523 err
= got_object_id_by_path(&id
, repo
, base_commit
, in_repo_path
);
2528 in_repo_path
= NULL
;
2530 err
= got_object_get_type(entry_type
, repo
, id
);
2534 if (*entry_type
== GOT_OBJ_TYPE_BLOB
) {
2535 /* Check out a single file. */
2536 if (strchr(wt_relpath
, '/') == NULL
) {
2537 /* Check out a single file in work tree's root dir. */
2538 in_repo_path
= strdup(worktree
->path_prefix
);
2539 if (in_repo_path
== NULL
) {
2540 err
= got_error_from_errno("strdup");
2543 *tree_relpath
= strdup("");
2544 if (*tree_relpath
== NULL
) {
2545 err
= got_error_from_errno("strdup");
2549 /* Check out a single file in a subdirectory. */
2550 err
= got_path_dirname(tree_relpath
, wt_relpath
);
2553 if (asprintf(&in_repo_path
, "%s%s%s",
2554 worktree
->path_prefix
, is_root_wt
? "" : "/",
2555 *tree_relpath
) == -1) {
2556 err
= got_error_from_errno("asprintf");
2560 err
= got_object_id_by_path(tree_id
, repo
,
2561 base_commit
, in_repo_path
);
2563 /* Check out all files within a subdirectory. */
2564 *tree_id
= got_object_id_dup(id
);
2565 if (*tree_id
== NULL
) {
2566 err
= got_error_from_errno("got_object_id_dup");
2569 *tree_relpath
= strdup(wt_relpath
);
2570 if (*tree_relpath
== NULL
) {
2571 err
= got_error_from_errno("strdup");
2579 *entry_type
= GOT_OBJ_TYPE_ANY
;
2580 free(*tree_relpath
);
2581 *tree_relpath
= NULL
;
2588 static const struct got_error
*
2589 checkout_files(struct got_worktree
*worktree
, struct got_fileindex
*fileindex
,
2590 const char *relpath
, struct got_object_id
*tree_id
, const char *entry_name
,
2591 struct got_repository
*repo
, got_worktree_checkout_cb progress_cb
,
2592 void *progress_arg
, got_cancel_cb cancel_cb
, void *cancel_arg
)
2594 const struct got_error
*err
= NULL
;
2595 struct got_commit_object
*commit
= NULL
;
2596 struct got_tree_object
*tree
= NULL
;
2597 struct got_fileindex_diff_tree_cb diff_cb
;
2598 struct diff_cb_arg arg
;
2600 err
= ref_base_commit(worktree
, repo
);
2602 if (!(err
->code
== GOT_ERR_ERRNO
&&
2603 (errno
== EACCES
|| errno
== EROFS
)))
2605 err
= (*progress_cb
)(progress_arg
,
2606 GOT_STATUS_BASE_REF_ERR
, worktree
->root_path
);
2611 err
= got_object_open_as_commit(&commit
, repo
,
2612 worktree
->base_commit_id
);
2616 err
= got_object_open_as_tree(&tree
, repo
, tree_id
);
2621 got_object_tree_find_entry(tree
, entry_name
) == NULL
) {
2622 err
= got_error_path(entry_name
, GOT_ERR_NO_TREE_ENTRY
);
2626 diff_cb
.diff_old_new
= diff_old_new
;
2627 diff_cb
.diff_old
= diff_old
;
2628 diff_cb
.diff_new
= diff_new
;
2629 arg
.fileindex
= fileindex
;
2630 arg
.worktree
= worktree
;
2632 arg
.progress_cb
= progress_cb
;
2633 arg
.progress_arg
= progress_arg
;
2634 arg
.cancel_cb
= cancel_cb
;
2635 arg
.cancel_arg
= cancel_arg
;
2636 err
= got_fileindex_diff_tree(fileindex
, tree
, relpath
,
2637 entry_name
, repo
, &diff_cb
, &arg
);
2640 got_object_tree_close(tree
);
2642 got_object_commit_close(commit
);
2646 const struct got_error
*
2647 got_worktree_checkout_files(struct got_worktree
*worktree
,
2648 struct got_pathlist_head
*paths
, struct got_repository
*repo
,
2649 got_worktree_checkout_cb progress_cb
, void *progress_arg
,
2650 got_cancel_cb cancel_cb
, void *cancel_arg
)
2652 const struct got_error
*err
= NULL
, *sync_err
, *unlockerr
;
2653 struct got_commit_object
*commit
= NULL
;
2654 struct got_tree_object
*tree
= NULL
;
2655 struct got_fileindex
*fileindex
= NULL
;
2656 char *fileindex_path
= NULL
;
2657 struct got_pathlist_entry
*pe
;
2658 struct tree_path_data
{
2659 STAILQ_ENTRY(tree_path_data
) entry
;
2660 struct got_object_id
*tree_id
;
2665 STAILQ_HEAD(tree_paths
, tree_path_data
) tree_paths
;
2667 STAILQ_INIT(&tree_paths
);
2669 err
= lock_worktree(worktree
, LOCK_EX
);
2673 err
= got_object_open_as_commit(&commit
, repo
,
2674 worktree
->base_commit_id
);
2678 /* Map all specified paths to in-repository trees. */
2679 TAILQ_FOREACH(pe
, paths
, entry
) {
2680 tpd
= malloc(sizeof(*tpd
));
2682 err
= got_error_from_errno("malloc");
2686 err
= find_tree_entry_for_checkout(&tpd
->entry_type
,
2687 &tpd
->relpath
, &tpd
->tree_id
, pe
->path
, commit
,
2694 if (tpd
->entry_type
== GOT_OBJ_TYPE_BLOB
) {
2695 err
= got_path_basename(&tpd
->entry_name
, pe
->path
);
2703 tpd
->entry_name
= NULL
;
2705 STAILQ_INSERT_TAIL(&tree_paths
, tpd
, entry
);
2709 * Read the file index.
2710 * Checking out files is supposed to be an idempotent operation.
2711 * If the on-disk file index is incomplete we will try to complete it.
2713 err
= open_fileindex(&fileindex
, &fileindex_path
, worktree
);
2717 tpd
= STAILQ_FIRST(&tree_paths
);
2718 TAILQ_FOREACH(pe
, paths
, entry
) {
2719 struct bump_base_commit_id_arg bbc_arg
;
2721 err
= checkout_files(worktree
, fileindex
, tpd
->relpath
,
2722 tpd
->tree_id
, tpd
->entry_name
, repo
,
2723 progress_cb
, progress_arg
, cancel_cb
, cancel_arg
);
2727 bbc_arg
.base_commit_id
= worktree
->base_commit_id
;
2728 bbc_arg
.entry_name
= tpd
->entry_name
;
2729 bbc_arg
.path
= pe
->path
;
2730 bbc_arg
.path_len
= pe
->path_len
;
2731 bbc_arg
.progress_cb
= progress_cb
;
2732 bbc_arg
.progress_arg
= progress_arg
;
2733 err
= got_fileindex_for_each_entry_safe(fileindex
,
2734 bump_base_commit_id
, &bbc_arg
);
2738 tpd
= STAILQ_NEXT(tpd
, entry
);
2740 sync_err
= sync_fileindex(fileindex
, fileindex_path
);
2741 if (sync_err
&& err
== NULL
)
2744 free(fileindex_path
);
2746 got_object_tree_close(tree
);
2748 got_object_commit_close(commit
);
2750 got_fileindex_free(fileindex
);
2751 while (!STAILQ_EMPTY(&tree_paths
)) {
2752 tpd
= STAILQ_FIRST(&tree_paths
);
2753 STAILQ_REMOVE_HEAD(&tree_paths
, entry
);
2758 unlockerr
= lock_worktree(worktree
, LOCK_SH
);
2759 if (unlockerr
&& err
== NULL
)
2764 struct merge_file_cb_arg
{
2765 struct got_worktree
*worktree
;
2766 struct got_fileindex
*fileindex
;
2767 got_worktree_checkout_cb progress_cb
;
2769 got_cancel_cb cancel_cb
;
2771 const char *label_orig
;
2772 struct got_object_id
*commit_id2
;
2773 int allow_bad_symlinks
;
2776 static const struct got_error
*
2777 merge_file_cb(void *arg
, struct got_blob_object
*blob1
,
2778 struct got_blob_object
*blob2
, FILE *f1
, FILE *f2
,
2779 struct got_object_id
*id1
, struct got_object_id
*id2
,
2780 const char *path1
, const char *path2
,
2781 mode_t mode1
, mode_t mode2
, struct got_repository
*repo
)
2783 static const struct got_error
*err
= NULL
;
2784 struct merge_file_cb_arg
*a
= arg
;
2785 struct got_fileindex_entry
*ie
;
2786 char *ondisk_path
= NULL
;
2788 unsigned char status
;
2789 int local_changes_subsumed
;
2790 FILE *f_orig
= NULL
, *f_deriv
= NULL
, *f_deriv2
= NULL
;
2791 char *id_str
= NULL
, *label_deriv2
= NULL
;
2793 if (blob1
&& blob2
) {
2794 ie
= got_fileindex_entry_get(a
->fileindex
, path2
,
2797 return (*a
->progress_cb
)(a
->progress_arg
,
2798 GOT_STATUS_MISSING
, path2
);
2800 if (asprintf(&ondisk_path
, "%s/%s", a
->worktree
->root_path
,
2802 return got_error_from_errno("asprintf");
2804 err
= get_file_status(&status
, &sb
, ie
, ondisk_path
, -1, NULL
,
2809 if (status
== GOT_STATUS_DELETE
) {
2810 err
= (*a
->progress_cb
)(a
->progress_arg
,
2811 GOT_STATUS_MERGE
, path2
);
2814 if (status
!= GOT_STATUS_NO_CHANGE
&&
2815 status
!= GOT_STATUS_MODIFY
&&
2816 status
!= GOT_STATUS_CONFLICT
&&
2817 status
!= GOT_STATUS_ADD
) {
2818 err
= (*a
->progress_cb
)(a
->progress_arg
, status
, path2
);
2822 if (S_ISLNK(mode1
) && S_ISLNK(mode2
)) {
2824 err
= got_object_blob_read_to_str(&link_target2
, blob2
);
2827 err
= merge_symlink(a
->worktree
, blob1
, ondisk_path
,
2828 path2
, a
->label_orig
, link_target2
, a
->commit_id2
,
2829 repo
, a
->progress_cb
, a
->progress_arg
);
2834 f_orig
= got_opentemp();
2835 if (f_orig
== NULL
) {
2836 err
= got_error_from_errno("got_opentemp");
2839 err
= got_object_blob_dump_to_file(NULL
, NULL
, NULL
,
2844 f_deriv2
= got_opentemp();
2845 if (f_deriv2
== NULL
)
2847 err
= got_object_blob_dump_to_file(NULL
, NULL
, NULL
,
2852 fd
= open(ondisk_path
,
2853 O_RDONLY
| O_NOFOLLOW
| O_CLOEXEC
);
2855 err
= got_error_from_errno2("open",
2859 f_deriv
= fdopen(fd
, "r");
2860 if (f_deriv
== NULL
) {
2861 err
= got_error_from_errno2("fdopen",
2866 err
= got_object_id_str(&id_str
, a
->commit_id2
);
2869 if (asprintf(&label_deriv2
, "%s: commit %s",
2870 GOT_MERGE_LABEL_MERGED
, id_str
) == -1) {
2871 err
= got_error_from_errno("asprintf");
2874 err
= merge_file(&local_changes_subsumed
, a
->worktree
,
2875 f_orig
, f_deriv
, f_deriv2
, ondisk_path
, path2
,
2876 sb
.st_mode
, a
->label_orig
, NULL
, label_deriv2
,
2877 GOT_DIFF_ALGORITHM_PATIENCE
, repo
,
2878 a
->progress_cb
, a
->progress_arg
);
2881 ie
= got_fileindex_entry_get(a
->fileindex
, path1
,
2884 return (*a
->progress_cb
)(a
->progress_arg
,
2885 GOT_STATUS_MISSING
, path1
);
2887 if (asprintf(&ondisk_path
, "%s/%s", a
->worktree
->root_path
,
2889 return got_error_from_errno("asprintf");
2891 err
= get_file_status(&status
, &sb
, ie
, ondisk_path
, -1, NULL
,
2897 case GOT_STATUS_NO_CHANGE
:
2898 err
= (*a
->progress_cb
)(a
->progress_arg
,
2899 GOT_STATUS_DELETE
, path1
);
2902 err
= remove_ondisk_file(a
->worktree
->root_path
, path1
);
2906 got_fileindex_entry_mark_deleted_from_disk(ie
);
2908 case GOT_STATUS_DELETE
:
2909 case GOT_STATUS_MISSING
:
2910 err
= (*a
->progress_cb
)(a
->progress_arg
,
2911 GOT_STATUS_DELETE
, path1
);
2915 got_fileindex_entry_mark_deleted_from_disk(ie
);
2917 case GOT_STATUS_ADD
: {
2918 struct got_object_id
*id
;
2922 * Delete the added file only if its content already
2923 * exists in the repository.
2925 err
= got_object_blob_file_create(&id
, &blob1_f
,
2926 &blob1_size
, path1
);
2929 if (got_object_id_cmp(id
, id1
) == 0) {
2930 err
= (*a
->progress_cb
)(a
->progress_arg
,
2931 GOT_STATUS_DELETE
, path1
);
2934 err
= remove_ondisk_file(a
->worktree
->root_path
,
2939 got_fileindex_entry_remove(a
->fileindex
,
2942 err
= (*a
->progress_cb
)(a
->progress_arg
,
2943 GOT_STATUS_CANNOT_DELETE
, path1
);
2945 if (fclose(blob1_f
) == EOF
&& err
== NULL
)
2946 err
= got_error_from_errno("fclose");
2952 case GOT_STATUS_MODIFY
:
2953 case GOT_STATUS_CONFLICT
:
2954 err
= (*a
->progress_cb
)(a
->progress_arg
,
2955 GOT_STATUS_CANNOT_DELETE
, path1
);
2959 case GOT_STATUS_OBSTRUCTED
:
2960 err
= (*a
->progress_cb
)(a
->progress_arg
, status
, path1
);
2968 if (asprintf(&ondisk_path
, "%s/%s", a
->worktree
->root_path
,
2970 return got_error_from_errno("asprintf");
2971 ie
= got_fileindex_entry_get(a
->fileindex
, path2
,
2974 err
= get_file_status(&status
, &sb
, ie
, ondisk_path
,
2978 if (status
!= GOT_STATUS_NO_CHANGE
&&
2979 status
!= GOT_STATUS_MODIFY
&&
2980 status
!= GOT_STATUS_CONFLICT
&&
2981 status
!= GOT_STATUS_ADD
) {
2982 err
= (*a
->progress_cb
)(a
->progress_arg
,
2986 if (S_ISLNK(mode2
) && S_ISLNK(sb
.st_mode
)) {
2988 err
= got_object_blob_read_to_str(&link_target2
,
2992 err
= merge_symlink(a
->worktree
, NULL
,
2993 ondisk_path
, path2
, a
->label_orig
,
2994 link_target2
, a
->commit_id2
, repo
,
2995 a
->progress_cb
, a
->progress_arg
);
2997 } else if (S_ISREG(sb
.st_mode
)) {
2998 err
= merge_blob(&local_changes_subsumed
,
2999 a
->worktree
, NULL
, ondisk_path
, path2
,
3000 sb
.st_mode
, a
->label_orig
, blob2
,
3001 a
->commit_id2
, repo
, a
->progress_cb
,
3004 err
= got_error_path(ondisk_path
,
3005 GOT_ERR_FILE_OBSTRUCTED
);
3009 if (status
== GOT_STATUS_DELETE
) {
3010 err
= got_fileindex_entry_update(ie
,
3011 a
->worktree
->root_fd
, path2
, blob2
->id
.sha1
,
3012 a
->worktree
->base_commit_id
->sha1
, 0);
3017 int is_bad_symlink
= 0;
3018 sb
.st_mode
= GOT_DEFAULT_FILE_MODE
;
3019 if (S_ISLNK(mode2
)) {
3020 err
= install_symlink(&is_bad_symlink
,
3021 a
->worktree
, ondisk_path
, path2
, blob2
, 0,
3022 0, 1, a
->allow_bad_symlinks
, repo
,
3023 a
->progress_cb
, a
->progress_arg
);
3025 err
= install_blob(a
->worktree
, ondisk_path
, path2
,
3026 mode2
, sb
.st_mode
, blob2
, 0, 0, 0, 1, repo
,
3027 a
->progress_cb
, a
->progress_arg
);
3031 err
= got_fileindex_entry_alloc(&ie
, path2
);
3034 err
= got_fileindex_entry_update(ie
,
3035 a
->worktree
->root_fd
, path2
, NULL
, NULL
, 1);
3037 got_fileindex_entry_free(ie
);
3040 err
= got_fileindex_entry_add(a
->fileindex
, ie
);
3042 got_fileindex_entry_free(ie
);
3045 if (is_bad_symlink
) {
3046 got_fileindex_entry_filetype_set(ie
,
3047 GOT_FILEIDX_MODE_BAD_SYMLINK
);
3052 if (f_orig
&& fclose(f_orig
) == EOF
&& err
== NULL
)
3053 err
= got_error_from_errno("fclose");
3054 if (f_deriv
&& fclose(f_deriv
) == EOF
&& err
== NULL
)
3055 err
= got_error_from_errno("fclose");
3056 if (f_deriv2
&& fclose(f_deriv2
) == EOF
&& err
== NULL
)
3057 err
= got_error_from_errno("fclose");
3064 static const struct got_error
*
3065 check_mixed_commits(void *arg
, struct got_fileindex_entry
*ie
)
3067 struct got_worktree
*worktree
= arg
;
3069 /* Reject merges into a work tree with mixed base commits. */
3070 if (got_fileindex_entry_has_commit(ie
) &&
3071 memcmp(ie
->commit_sha1
, worktree
->base_commit_id
->sha1
,
3072 SHA1_DIGEST_LENGTH
) != 0)
3073 return got_error(GOT_ERR_MIXED_COMMITS
);
3078 struct check_merge_conflicts_arg
{
3079 struct got_worktree
*worktree
;
3080 struct got_fileindex
*fileindex
;
3081 struct got_repository
*repo
;
3084 static const struct got_error
*
3085 check_merge_conflicts(void *arg
, struct got_blob_object
*blob1
,
3086 struct got_blob_object
*blob2
, FILE *f1
, FILE *f2
,
3087 struct got_object_id
*id1
, struct got_object_id
*id2
,
3088 const char *path1
, const char *path2
,
3089 mode_t mode1
, mode_t mode2
, struct got_repository
*repo
)
3091 const struct got_error
*err
= NULL
;
3092 struct check_merge_conflicts_arg
*a
= arg
;
3093 unsigned char status
;
3095 struct got_fileindex_entry
*ie
;
3096 const char *path
= path2
? path2
: path1
;
3097 struct got_object_id
*id
= id2
? id2
: id1
;
3103 ie
= got_fileindex_entry_get(a
->fileindex
, path
, strlen(path
));
3107 if (asprintf(&ondisk_path
, "%s/%s", a
->worktree
->root_path
, ie
->path
)
3109 return got_error_from_errno("asprintf");
3111 /* Reject merges into a work tree with conflicted files. */
3112 err
= get_file_status(&status
, &sb
, ie
, ondisk_path
, -1, NULL
, a
->repo
);
3116 if (status
== GOT_STATUS_CONFLICT
)
3117 return got_error(GOT_ERR_CONFLICTS
);
3122 static const struct got_error
*
3123 merge_files(struct got_worktree
*worktree
, struct got_fileindex
*fileindex
,
3124 const char *fileindex_path
, struct got_object_id
*commit_id1
,
3125 struct got_object_id
*commit_id2
, struct got_repository
*repo
,
3126 got_worktree_checkout_cb progress_cb
, void *progress_arg
,
3127 got_cancel_cb cancel_cb
, void *cancel_arg
)
3129 const struct got_error
*err
= NULL
, *sync_err
;
3130 struct got_object_id
*tree_id1
= NULL
, *tree_id2
= NULL
;
3131 struct got_tree_object
*tree1
= NULL
, *tree2
= NULL
;
3132 struct got_commit_object
*commit1
= NULL
, *commit2
= NULL
;
3133 struct check_merge_conflicts_arg cmc_arg
;
3134 struct merge_file_cb_arg arg
;
3135 char *label_orig
= NULL
;
3136 FILE *f1
= NULL
, *f2
= NULL
;
3137 int fd1
= -1, fd2
= -1;
3140 err
= got_object_open_as_commit(&commit1
, repo
, commit_id1
);
3143 err
= got_object_id_by_path(&tree_id1
, repo
, commit1
,
3144 worktree
->path_prefix
);
3145 if (err
&& err
->code
!= GOT_ERR_NO_TREE_ENTRY
)
3151 err
= got_object_open_as_tree(&tree1
, repo
, tree_id1
);
3155 err
= got_object_id_str(&id_str
, commit_id1
);
3159 if (asprintf(&label_orig
, "%s: commit %s",
3160 GOT_MERGE_LABEL_BASE
, id_str
) == -1) {
3161 err
= got_error_from_errno("asprintf");
3167 f1
= got_opentemp();
3169 err
= got_error_from_errno("got_opentemp");
3174 err
= got_object_open_as_commit(&commit2
, repo
, commit_id2
);
3178 err
= got_object_id_by_path(&tree_id2
, repo
, commit2
,
3179 worktree
->path_prefix
);
3183 err
= got_object_open_as_tree(&tree2
, repo
, tree_id2
);
3187 f2
= got_opentemp();
3189 err
= got_error_from_errno("got_opentemp");
3193 fd1
= got_opentempfd();
3195 err
= got_error_from_errno("got_opentempfd");
3199 fd2
= got_opentempfd();
3201 err
= got_error_from_errno("got_opentempfd");
3205 cmc_arg
.worktree
= worktree
;
3206 cmc_arg
.fileindex
= fileindex
;
3207 cmc_arg
.repo
= repo
;
3208 err
= got_diff_tree(tree1
, tree2
, f1
, f2
, fd1
, fd2
, "", "", repo
,
3209 check_merge_conflicts
, &cmc_arg
, 0);
3213 arg
.worktree
= worktree
;
3214 arg
.fileindex
= fileindex
;
3215 arg
.progress_cb
= progress_cb
;
3216 arg
.progress_arg
= progress_arg
;
3217 arg
.cancel_cb
= cancel_cb
;
3218 arg
.cancel_arg
= cancel_arg
;
3219 arg
.label_orig
= label_orig
;
3220 arg
.commit_id2
= commit_id2
;
3221 arg
.allow_bad_symlinks
= 1; /* preserve bad symlinks across merges */
3222 err
= got_diff_tree(tree1
, tree2
, f1
, f2
, fd1
, fd2
, "", "", repo
,
3223 merge_file_cb
, &arg
, 1);
3224 sync_err
= sync_fileindex(fileindex
, fileindex_path
);
3225 if (sync_err
&& err
== NULL
)
3229 got_object_commit_close(commit1
);
3231 got_object_commit_close(commit2
);
3233 got_object_tree_close(tree1
);
3235 got_object_tree_close(tree2
);
3236 if (f1
&& fclose(f1
) == EOF
&& err
== NULL
)
3237 err
= got_error_from_errno("fclose");
3238 if (f2
&& fclose(f2
) == EOF
&& err
== NULL
)
3239 err
= got_error_from_errno("fclose");
3240 if (fd1
!= -1 && close(fd1
) == -1 && err
== NULL
)
3241 err
= got_error_from_errno("close");
3242 if (fd2
!= -1 && close(fd2
) == -1 && err
== NULL
)
3243 err
= got_error_from_errno("close");
3248 const struct got_error
*
3249 got_worktree_merge_files(struct got_worktree
*worktree
,
3250 struct got_object_id
*commit_id1
, struct got_object_id
*commit_id2
,
3251 struct got_repository
*repo
, got_worktree_checkout_cb progress_cb
,
3252 void *progress_arg
, got_cancel_cb cancel_cb
, void *cancel_arg
)
3254 const struct got_error
*err
, *unlockerr
;
3255 char *fileindex_path
= NULL
;
3256 struct got_fileindex
*fileindex
= NULL
;
3258 err
= lock_worktree(worktree
, LOCK_EX
);
3262 err
= open_fileindex(&fileindex
, &fileindex_path
, worktree
);
3266 err
= got_fileindex_for_each_entry_safe(fileindex
, check_mixed_commits
,
3271 err
= merge_files(worktree
, fileindex
, fileindex_path
, commit_id1
,
3272 commit_id2
, repo
, progress_cb
, progress_arg
,
3273 cancel_cb
, cancel_arg
);
3276 got_fileindex_free(fileindex
);
3277 free(fileindex_path
);
3278 unlockerr
= lock_worktree(worktree
, LOCK_SH
);
3279 if (unlockerr
&& err
== NULL
)
3284 struct diff_dir_cb_arg
{
3285 struct got_fileindex
*fileindex
;
3286 struct got_worktree
*worktree
;
3287 const char *status_path
;
3288 size_t status_path_len
;
3289 struct got_repository
*repo
;
3290 got_worktree_status_cb status_cb
;
3292 got_cancel_cb cancel_cb
;
3294 /* A pathlist containing per-directory pathlists of ignore patterns. */
3295 struct got_pathlist_head
*ignores
;
3296 int report_unchanged
;
3300 static const struct got_error
*
3301 report_file_status(struct got_fileindex_entry
*ie
, const char *abspath
,
3302 int dirfd
, const char *de_name
,
3303 got_worktree_status_cb status_cb
, void *status_arg
,
3304 struct got_repository
*repo
, int report_unchanged
)
3306 const struct got_error
*err
= NULL
;
3307 unsigned char status
= GOT_STATUS_NO_CHANGE
;
3308 unsigned char staged_status
= get_staged_status(ie
);
3310 struct got_object_id blob_id
, commit_id
, staged_blob_id
;
3311 struct got_object_id
*blob_idp
= NULL
, *commit_idp
= NULL
;
3312 struct got_object_id
*staged_blob_idp
= NULL
;
3314 err
= get_file_status(&status
, &sb
, ie
, abspath
, dirfd
, de_name
, repo
);
3318 if (status
== GOT_STATUS_NO_CHANGE
&&
3319 staged_status
== GOT_STATUS_NO_CHANGE
&& !report_unchanged
)
3322 if (got_fileindex_entry_has_blob(ie
)) {
3323 memcpy(blob_id
.sha1
, ie
->blob_sha1
, SHA1_DIGEST_LENGTH
);
3324 blob_idp
= &blob_id
;
3326 if (got_fileindex_entry_has_commit(ie
)) {
3327 memcpy(commit_id
.sha1
, ie
->commit_sha1
, SHA1_DIGEST_LENGTH
);
3328 commit_idp
= &commit_id
;
3330 if (staged_status
== GOT_STATUS_ADD
||
3331 staged_status
== GOT_STATUS_MODIFY
) {
3332 memcpy(staged_blob_id
.sha1
, ie
->staged_blob_sha1
,
3333 SHA1_DIGEST_LENGTH
);
3334 staged_blob_idp
= &staged_blob_id
;
3337 return (*status_cb
)(status_arg
, status
, staged_status
,
3338 ie
->path
, blob_idp
, staged_blob_idp
, commit_idp
, dirfd
, de_name
);
3341 static const struct got_error
*
3342 status_old_new(void *arg
, struct got_fileindex_entry
*ie
,
3343 struct dirent
*de
, const char *parent_path
, int dirfd
)
3345 const struct got_error
*err
= NULL
;
3346 struct diff_dir_cb_arg
*a
= arg
;
3349 if (a
->cancel_cb
&& a
->cancel_cb(a
->cancel_arg
))
3350 return got_error(GOT_ERR_CANCELLED
);
3352 if (got_path_cmp(parent_path
, a
->status_path
,
3353 strlen(parent_path
), a
->status_path_len
) != 0 &&
3354 !got_path_is_child(parent_path
, a
->status_path
, a
->status_path_len
))
3357 if (parent_path
[0]) {
3358 if (asprintf(&abspath
, "%s/%s/%s", a
->worktree
->root_path
,
3359 parent_path
, de
->d_name
) == -1)
3360 return got_error_from_errno("asprintf");
3362 if (asprintf(&abspath
, "%s/%s", a
->worktree
->root_path
,
3364 return got_error_from_errno("asprintf");
3367 err
= report_file_status(ie
, abspath
, dirfd
, de
->d_name
,
3368 a
->status_cb
, a
->status_arg
, a
->repo
, a
->report_unchanged
);
3373 static const struct got_error
*
3374 status_old(void *arg
, struct got_fileindex_entry
*ie
, const char *parent_path
)
3376 struct diff_dir_cb_arg
*a
= arg
;
3377 struct got_object_id blob_id
, commit_id
;
3378 unsigned char status
;
3380 if (a
->cancel_cb
&& a
->cancel_cb(a
->cancel_arg
))
3381 return got_error(GOT_ERR_CANCELLED
);
3383 if (!got_path_is_child(ie
->path
, a
->status_path
, a
->status_path_len
))
3386 memcpy(blob_id
.sha1
, ie
->blob_sha1
, SHA1_DIGEST_LENGTH
);
3387 memcpy(commit_id
.sha1
, ie
->commit_sha1
, SHA1_DIGEST_LENGTH
);
3388 if (got_fileindex_entry_has_file_on_disk(ie
))
3389 status
= GOT_STATUS_MISSING
;
3391 status
= GOT_STATUS_DELETE
;
3392 return (*a
->status_cb
)(a
->status_arg
, status
, get_staged_status(ie
),
3393 ie
->path
, &blob_id
, NULL
, &commit_id
, -1, NULL
);
3397 free_ignorelist(struct got_pathlist_head
*ignorelist
)
3399 struct got_pathlist_entry
*pe
;
3401 TAILQ_FOREACH(pe
, ignorelist
, entry
)
3402 free((char *)pe
->path
);
3403 got_pathlist_free(ignorelist
);
3407 free_ignores(struct got_pathlist_head
*ignores
)
3409 struct got_pathlist_entry
*pe
;
3411 TAILQ_FOREACH(pe
, ignores
, entry
) {
3412 struct got_pathlist_head
*ignorelist
= pe
->data
;
3413 free_ignorelist(ignorelist
);
3414 free((char *)pe
->path
);
3416 got_pathlist_free(ignores
);
3419 static const struct got_error
*
3420 read_ignores(struct got_pathlist_head
*ignores
, const char *path
, FILE *f
)
3422 const struct got_error
*err
= NULL
;
3423 struct got_pathlist_entry
*pe
= NULL
;
3424 struct got_pathlist_head
*ignorelist
;
3425 char *line
= NULL
, *pattern
, *dirpath
= NULL
;
3426 size_t linesize
= 0;
3429 ignorelist
= calloc(1, sizeof(*ignorelist
));
3430 if (ignorelist
== NULL
)
3431 return got_error_from_errno("calloc");
3432 TAILQ_INIT(ignorelist
);
3434 while ((linelen
= getline(&line
, &linesize
, f
)) != -1) {
3435 if (linelen
> 0 && line
[linelen
- 1] == '\n')
3436 line
[linelen
- 1] = '\0';
3438 /* Git's ignores may contain comments. */
3442 /* Git's negated patterns are not (yet?) supported. */
3446 if (asprintf(&pattern
, "%s%s%s", path
, path
[0] ? "/" : "",
3448 err
= got_error_from_errno("asprintf");
3451 err
= got_pathlist_insert(NULL
, ignorelist
, pattern
, NULL
);
3456 err
= got_error_from_errno("getline");
3460 dirpath
= strdup(path
);
3461 if (dirpath
== NULL
) {
3462 err
= got_error_from_errno("strdup");
3465 err
= got_pathlist_insert(&pe
, ignores
, dirpath
, ignorelist
);
3468 if (err
|| pe
== NULL
) {
3470 free_ignorelist(ignorelist
);
3476 match_ignores(struct got_pathlist_head
*ignores
, const char *path
)
3478 struct got_pathlist_entry
*pe
;
3480 /* Handle patterns which match in all directories. */
3481 TAILQ_FOREACH(pe
, ignores
, entry
) {
3482 struct got_pathlist_head
*ignorelist
= pe
->data
;
3483 struct got_pathlist_entry
*pi
;
3485 TAILQ_FOREACH(pi
, ignorelist
, entry
) {
3486 const char *p
, *pattern
= pi
->path
;
3488 if (strncmp(pattern
, "**/", 3) != 0)
3493 if (fnmatch(pattern
, p
,
3494 FNM_PATHNAME
| FNM_LEADING_DIR
)) {
3495 /* Retry in next directory. */
3496 while (*p
&& *p
!= '/')
3508 * The ignores pathlist contains ignore lists from children before
3509 * parents, so we can find the most specific ignorelist by walking
3510 * ignores backwards.
3512 pe
= TAILQ_LAST(ignores
, got_pathlist_head
);
3514 if (got_path_is_child(path
, pe
->path
, pe
->path_len
)) {
3515 struct got_pathlist_head
*ignorelist
= pe
->data
;
3516 struct got_pathlist_entry
*pi
;
3517 TAILQ_FOREACH(pi
, ignorelist
, entry
) {
3518 const char *pattern
= pi
->path
;
3519 int flags
= FNM_LEADING_DIR
;
3520 if (strstr(pattern
, "/**/") == NULL
)
3521 flags
|= FNM_PATHNAME
;
3522 if (fnmatch(pattern
, path
, flags
))
3527 pe
= TAILQ_PREV(pe
, got_pathlist_head
, entry
);
3533 static const struct got_error
*
3534 add_ignores(struct got_pathlist_head
*ignores
, const char *root_path
,
3535 const char *path
, int dirfd
, const char *ignores_filename
)
3537 const struct got_error
*err
= NULL
;
3540 FILE *ignoresfile
= NULL
;
3542 if (asprintf(&ignorespath
, "%s/%s%s%s", root_path
, path
,
3543 path
[0] ? "/" : "", ignores_filename
) == -1)
3544 return got_error_from_errno("asprintf");
3547 fd
= openat(dirfd
, ignores_filename
,
3548 O_RDONLY
| O_NOFOLLOW
| O_CLOEXEC
);
3550 if (errno
!= ENOENT
&& errno
!= EACCES
)
3551 err
= got_error_from_errno2("openat",
3554 ignoresfile
= fdopen(fd
, "r");
3555 if (ignoresfile
== NULL
)
3556 err
= got_error_from_errno2("fdopen",
3560 err
= read_ignores(ignores
, path
, ignoresfile
);
3564 ignoresfile
= fopen(ignorespath
, "re");
3565 if (ignoresfile
== NULL
) {
3566 if (errno
!= ENOENT
&& errno
!= EACCES
)
3567 err
= got_error_from_errno2("fopen",
3570 err
= read_ignores(ignores
, path
, ignoresfile
);
3573 if (ignoresfile
&& fclose(ignoresfile
) == EOF
&& err
== NULL
)
3574 err
= got_error_from_errno2("fclose", path
);
3575 if (fd
!= -1 && close(fd
) == -1 && err
== NULL
)
3576 err
= got_error_from_errno2("close", path
);
3581 static const struct got_error
*
3582 status_new(int *ignore
, void *arg
, struct dirent
*de
, const char *parent_path
,
3585 const struct got_error
*err
= NULL
;
3586 struct diff_dir_cb_arg
*a
= arg
;
3592 if (a
->cancel_cb
&& a
->cancel_cb(a
->cancel_arg
))
3593 return got_error(GOT_ERR_CANCELLED
);
3595 if (parent_path
[0]) {
3596 if (asprintf(&path
, "%s/%s", parent_path
, de
->d_name
) == -1)
3597 return got_error_from_errno("asprintf");
3602 if (de
->d_type
== DT_DIR
) {
3603 if (!a
->no_ignores
&& ignore
!= NULL
&&
3604 match_ignores(a
->ignores
, path
))
3606 } else if (!match_ignores(a
->ignores
, path
) &&
3607 got_path_is_child(path
, a
->status_path
, a
->status_path_len
))
3608 err
= (*a
->status_cb
)(a
->status_arg
, GOT_STATUS_UNVERSIONED
,
3609 GOT_STATUS_NO_CHANGE
, path
, NULL
, NULL
, NULL
, -1, NULL
);
3615 static const struct got_error
*
3616 status_traverse(void *arg
, const char *path
, int dirfd
)
3618 const struct got_error
*err
= NULL
;
3619 struct diff_dir_cb_arg
*a
= arg
;
3624 err
= add_ignores(a
->ignores
, a
->worktree
->root_path
,
3625 path
, dirfd
, ".cvsignore");
3629 err
= add_ignores(a
->ignores
, a
->worktree
->root_path
, path
,
3630 dirfd
, ".gitignore");
3635 static const struct got_error
*
3636 report_single_file_status(const char *path
, const char *ondisk_path
,
3637 struct got_fileindex
*fileindex
, got_worktree_status_cb status_cb
,
3638 void *status_arg
, struct got_repository
*repo
, int report_unchanged
,
3639 struct got_pathlist_head
*ignores
, int no_ignores
)
3641 struct got_fileindex_entry
*ie
;
3644 ie
= got_fileindex_entry_get(fileindex
, path
, strlen(path
));
3646 return report_file_status(ie
, ondisk_path
, -1, NULL
,
3647 status_cb
, status_arg
, repo
, report_unchanged
);
3649 if (lstat(ondisk_path
, &sb
) == -1) {
3650 if (errno
!= ENOENT
)
3651 return got_error_from_errno2("lstat", ondisk_path
);
3652 return (*status_cb
)(status_arg
, GOT_STATUS_NONEXISTENT
,
3653 GOT_STATUS_NO_CHANGE
, path
, NULL
, NULL
, NULL
, -1, NULL
);
3656 if (!no_ignores
&& match_ignores(ignores
, path
))
3659 if (S_ISREG(sb
.st_mode
) || S_ISLNK(sb
.st_mode
))
3660 return (*status_cb
)(status_arg
, GOT_STATUS_UNVERSIONED
,
3661 GOT_STATUS_NO_CHANGE
, path
, NULL
, NULL
, NULL
, -1, NULL
);
3666 static const struct got_error
*
3667 add_ignores_from_parent_paths(struct got_pathlist_head
*ignores
,
3668 const char *root_path
, const char *path
)
3670 const struct got_error
*err
;
3671 char *parent_path
, *next_parent_path
= NULL
;
3673 err
= add_ignores(ignores
, root_path
, "", -1,
3678 err
= add_ignores(ignores
, root_path
, "", -1,
3683 err
= got_path_dirname(&parent_path
, path
);
3685 if (err
->code
== GOT_ERR_BAD_PATH
)
3686 return NULL
; /* cannot traverse parent */
3690 err
= add_ignores(ignores
, root_path
, parent_path
, -1,
3694 err
= add_ignores(ignores
, root_path
, parent_path
, -1,
3698 err
= got_path_dirname(&next_parent_path
, parent_path
);
3700 if (err
->code
== GOT_ERR_BAD_PATH
)
3701 err
= NULL
; /* traversed everything */
3704 if (got_path_is_root_dir(parent_path
))
3707 parent_path
= next_parent_path
;
3708 next_parent_path
= NULL
;
3712 free(next_parent_path
);
3716 static const struct got_error
*
3717 worktree_status(struct got_worktree
*worktree
, const char *path
,
3718 struct got_fileindex
*fileindex
, struct got_repository
*repo
,
3719 got_worktree_status_cb status_cb
, void *status_arg
,
3720 got_cancel_cb cancel_cb
, void *cancel_arg
, int no_ignores
,
3721 int report_unchanged
)
3723 const struct got_error
*err
= NULL
;
3725 struct got_fileindex_diff_dir_cb fdiff_cb
;
3726 struct diff_dir_cb_arg arg
;
3727 char *ondisk_path
= NULL
;
3728 struct got_pathlist_head ignores
;
3729 struct got_fileindex_entry
*ie
;
3731 TAILQ_INIT(&ignores
);
3733 if (asprintf(&ondisk_path
, "%s%s%s",
3734 worktree
->root_path
, path
[0] ? "/" : "", path
) == -1)
3735 return got_error_from_errno("asprintf");
3737 ie
= got_fileindex_entry_get(fileindex
, path
, strlen(path
));
3739 err
= report_single_file_status(path
, ondisk_path
,
3740 fileindex
, status_cb
, status_arg
, repo
,
3741 report_unchanged
, &ignores
, no_ignores
);
3745 fd
= open(ondisk_path
, O_RDONLY
| O_NOFOLLOW
| O_DIRECTORY
| O_CLOEXEC
);
3747 if (errno
!= ENOTDIR
&& errno
!= ENOENT
&& errno
!= EACCES
&&
3748 !got_err_open_nofollow_on_symlink())
3749 err
= got_error_from_errno2("open", ondisk_path
);
3752 err
= add_ignores_from_parent_paths(&ignores
,
3753 worktree
->root_path
, ondisk_path
);
3757 err
= report_single_file_status(path
, ondisk_path
,
3758 fileindex
, status_cb
, status_arg
, repo
,
3759 report_unchanged
, &ignores
, no_ignores
);
3762 fdiff_cb
.diff_old_new
= status_old_new
;
3763 fdiff_cb
.diff_old
= status_old
;
3764 fdiff_cb
.diff_new
= status_new
;
3765 fdiff_cb
.diff_traverse
= status_traverse
;
3766 arg
.fileindex
= fileindex
;
3767 arg
.worktree
= worktree
;
3768 arg
.status_path
= path
;
3769 arg
.status_path_len
= strlen(path
);
3771 arg
.status_cb
= status_cb
;
3772 arg
.status_arg
= status_arg
;
3773 arg
.cancel_cb
= cancel_cb
;
3774 arg
.cancel_arg
= cancel_arg
;
3775 arg
.report_unchanged
= report_unchanged
;
3776 arg
.no_ignores
= no_ignores
;
3778 err
= add_ignores_from_parent_paths(&ignores
,
3779 worktree
->root_path
, path
);
3783 arg
.ignores
= &ignores
;
3784 err
= got_fileindex_diff_dir(fileindex
, fd
,
3785 worktree
->root_path
, path
, repo
, &fdiff_cb
, &arg
);
3788 free_ignores(&ignores
);
3789 if (fd
!= -1 && close(fd
) == -1 && err
== NULL
)
3790 err
= got_error_from_errno("close");
3795 const struct got_error
*
3796 got_worktree_status(struct got_worktree
*worktree
,
3797 struct got_pathlist_head
*paths
, struct got_repository
*repo
,
3798 int no_ignores
, got_worktree_status_cb status_cb
, void *status_arg
,
3799 got_cancel_cb cancel_cb
, void *cancel_arg
)
3801 const struct got_error
*err
= NULL
;
3802 char *fileindex_path
= NULL
;
3803 struct got_fileindex
*fileindex
= NULL
;
3804 struct got_pathlist_entry
*pe
;
3806 err
= open_fileindex(&fileindex
, &fileindex_path
, worktree
);
3810 TAILQ_FOREACH(pe
, paths
, entry
) {
3811 err
= worktree_status(worktree
, pe
->path
, fileindex
, repo
,
3812 status_cb
, status_arg
, cancel_cb
, cancel_arg
,
3817 free(fileindex_path
);
3818 got_fileindex_free(fileindex
);
3822 const struct got_error
*
3823 got_worktree_resolve_path(char **wt_path
, struct got_worktree
*worktree
,
3826 const struct got_error
*err
= NULL
;
3827 char *resolved
= NULL
, *cwd
= NULL
, *path
= NULL
;
3830 char *abspath
= NULL
;
3831 char canonpath
[PATH_MAX
];
3835 cwd
= getcwd(NULL
, 0);
3837 return got_error_from_errno("getcwd");
3839 if (lstat(arg
, &sb
) == -1) {
3840 if (errno
!= ENOENT
) {
3841 err
= got_error_from_errno2("lstat", arg
);
3846 if (S_ISLNK(sb
.st_mode
)) {
3848 * We cannot use realpath(3) with symlinks since we want to
3849 * operate on the symlink itself.
3850 * But we can make the path absolute, assuming it is relative
3851 * to the current working directory, and then canonicalize it.
3853 if (!got_path_is_absolute(arg
)) {
3854 if (asprintf(&abspath
, "%s/%s", cwd
, arg
) == -1) {
3855 err
= got_error_from_errno("asprintf");
3860 err
= got_canonpath(abspath
? abspath
: arg
, canonpath
,
3864 resolved
= strdup(canonpath
);
3865 if (resolved
== NULL
) {
3866 err
= got_error_from_errno("strdup");
3870 resolved
= realpath(arg
, NULL
);
3871 if (resolved
== NULL
) {
3872 if (errno
!= ENOENT
) {
3873 err
= got_error_from_errno2("realpath", arg
);
3876 if (asprintf(&abspath
, "%s/%s", cwd
, arg
) == -1) {
3877 err
= got_error_from_errno("asprintf");
3880 err
= got_canonpath(abspath
, canonpath
,
3884 resolved
= strdup(canonpath
);
3885 if (resolved
== NULL
) {
3886 err
= got_error_from_errno("strdup");
3892 if (strncmp(got_worktree_get_root_path(worktree
), resolved
,
3893 strlen(got_worktree_get_root_path(worktree
)))) {
3894 err
= got_error_path(resolved
, GOT_ERR_BAD_PATH
);
3898 if (strlen(resolved
) > strlen(got_worktree_get_root_path(worktree
))) {
3899 err
= got_path_skip_common_ancestor(&path
,
3900 got_worktree_get_root_path(worktree
), resolved
);
3906 err
= got_error_from_errno("strdup");
3911 /* XXX status walk can't deal with trailing slash! */
3913 while (len
> 0 && path
[len
- 1] == '/') {
3914 path
[len
- 1] = '\0';
3928 struct schedule_addition_args
{
3929 struct got_worktree
*worktree
;
3930 struct got_fileindex
*fileindex
;
3931 got_worktree_checkout_cb progress_cb
;
3933 struct got_repository
*repo
;
3936 static const struct got_error
*
3937 schedule_addition(void *arg
, unsigned char status
, unsigned char staged_status
,
3938 const char *relpath
, struct got_object_id
*blob_id
,
3939 struct got_object_id
*staged_blob_id
, struct got_object_id
*commit_id
,
3940 int dirfd
, const char *de_name
)
3942 struct schedule_addition_args
*a
= arg
;
3943 const struct got_error
*err
= NULL
;
3944 struct got_fileindex_entry
*ie
;
3948 if (asprintf(&ondisk_path
, "%s/%s", a
->worktree
->root_path
,
3950 return got_error_from_errno("asprintf");
3952 ie
= got_fileindex_entry_get(a
->fileindex
, relpath
, strlen(relpath
));
3954 err
= get_file_status(&status
, &sb
, ie
, ondisk_path
, dirfd
,
3958 /* Re-adding an existing entry is a no-op. */
3959 if (status
== GOT_STATUS_ADD
)
3961 err
= got_error_path(relpath
, GOT_ERR_FILE_STATUS
);
3966 if (status
!= GOT_STATUS_UNVERSIONED
) {
3967 if (status
== GOT_STATUS_NONEXISTENT
)
3968 err
= got_error_set_errno(ENOENT
, ondisk_path
);
3970 err
= got_error_path(ondisk_path
, GOT_ERR_FILE_STATUS
);
3974 err
= got_fileindex_entry_alloc(&ie
, relpath
);
3977 err
= got_fileindex_entry_update(ie
, a
->worktree
->root_fd
,
3978 relpath
, NULL
, NULL
, 1);
3980 got_fileindex_entry_free(ie
);
3983 err
= got_fileindex_entry_add(a
->fileindex
, ie
);
3985 got_fileindex_entry_free(ie
);
3992 if (status
== GOT_STATUS_ADD
)
3994 return (*a
->progress_cb
)(a
->progress_arg
, GOT_STATUS_ADD
, relpath
);
3997 const struct got_error
*
3998 got_worktree_schedule_add(struct got_worktree
*worktree
,
3999 struct got_pathlist_head
*paths
,
4000 got_worktree_checkout_cb progress_cb
, void *progress_arg
,
4001 struct got_repository
*repo
, int no_ignores
)
4003 struct got_fileindex
*fileindex
= NULL
;
4004 char *fileindex_path
= NULL
;
4005 const struct got_error
*err
= NULL
, *sync_err
, *unlockerr
;
4006 struct got_pathlist_entry
*pe
;
4007 struct schedule_addition_args saa
;
4009 err
= lock_worktree(worktree
, LOCK_EX
);
4013 err
= open_fileindex(&fileindex
, &fileindex_path
, worktree
);
4017 saa
.worktree
= worktree
;
4018 saa
.fileindex
= fileindex
;
4019 saa
.progress_cb
= progress_cb
;
4020 saa
.progress_arg
= progress_arg
;
4023 TAILQ_FOREACH(pe
, paths
, entry
) {
4024 err
= worktree_status(worktree
, pe
->path
, fileindex
, repo
,
4025 schedule_addition
, &saa
, NULL
, NULL
, no_ignores
, 0);
4029 sync_err
= sync_fileindex(fileindex
, fileindex_path
);
4030 if (sync_err
&& err
== NULL
)
4033 free(fileindex_path
);
4035 got_fileindex_free(fileindex
);
4036 unlockerr
= lock_worktree(worktree
, LOCK_SH
);
4037 if (unlockerr
&& err
== NULL
)
4042 struct schedule_deletion_args
{
4043 struct got_worktree
*worktree
;
4044 struct got_fileindex
*fileindex
;
4045 got_worktree_delete_cb progress_cb
;
4047 struct got_repository
*repo
;
4048 int delete_local_mods
;
4050 int ignore_missing_paths
;
4051 const char *status_codes
;
4054 static const struct got_error
*
4055 schedule_for_deletion(void *arg
, unsigned char status
,
4056 unsigned char staged_status
, const char *relpath
,
4057 struct got_object_id
*blob_id
, struct got_object_id
*staged_blob_id
,
4058 struct got_object_id
*commit_id
, int dirfd
, const char *de_name
)
4060 struct schedule_deletion_args
*a
= arg
;
4061 const struct got_error
*err
= NULL
;
4062 struct got_fileindex_entry
*ie
= NULL
;
4066 if (status
== GOT_STATUS_NONEXISTENT
) {
4067 if (a
->ignore_missing_paths
)
4069 return got_error_set_errno(ENOENT
, relpath
);
4072 ie
= got_fileindex_entry_get(a
->fileindex
, relpath
, strlen(relpath
));
4074 return got_error_path(relpath
, GOT_ERR_FILE_STATUS
);
4076 staged_status
= get_staged_status(ie
);
4077 if (staged_status
!= GOT_STATUS_NO_CHANGE
) {
4078 if (staged_status
== GOT_STATUS_DELETE
)
4080 return got_error_path(relpath
, GOT_ERR_FILE_STAGED
);
4083 if (asprintf(&ondisk_path
, "%s/%s", a
->worktree
->root_path
,
4085 return got_error_from_errno("asprintf");
4087 err
= get_file_status(&status
, &sb
, ie
, ondisk_path
, dirfd
, de_name
,
4092 if (a
->status_codes
) {
4093 size_t ncodes
= strlen(a
->status_codes
);
4095 for (i
= 0; i
< ncodes
; i
++) {
4096 if (status
== a
->status_codes
[i
])
4100 /* Do not delete files in non-matching status. */
4104 if (a
->status_codes
[i
] != GOT_STATUS_MODIFY
&&
4105 a
->status_codes
[i
] != GOT_STATUS_MISSING
) {
4106 static char msg
[64];
4107 snprintf(msg
, sizeof(msg
),
4108 "invalid status code '%c'", a
->status_codes
[i
]);
4109 err
= got_error_msg(GOT_ERR_FILE_STATUS
, msg
);
4114 if (status
!= GOT_STATUS_NO_CHANGE
) {
4115 if (status
== GOT_STATUS_DELETE
)
4117 if (status
== GOT_STATUS_MODIFY
&& !a
->delete_local_mods
) {
4118 err
= got_error_path(relpath
, GOT_ERR_FILE_MODIFIED
);
4121 if (status
== GOT_STATUS_MISSING
&& !a
->ignore_missing_paths
) {
4122 err
= got_error_set_errno(ENOENT
, relpath
);
4125 if (status
!= GOT_STATUS_MODIFY
&&
4126 status
!= GOT_STATUS_MISSING
) {
4127 err
= got_error_path(relpath
, GOT_ERR_FILE_STATUS
);
4132 if (!a
->keep_on_disk
&& status
!= GOT_STATUS_MISSING
) {
4136 if (unlinkat(dirfd
, de_name
, 0) != 0) {
4137 err
= got_error_from_errno2("unlinkat",
4141 } else if (unlink(ondisk_path
) != 0) {
4142 err
= got_error_from_errno2("unlink", ondisk_path
);
4146 root_len
= strlen(a
->worktree
->root_path
);
4149 err
= got_path_dirname(&parent
, ondisk_path
);
4153 ondisk_path
= parent
;
4154 if (rmdir(ondisk_path
) == -1) {
4155 if (errno
!= ENOTEMPTY
)
4156 err
= got_error_from_errno2("rmdir",
4160 } while (got_path_cmp(ondisk_path
, a
->worktree
->root_path
,
4161 strlen(ondisk_path
), root_len
) != 0);
4164 got_fileindex_entry_mark_deleted_from_disk(ie
);
4169 if (status
== GOT_STATUS_DELETE
)
4171 return (*a
->progress_cb
)(a
->progress_arg
, GOT_STATUS_DELETE
,
4172 staged_status
, relpath
);
4175 const struct got_error
*
4176 got_worktree_schedule_delete(struct got_worktree
*worktree
,
4177 struct got_pathlist_head
*paths
, int delete_local_mods
,
4178 const char *status_codes
,
4179 got_worktree_delete_cb progress_cb
, void *progress_arg
,
4180 struct got_repository
*repo
, int keep_on_disk
, int ignore_missing_paths
)
4182 struct got_fileindex
*fileindex
= NULL
;
4183 char *fileindex_path
= NULL
;
4184 const struct got_error
*err
= NULL
, *sync_err
, *unlockerr
;
4185 struct got_pathlist_entry
*pe
;
4186 struct schedule_deletion_args sda
;
4188 err
= lock_worktree(worktree
, LOCK_EX
);
4192 err
= open_fileindex(&fileindex
, &fileindex_path
, worktree
);
4196 sda
.worktree
= worktree
;
4197 sda
.fileindex
= fileindex
;
4198 sda
.progress_cb
= progress_cb
;
4199 sda
.progress_arg
= progress_arg
;
4201 sda
.delete_local_mods
= delete_local_mods
;
4202 sda
.keep_on_disk
= keep_on_disk
;
4203 sda
.ignore_missing_paths
= ignore_missing_paths
;
4204 sda
.status_codes
= status_codes
;
4206 TAILQ_FOREACH(pe
, paths
, entry
) {
4207 err
= worktree_status(worktree
, pe
->path
, fileindex
, repo
,
4208 schedule_for_deletion
, &sda
, NULL
, NULL
, 1, 1);
4212 sync_err
= sync_fileindex(fileindex
, fileindex_path
);
4213 if (sync_err
&& err
== NULL
)
4216 free(fileindex_path
);
4218 got_fileindex_free(fileindex
);
4219 unlockerr
= lock_worktree(worktree
, LOCK_SH
);
4220 if (unlockerr
&& err
== NULL
)
4225 static const struct got_error
*
4226 copy_one_line(FILE *infile
, FILE *outfile
, FILE *rejectfile
)
4228 const struct got_error
*err
= NULL
;
4230 size_t linesize
= 0, n
;
4233 linelen
= getline(&line
, &linesize
, infile
);
4234 if (linelen
== -1) {
4235 if (ferror(infile
)) {
4236 err
= got_error_from_errno("getline");
4242 n
= fwrite(line
, 1, linelen
, outfile
);
4244 err
= got_ferror(outfile
, GOT_ERR_IO
);
4249 n
= fwrite(line
, 1, linelen
, rejectfile
);
4251 err
= got_ferror(outfile
, GOT_ERR_IO
);
4258 static const struct got_error
*
4259 skip_one_line(FILE *f
)
4262 size_t linesize
= 0;
4265 linelen
= getline(&line
, &linesize
, f
);
4266 if (linelen
== -1) {
4268 return got_error_from_errno("getline");
4275 static const struct got_error
*
4276 copy_change(FILE *f1
, FILE *f2
, int *line_cur1
, int *line_cur2
,
4277 int start_old
, int end_old
, int start_new
, int end_new
,
4278 FILE *outfile
, FILE *rejectfile
)
4280 const struct got_error
*err
;
4282 /* Copy old file's lines leading up to patch. */
4283 while (!feof(f1
) && *line_cur1
< start_old
) {
4284 err
= copy_one_line(f1
, outfile
, NULL
);
4289 /* Skip new file's lines leading up to patch. */
4290 while (!feof(f2
) && *line_cur2
< start_new
) {
4292 err
= copy_one_line(f2
, NULL
, rejectfile
);
4294 err
= skip_one_line(f2
);
4299 /* Copy patched lines. */
4300 while (!feof(f2
) && *line_cur2
<= end_new
) {
4301 err
= copy_one_line(f2
, outfile
, NULL
);
4306 /* Skip over old file's replaced lines. */
4307 while (!feof(f1
) && *line_cur1
<= end_old
) {
4309 err
= copy_one_line(f1
, NULL
, rejectfile
);
4311 err
= skip_one_line(f1
);
4320 static const struct got_error
*
4321 copy_remaining_content(FILE *f1
, FILE *f2
, int *line_cur1
, int *line_cur2
,
4322 FILE *outfile
, FILE *rejectfile
)
4324 const struct got_error
*err
;
4327 /* Copy old file's lines until EOF. */
4329 err
= copy_one_line(f1
, outfile
, NULL
);
4336 /* Copy new file's lines until EOF. */
4338 err
= copy_one_line(f2
, NULL
, rejectfile
);
4348 static const struct got_error
*
4349 apply_or_reject_change(int *choice
, int *nchunks_used
,
4350 struct diff_result
*diff_result
, int n
,
4351 const char *relpath
, FILE *f1
, FILE *f2
, int *line_cur1
, int *line_cur2
,
4352 FILE *outfile
, FILE *rejectfile
, int changeno
, int nchanges
,
4353 got_worktree_patch_cb patch_cb
, void *patch_arg
)
4355 const struct got_error
*err
= NULL
;
4356 struct diff_chunk_context cc
= {};
4357 int start_old
, end_old
, start_new
, end_new
;
4359 struct diff_output_unidiff_state
*diff_state
;
4360 struct diff_input_info diff_info
;
4363 *choice
= GOT_PATCH_CHOICE_NONE
;
4365 /* Get changed line numbers without context lines for copy_change(). */
4366 diff_chunk_context_load_change(&cc
, NULL
, diff_result
, n
, 0);
4367 start_old
= cc
.left
.start
;
4368 end_old
= cc
.left
.end
;
4369 start_new
= cc
.right
.start
;
4370 end_new
= cc
.right
.end
;
4372 /* Get the same change with context lines for display. */
4373 memset(&cc
, 0, sizeof(cc
));
4374 diff_chunk_context_load_change(&cc
, nchunks_used
, diff_result
, n
, 3);
4376 memset(&diff_info
, 0, sizeof(diff_info
));
4377 diff_info
.left_path
= relpath
;
4378 diff_info
.right_path
= relpath
;
4380 diff_state
= diff_output_unidiff_state_alloc();
4381 if (diff_state
== NULL
)
4382 return got_error_set_errno(ENOMEM
,
4383 "diff_output_unidiff_state_alloc");
4385 hunkfile
= got_opentemp();
4386 if (hunkfile
== NULL
) {
4387 err
= got_error_from_errno("got_opentemp");
4391 rc
= diff_output_unidiff_chunk(NULL
, hunkfile
, diff_state
, &diff_info
,
4393 if (rc
!= DIFF_RC_OK
) {
4394 err
= got_error_set_errno(rc
, "diff_output_unidiff_chunk");
4398 if (fseek(hunkfile
, 0L, SEEK_SET
) == -1) {
4399 err
= got_ferror(hunkfile
, GOT_ERR_IO
);
4403 err
= (*patch_cb
)(choice
, patch_arg
, GOT_STATUS_MODIFY
, relpath
,
4404 hunkfile
, changeno
, nchanges
);
4409 case GOT_PATCH_CHOICE_YES
:
4410 err
= copy_change(f1
, f2
, line_cur1
, line_cur2
, start_old
,
4411 end_old
, start_new
, end_new
, outfile
, rejectfile
);
4413 case GOT_PATCH_CHOICE_NO
:
4414 err
= copy_change(f1
, f2
, line_cur1
, line_cur2
, start_old
,
4415 end_old
, start_new
, end_new
, rejectfile
, outfile
);
4417 case GOT_PATCH_CHOICE_QUIT
:
4420 err
= got_error(GOT_ERR_PATCH_CHOICE
);
4424 diff_output_unidiff_state_free(diff_state
);
4425 if (hunkfile
&& fclose(hunkfile
) == EOF
&& err
== NULL
)
4426 err
= got_error_from_errno("fclose");
4430 struct revert_file_args
{
4431 struct got_worktree
*worktree
;
4432 struct got_fileindex
*fileindex
;
4433 got_worktree_checkout_cb progress_cb
;
4435 got_worktree_patch_cb patch_cb
;
4437 struct got_repository
*repo
;
4438 int unlink_added_files
;
4441 static const struct got_error
*
4442 create_patched_content(char **path_outfile
, int reverse_patch
,
4443 struct got_object_id
*blob_id
, const char *path2
,
4444 int dirfd2
, const char *de_name2
,
4445 const char *relpath
, struct got_repository
*repo
,
4446 got_worktree_patch_cb patch_cb
, void *patch_arg
)
4448 const struct got_error
*err
, *free_err
;
4449 struct got_blob_object
*blob
= NULL
;
4450 FILE *f1
= NULL
, *f2
= NULL
, *outfile
= NULL
;
4451 int fd
= -1, fd2
= -1;
4452 char link_target
[PATH_MAX
];
4453 ssize_t link_len
= 0;
4454 char *path1
= NULL
, *id_str
= NULL
;
4456 struct got_diffreg_result
*diffreg_result
= NULL
;
4457 int line_cur1
= 1, line_cur2
= 1, have_content
= 0;
4458 int i
= 0, n
= 0, nchunks_used
= 0, nchanges
= 0;
4460 *path_outfile
= NULL
;
4462 err
= got_object_id_str(&id_str
, blob_id
);
4467 fd2
= openat(dirfd2
, de_name2
,
4468 O_RDONLY
| O_NOFOLLOW
| O_CLOEXEC
);
4470 if (!got_err_open_nofollow_on_symlink()) {
4471 err
= got_error_from_errno2("openat", path2
);
4474 link_len
= readlinkat(dirfd2
, de_name2
,
4475 link_target
, sizeof(link_target
));
4476 if (link_len
== -1) {
4477 return got_error_from_errno2("readlinkat",
4480 sb2
.st_mode
= S_IFLNK
;
4481 sb2
.st_size
= link_len
;
4484 fd2
= open(path2
, O_RDONLY
| O_NOFOLLOW
| O_CLOEXEC
);
4486 if (!got_err_open_nofollow_on_symlink()) {
4487 err
= got_error_from_errno2("open", path2
);
4490 link_len
= readlink(path2
, link_target
,
4491 sizeof(link_target
));
4493 return got_error_from_errno2("readlink", path2
);
4494 sb2
.st_mode
= S_IFLNK
;
4495 sb2
.st_size
= link_len
;
4499 if (fstat(fd2
, &sb2
) == -1) {
4500 err
= got_error_from_errno2("fstat", path2
);
4504 f2
= fdopen(fd2
, "r");
4506 err
= got_error_from_errno2("fdopen", path2
);
4512 f2
= got_opentemp();
4514 err
= got_error_from_errno2("got_opentemp", path2
);
4517 n
= fwrite(link_target
, 1, link_len
, f2
);
4518 if (n
!= link_len
) {
4519 err
= got_ferror(f2
, GOT_ERR_IO
);
4522 if (fflush(f2
) == EOF
) {
4523 err
= got_error_from_errno("fflush");
4529 fd
= got_opentempfd();
4531 err
= got_error_from_errno("got_opentempfd");
4535 err
= got_object_open_as_blob(&blob
, repo
, blob_id
, 8192, fd
);
4539 err
= got_opentemp_named(&path1
, &f1
, "got-patched-blob");
4543 err
= got_object_blob_dump_to_file(NULL
, NULL
, NULL
, f1
, blob
);
4547 err
= got_diff_files(&diffreg_result
, f1
, 1, id_str
, f2
, 1, path2
,
4548 3, 0, 1, NULL
, GOT_DIFF_ALGORITHM_MYERS
);
4552 err
= got_opentemp_named(path_outfile
, &outfile
, "got-patched-content");
4556 if (fseek(f1
, 0L, SEEK_SET
) == -1)
4557 return got_ferror(f1
, GOT_ERR_IO
);
4558 if (fseek(f2
, 0L, SEEK_SET
) == -1)
4559 return got_ferror(f2
, GOT_ERR_IO
);
4561 /* Count the number of actual changes in the diff result. */
4562 for (n
= 0; n
< diffreg_result
->result
->chunks
.len
; n
+= nchunks_used
) {
4563 struct diff_chunk_context cc
= {};
4564 diff_chunk_context_load_change(&cc
, &nchunks_used
,
4565 diffreg_result
->result
, n
, 0);
4568 for (n
= 0; n
< diffreg_result
->result
->chunks
.len
; n
+= nchunks_used
) {
4570 err
= apply_or_reject_change(&choice
, &nchunks_used
,
4571 diffreg_result
->result
, n
, relpath
, f1
, f2
,
4572 &line_cur1
, &line_cur2
,
4573 reverse_patch
? NULL
: outfile
,
4574 reverse_patch
? outfile
: NULL
,
4575 ++i
, nchanges
, patch_cb
, patch_arg
);
4578 if (choice
== GOT_PATCH_CHOICE_YES
)
4580 else if (choice
== GOT_PATCH_CHOICE_QUIT
)
4584 err
= copy_remaining_content(f1
, f2
, &line_cur1
, &line_cur2
,
4585 reverse_patch
? NULL
: outfile
,
4586 reverse_patch
? outfile
: NULL
);
4590 if (!S_ISLNK(sb2
.st_mode
)) {
4591 if (fchmod(fileno(outfile
), sb2
.st_mode
) == -1) {
4592 err
= got_error_from_errno2("fchmod", path2
);
4599 if (fd
!= -1 && close(fd
) == -1 && err
== NULL
)
4600 err
= got_error_from_errno("close");
4602 got_object_blob_close(blob
);
4603 free_err
= got_diffreg_result_free(diffreg_result
);
4606 if (f1
&& fclose(f1
) == EOF
&& err
== NULL
)
4607 err
= got_error_from_errno2("fclose", path1
);
4608 if (f2
&& fclose(f2
) == EOF
&& err
== NULL
)
4609 err
= got_error_from_errno2("fclose", path2
);
4610 if (fd2
!= -1 && close(fd2
) == -1 && err
== NULL
)
4611 err
= got_error_from_errno2("close", path2
);
4612 if (outfile
&& fclose(outfile
) == EOF
&& err
== NULL
)
4613 err
= got_error_from_errno2("fclose", *path_outfile
);
4614 if (path1
&& unlink(path1
) == -1 && err
== NULL
)
4615 err
= got_error_from_errno2("unlink", path1
);
4616 if (err
|| !have_content
) {
4617 if (*path_outfile
&& unlink(*path_outfile
) == -1 && err
== NULL
)
4618 err
= got_error_from_errno2("unlink", *path_outfile
);
4619 free(*path_outfile
);
4620 *path_outfile
= NULL
;
4626 static const struct got_error
*
4627 revert_file(void *arg
, unsigned char status
, unsigned char staged_status
,
4628 const char *relpath
, struct got_object_id
*blob_id
,
4629 struct got_object_id
*staged_blob_id
, struct got_object_id
*commit_id
,
4630 int dirfd
, const char *de_name
)
4632 struct revert_file_args
*a
= arg
;
4633 const struct got_error
*err
= NULL
;
4634 char *parent_path
= NULL
;
4635 struct got_fileindex_entry
*ie
;
4636 struct got_commit_object
*base_commit
= NULL
;
4637 struct got_tree_object
*tree
= NULL
;
4638 struct got_object_id
*tree_id
= NULL
;
4639 const struct got_tree_entry
*te
= NULL
;
4640 char *tree_path
= NULL
, *te_name
;
4641 char *ondisk_path
= NULL
, *path_content
= NULL
;
4642 struct got_blob_object
*blob
= NULL
;
4645 /* Reverting a staged deletion is a no-op. */
4646 if (status
== GOT_STATUS_DELETE
&&
4647 staged_status
!= GOT_STATUS_NO_CHANGE
)
4650 if (status
== GOT_STATUS_UNVERSIONED
)
4651 return (*a
->progress_cb
)(a
->progress_arg
,
4652 GOT_STATUS_UNVERSIONED
, relpath
);
4654 ie
= got_fileindex_entry_get(a
->fileindex
, relpath
, strlen(relpath
));
4656 return got_error_path(relpath
, GOT_ERR_BAD_PATH
);
4658 /* Construct in-repository path of tree which contains this blob. */
4659 err
= got_path_dirname(&parent_path
, ie
->path
);
4661 if (err
->code
!= GOT_ERR_BAD_PATH
)
4663 parent_path
= strdup("/");
4664 if (parent_path
== NULL
) {
4665 err
= got_error_from_errno("strdup");
4669 if (got_path_is_root_dir(a
->worktree
->path_prefix
)) {
4670 tree_path
= strdup(parent_path
);
4671 if (tree_path
== NULL
) {
4672 err
= got_error_from_errno("strdup");
4676 if (got_path_is_root_dir(parent_path
)) {
4677 tree_path
= strdup(a
->worktree
->path_prefix
);
4678 if (tree_path
== NULL
) {
4679 err
= got_error_from_errno("strdup");
4683 if (asprintf(&tree_path
, "%s/%s",
4684 a
->worktree
->path_prefix
, parent_path
) == -1) {
4685 err
= got_error_from_errno("asprintf");
4691 err
= got_object_open_as_commit(&base_commit
, a
->repo
,
4692 a
->worktree
->base_commit_id
);
4696 err
= got_object_id_by_path(&tree_id
, a
->repo
, base_commit
, tree_path
);
4698 if (!(err
->code
== GOT_ERR_NO_TREE_ENTRY
&&
4699 (status
== GOT_STATUS_ADD
||
4700 staged_status
== GOT_STATUS_ADD
)))
4703 err
= got_object_open_as_tree(&tree
, a
->repo
, tree_id
);
4707 err
= got_path_basename(&te_name
, ie
->path
);
4711 te
= got_object_tree_find_entry(tree
, te_name
);
4713 if (te
== NULL
&& status
!= GOT_STATUS_ADD
&&
4714 staged_status
!= GOT_STATUS_ADD
) {
4715 err
= got_error_path(ie
->path
, GOT_ERR_NO_TREE_ENTRY
);
4721 case GOT_STATUS_ADD
:
4723 int choice
= GOT_PATCH_CHOICE_NONE
;
4724 err
= (*a
->patch_cb
)(&choice
, a
->patch_arg
,
4725 status
, ie
->path
, NULL
, 1, 1);
4728 if (choice
!= GOT_PATCH_CHOICE_YES
)
4731 err
= (*a
->progress_cb
)(a
->progress_arg
, GOT_STATUS_REVERT
,
4735 got_fileindex_entry_remove(a
->fileindex
, ie
);
4736 if (a
->unlink_added_files
) {
4737 if (asprintf(&ondisk_path
, "%s/%s",
4738 got_worktree_get_root_path(a
->worktree
),
4740 err
= got_error_from_errno("asprintf");
4743 if (unlink(ondisk_path
) == -1) {
4744 err
= got_error_from_errno2("unlink",
4750 case GOT_STATUS_DELETE
:
4752 int choice
= GOT_PATCH_CHOICE_NONE
;
4753 err
= (*a
->patch_cb
)(&choice
, a
->patch_arg
,
4754 status
, ie
->path
, NULL
, 1, 1);
4757 if (choice
!= GOT_PATCH_CHOICE_YES
)
4761 case GOT_STATUS_MODIFY
:
4762 case GOT_STATUS_MODE_CHANGE
:
4763 case GOT_STATUS_CONFLICT
:
4764 case GOT_STATUS_MISSING
: {
4765 struct got_object_id id
;
4766 if (staged_status
== GOT_STATUS_ADD
||
4767 staged_status
== GOT_STATUS_MODIFY
) {
4768 memcpy(id
.sha1
, ie
->staged_blob_sha1
,
4769 SHA1_DIGEST_LENGTH
);
4771 memcpy(id
.sha1
, ie
->blob_sha1
,
4772 SHA1_DIGEST_LENGTH
);
4773 fd
= got_opentempfd();
4775 err
= got_error_from_errno("got_opentempfd");
4779 err
= got_object_open_as_blob(&blob
, a
->repo
, &id
, 8192, fd
);
4783 if (asprintf(&ondisk_path
, "%s/%s",
4784 got_worktree_get_root_path(a
->worktree
), relpath
) == -1) {
4785 err
= got_error_from_errno("asprintf");
4789 if (a
->patch_cb
&& (status
== GOT_STATUS_MODIFY
||
4790 status
== GOT_STATUS_CONFLICT
)) {
4791 int is_bad_symlink
= 0;
4792 err
= create_patched_content(&path_content
, 1, &id
,
4793 ondisk_path
, dirfd
, de_name
, ie
->path
, a
->repo
,
4794 a
->patch_cb
, a
->patch_arg
);
4795 if (err
|| path_content
== NULL
)
4797 if (te
&& S_ISLNK(te
->mode
)) {
4798 if (unlink(path_content
) == -1) {
4799 err
= got_error_from_errno2("unlink",
4803 err
= install_symlink(&is_bad_symlink
,
4804 a
->worktree
, ondisk_path
, ie
->path
,
4805 blob
, 0, 1, 0, 0, a
->repo
,
4806 a
->progress_cb
, a
->progress_arg
);
4808 if (rename(path_content
, ondisk_path
) == -1) {
4809 err
= got_error_from_errno3("rename",
4810 path_content
, ondisk_path
);
4815 int is_bad_symlink
= 0;
4816 if (te
&& S_ISLNK(te
->mode
)) {
4817 err
= install_symlink(&is_bad_symlink
,
4818 a
->worktree
, ondisk_path
, ie
->path
,
4819 blob
, 0, 1, 0, 0, a
->repo
,
4820 a
->progress_cb
, a
->progress_arg
);
4822 err
= install_blob(a
->worktree
, ondisk_path
,
4824 te
? te
->mode
: GOT_DEFAULT_FILE_MODE
,
4825 got_fileindex_perms_to_st(ie
), blob
,
4826 0, 1, 0, 0, a
->repo
,
4827 a
->progress_cb
, a
->progress_arg
);
4831 if (status
== GOT_STATUS_DELETE
||
4832 status
== GOT_STATUS_MODE_CHANGE
) {
4833 err
= got_fileindex_entry_update(ie
,
4834 a
->worktree
->root_fd
, relpath
,
4836 a
->worktree
->base_commit_id
->sha1
, 1);
4840 if (is_bad_symlink
) {
4841 got_fileindex_entry_filetype_set(ie
,
4842 GOT_FILEIDX_MODE_BAD_SYMLINK
);
4855 if (fd
!= -1 && close(fd
) == -1 && err
== NULL
)
4856 err
= got_error_from_errno("close");
4858 got_object_blob_close(blob
);
4860 got_object_tree_close(tree
);
4863 got_object_commit_close(base_commit
);
4867 const struct got_error
*
4868 got_worktree_revert(struct got_worktree
*worktree
,
4869 struct got_pathlist_head
*paths
,
4870 got_worktree_checkout_cb progress_cb
, void *progress_arg
,
4871 got_worktree_patch_cb patch_cb
, void *patch_arg
,
4872 struct got_repository
*repo
)
4874 struct got_fileindex
*fileindex
= NULL
;
4875 char *fileindex_path
= NULL
;
4876 const struct got_error
*err
= NULL
, *unlockerr
= NULL
;
4877 const struct got_error
*sync_err
= NULL
;
4878 struct got_pathlist_entry
*pe
;
4879 struct revert_file_args rfa
;
4881 err
= lock_worktree(worktree
, LOCK_EX
);
4885 err
= open_fileindex(&fileindex
, &fileindex_path
, worktree
);
4889 rfa
.worktree
= worktree
;
4890 rfa
.fileindex
= fileindex
;
4891 rfa
.progress_cb
= progress_cb
;
4892 rfa
.progress_arg
= progress_arg
;
4893 rfa
.patch_cb
= patch_cb
;
4894 rfa
.patch_arg
= patch_arg
;
4896 rfa
.unlink_added_files
= 0;
4897 TAILQ_FOREACH(pe
, paths
, entry
) {
4898 err
= worktree_status(worktree
, pe
->path
, fileindex
, repo
,
4899 revert_file
, &rfa
, NULL
, NULL
, 1, 0);
4903 sync_err
= sync_fileindex(fileindex
, fileindex_path
);
4904 if (sync_err
&& err
== NULL
)
4907 free(fileindex_path
);
4909 got_fileindex_free(fileindex
);
4910 unlockerr
= lock_worktree(worktree
, LOCK_SH
);
4911 if (unlockerr
&& err
== NULL
)
4917 free_commitable(struct got_commitable
*ct
)
4920 free(ct
->in_repo_path
);
4921 free(ct
->ondisk_path
);
4923 free(ct
->base_blob_id
);
4924 free(ct
->staged_blob_id
);
4925 free(ct
->base_commit_id
);
4929 struct collect_commitables_arg
{
4930 struct got_pathlist_head
*commitable_paths
;
4931 struct got_repository
*repo
;
4932 struct got_worktree
*worktree
;
4933 struct got_fileindex
*fileindex
;
4934 int have_staged_files
;
4935 int allow_bad_symlinks
;
4938 static const struct got_error
*
4939 collect_commitables(void *arg
, unsigned char status
,
4940 unsigned char staged_status
, const char *relpath
,
4941 struct got_object_id
*blob_id
, struct got_object_id
*staged_blob_id
,
4942 struct got_object_id
*commit_id
, int dirfd
, const char *de_name
)
4944 struct collect_commitables_arg
*a
= arg
;
4945 const struct got_error
*err
= NULL
;
4946 struct got_commitable
*ct
= NULL
;
4947 struct got_pathlist_entry
*new = NULL
;
4948 char *parent_path
= NULL
, *path
= NULL
;
4951 if (a
->have_staged_files
) {
4952 if (staged_status
!= GOT_STATUS_MODIFY
&&
4953 staged_status
!= GOT_STATUS_ADD
&&
4954 staged_status
!= GOT_STATUS_DELETE
)
4957 if (status
== GOT_STATUS_CONFLICT
)
4958 return got_error(GOT_ERR_COMMIT_CONFLICT
);
4960 if (status
!= GOT_STATUS_MODIFY
&&
4961 status
!= GOT_STATUS_MODE_CHANGE
&&
4962 status
!= GOT_STATUS_ADD
&&
4963 status
!= GOT_STATUS_DELETE
)
4967 if (asprintf(&path
, "/%s", relpath
) == -1) {
4968 err
= got_error_from_errno("asprintf");
4971 if (strcmp(path
, "/") == 0) {
4972 parent_path
= strdup("");
4973 if (parent_path
== NULL
)
4974 return got_error_from_errno("strdup");
4976 err
= got_path_dirname(&parent_path
, path
);
4981 ct
= calloc(1, sizeof(*ct
));
4983 err
= got_error_from_errno("calloc");
4987 if (asprintf(&ct
->ondisk_path
, "%s/%s", a
->worktree
->root_path
,
4989 err
= got_error_from_errno("asprintf");
4993 if (staged_status
== GOT_STATUS_ADD
||
4994 staged_status
== GOT_STATUS_MODIFY
) {
4995 struct got_fileindex_entry
*ie
;
4996 ie
= got_fileindex_entry_get(a
->fileindex
, path
, strlen(path
));
4997 switch (got_fileindex_entry_staged_filetype_get(ie
)) {
4998 case GOT_FILEIDX_MODE_REGULAR_FILE
:
4999 case GOT_FILEIDX_MODE_BAD_SYMLINK
:
5002 case GOT_FILEIDX_MODE_SYMLINK
:
5006 err
= got_error_path(path
, GOT_ERR_BAD_FILETYPE
);
5009 ct
->mode
|= got_fileindex_entry_perms_get(ie
);
5010 } else if (status
!= GOT_STATUS_DELETE
&&
5011 staged_status
!= GOT_STATUS_DELETE
) {
5013 if (fstatat(dirfd
, de_name
, &sb
,
5014 AT_SYMLINK_NOFOLLOW
) == -1) {
5015 err
= got_error_from_errno2("fstatat",
5019 } else if (lstat(ct
->ondisk_path
, &sb
) == -1) {
5020 err
= got_error_from_errno2("lstat", ct
->ondisk_path
);
5023 ct
->mode
= sb
.st_mode
;
5026 if (asprintf(&ct
->in_repo_path
, "%s%s%s", a
->worktree
->path_prefix
,
5027 got_path_is_root_dir(a
->worktree
->path_prefix
) ? "" : "/",
5029 err
= got_error_from_errno("asprintf");
5033 if (S_ISLNK(ct
->mode
) && staged_status
== GOT_STATUS_NO_CHANGE
&&
5034 status
== GOT_STATUS_ADD
&& !a
->allow_bad_symlinks
) {
5036 char target_path
[PATH_MAX
];
5038 target_len
= readlink(ct
->ondisk_path
, target_path
,
5039 sizeof(target_path
));
5040 if (target_len
== -1) {
5041 err
= got_error_from_errno2("readlink",
5045 err
= is_bad_symlink_target(&is_bad_symlink
, target_path
,
5046 target_len
, ct
->ondisk_path
, a
->worktree
->root_path
);
5049 if (is_bad_symlink
) {
5050 err
= got_error_path(ct
->ondisk_path
,
5051 GOT_ERR_BAD_SYMLINK
);
5057 ct
->status
= status
;
5058 ct
->staged_status
= staged_status
;
5059 ct
->blob_id
= NULL
; /* will be filled in when blob gets created */
5060 if (ct
->status
!= GOT_STATUS_ADD
&&
5061 ct
->staged_status
!= GOT_STATUS_ADD
) {
5062 ct
->base_blob_id
= got_object_id_dup(blob_id
);
5063 if (ct
->base_blob_id
== NULL
) {
5064 err
= got_error_from_errno("got_object_id_dup");
5067 ct
->base_commit_id
= got_object_id_dup(commit_id
);
5068 if (ct
->base_commit_id
== NULL
) {
5069 err
= got_error_from_errno("got_object_id_dup");
5073 if (ct
->staged_status
== GOT_STATUS_ADD
||
5074 ct
->staged_status
== GOT_STATUS_MODIFY
) {
5075 ct
->staged_blob_id
= got_object_id_dup(staged_blob_id
);
5076 if (ct
->staged_blob_id
== NULL
) {
5077 err
= got_error_from_errno("got_object_id_dup");
5081 ct
->path
= strdup(path
);
5082 if (ct
->path
== NULL
) {
5083 err
= got_error_from_errno("strdup");
5086 err
= got_pathlist_insert(&new, a
->commitable_paths
, ct
->path
, ct
);
5088 if (ct
&& (err
|| new == NULL
))
5089 free_commitable(ct
);
5095 static const struct got_error
*write_tree(struct got_object_id
**, int *,
5096 struct got_tree_object
*, const char *, struct got_pathlist_head
*,
5097 got_worktree_status_cb status_cb
, void *status_arg
,
5098 struct got_repository
*);
5100 static const struct got_error
*
5101 write_subtree(struct got_object_id
**new_subtree_id
, int *nentries
,
5102 struct got_tree_entry
*te
, const char *parent_path
,
5103 struct got_pathlist_head
*commitable_paths
,
5104 got_worktree_status_cb status_cb
, void *status_arg
,
5105 struct got_repository
*repo
)
5107 const struct got_error
*err
= NULL
;
5108 struct got_tree_object
*subtree
;
5111 if (asprintf(&subpath
, "%s%s%s", parent_path
,
5112 got_path_is_root_dir(parent_path
) ? "" : "/", te
->name
) == -1)
5113 return got_error_from_errno("asprintf");
5115 err
= got_object_open_as_tree(&subtree
, repo
, &te
->id
);
5119 err
= write_tree(new_subtree_id
, nentries
, subtree
, subpath
,
5120 commitable_paths
, status_cb
, status_arg
, repo
);
5121 got_object_tree_close(subtree
);
5126 static const struct got_error
*
5127 match_ct_parent_path(int *match
, struct got_commitable
*ct
, const char *path
)
5129 const struct got_error
*err
= NULL
;
5130 char *ct_parent_path
= NULL
;
5134 if (strchr(ct
->in_repo_path
, '/') == NULL
) {
5135 *match
= got_path_is_root_dir(path
);
5139 err
= got_path_dirname(&ct_parent_path
, ct
->in_repo_path
);
5142 *match
= (strcmp(path
, ct_parent_path
) == 0);
5143 free(ct_parent_path
);
5148 get_ct_file_mode(struct got_commitable
*ct
)
5150 if (S_ISLNK(ct
->mode
))
5153 return S_IFREG
| (ct
->mode
& ((S_IRWXU
| S_IRWXG
| S_IRWXO
)));
5156 static const struct got_error
*
5157 alloc_modified_blob_tree_entry(struct got_tree_entry
**new_te
,
5158 struct got_tree_entry
*te
, struct got_commitable
*ct
)
5160 const struct got_error
*err
= NULL
;
5164 err
= got_object_tree_entry_dup(new_te
, te
);
5168 (*new_te
)->mode
= get_ct_file_mode(ct
);
5170 if (ct
->staged_status
== GOT_STATUS_MODIFY
)
5171 memcpy(&(*new_te
)->id
, ct
->staged_blob_id
,
5172 sizeof((*new_te
)->id
));
5174 memcpy(&(*new_te
)->id
, ct
->blob_id
, sizeof((*new_te
)->id
));
5176 if (err
&& *new_te
) {
5183 static const struct got_error
*
5184 alloc_added_blob_tree_entry(struct got_tree_entry
**new_te
,
5185 struct got_commitable
*ct
)
5187 const struct got_error
*err
= NULL
;
5188 char *ct_name
= NULL
;
5192 *new_te
= calloc(1, sizeof(**new_te
));
5193 if (*new_te
== NULL
)
5194 return got_error_from_errno("calloc");
5196 err
= got_path_basename(&ct_name
, ct
->path
);
5199 if (strlcpy((*new_te
)->name
, ct_name
, sizeof((*new_te
)->name
)) >=
5200 sizeof((*new_te
)->name
)) {
5201 err
= got_error(GOT_ERR_NO_SPACE
);
5205 (*new_te
)->mode
= get_ct_file_mode(ct
);
5207 if (ct
->staged_status
== GOT_STATUS_ADD
)
5208 memcpy(&(*new_te
)->id
, ct
->staged_blob_id
,
5209 sizeof((*new_te
)->id
));
5211 memcpy(&(*new_te
)->id
, ct
->blob_id
, sizeof((*new_te
)->id
));
5214 if (err
&& *new_te
) {
5221 static const struct got_error
*
5222 insert_tree_entry(struct got_tree_entry
*new_te
,
5223 struct got_pathlist_head
*paths
)
5225 const struct got_error
*err
= NULL
;
5226 struct got_pathlist_entry
*new_pe
;
5228 err
= got_pathlist_insert(&new_pe
, paths
, new_te
->name
, new_te
);
5232 return got_error(GOT_ERR_TREE_DUP_ENTRY
);
5236 static const struct got_error
*
5237 report_ct_status(struct got_commitable
*ct
,
5238 got_worktree_status_cb status_cb
, void *status_arg
)
5240 const char *ct_path
= ct
->path
;
5241 unsigned char status
;
5243 if (status_cb
== NULL
) /* no commit progress output desired */
5246 while (ct_path
[0] == '/')
5249 if (ct
->staged_status
!= GOT_STATUS_NO_CHANGE
)
5250 status
= ct
->staged_status
;
5252 status
= ct
->status
;
5254 return (*status_cb
)(status_arg
, status
, GOT_STATUS_NO_CHANGE
,
5255 ct_path
, ct
->blob_id
, NULL
, NULL
, -1, NULL
);
5258 static const struct got_error
*
5259 match_modified_subtree(int *modified
, struct got_tree_entry
*te
,
5260 const char *base_tree_path
, struct got_pathlist_head
*commitable_paths
)
5262 const struct got_error
*err
= NULL
;
5263 struct got_pathlist_entry
*pe
;
5268 if (asprintf(&te_path
, "%s%s%s", base_tree_path
,
5269 got_path_is_root_dir(base_tree_path
) ? "" : "/",
5271 return got_error_from_errno("asprintf");
5273 TAILQ_FOREACH(pe
, commitable_paths
, entry
) {
5274 struct got_commitable
*ct
= pe
->data
;
5275 *modified
= got_path_is_child(ct
->in_repo_path
, te_path
,
5285 static const struct got_error
*
5286 match_deleted_or_modified_ct(struct got_commitable
**ctp
,
5287 struct got_tree_entry
*te
, const char *base_tree_path
,
5288 struct got_pathlist_head
*commitable_paths
)
5290 const struct got_error
*err
= NULL
;
5291 struct got_pathlist_entry
*pe
;
5295 TAILQ_FOREACH(pe
, commitable_paths
, entry
) {
5296 struct got_commitable
*ct
= pe
->data
;
5297 char *ct_name
= NULL
;
5300 if (ct
->staged_status
== GOT_STATUS_NO_CHANGE
) {
5301 if (ct
->status
!= GOT_STATUS_MODIFY
&&
5302 ct
->status
!= GOT_STATUS_MODE_CHANGE
&&
5303 ct
->status
!= GOT_STATUS_DELETE
)
5306 if (ct
->staged_status
!= GOT_STATUS_MODIFY
&&
5307 ct
->staged_status
!= GOT_STATUS_DELETE
)
5311 if (got_object_id_cmp(ct
->base_blob_id
, &te
->id
) != 0)
5314 err
= match_ct_parent_path(&path_matches
, ct
, base_tree_path
);
5320 err
= got_path_basename(&ct_name
, pe
->path
);
5324 if (strcmp(te
->name
, ct_name
) != 0) {
5337 static const struct got_error
*
5338 make_subtree_for_added_blob(struct got_tree_entry
**new_tep
,
5339 const char *child_path
, const char *path_base_tree
,
5340 struct got_pathlist_head
*commitable_paths
,
5341 got_worktree_status_cb status_cb
, void *status_arg
,
5342 struct got_repository
*repo
)
5344 const struct got_error
*err
= NULL
;
5345 struct got_tree_entry
*new_te
;
5347 struct got_object_id
*id
= NULL
;
5352 if (asprintf(&subtree_path
, "%s%s%s", path_base_tree
,
5353 got_path_is_root_dir(path_base_tree
) ? "" : "/",
5355 return got_error_from_errno("asprintf");
5357 new_te
= calloc(1, sizeof(*new_te
));
5359 return got_error_from_errno("calloc");
5360 new_te
->mode
= S_IFDIR
;
5362 if (strlcpy(new_te
->name
, child_path
, sizeof(new_te
->name
)) >=
5363 sizeof(new_te
->name
)) {
5364 err
= got_error(GOT_ERR_NO_SPACE
);
5367 err
= write_tree(&id
, &nentries
, NULL
, subtree_path
,
5368 commitable_paths
, status_cb
, status_arg
, repo
);
5373 memcpy(&new_te
->id
, id
, sizeof(new_te
->id
));
5382 static const struct got_error
*
5383 write_tree(struct got_object_id
**new_tree_id
, int *nentries
,
5384 struct got_tree_object
*base_tree
, const char *path_base_tree
,
5385 struct got_pathlist_head
*commitable_paths
,
5386 got_worktree_status_cb status_cb
, void *status_arg
,
5387 struct got_repository
*repo
)
5389 const struct got_error
*err
= NULL
;
5390 struct got_pathlist_head paths
;
5391 struct got_tree_entry
*te
, *new_te
= NULL
;
5392 struct got_pathlist_entry
*pe
;
5397 /* Insert, and recurse into, newly added entries first. */
5398 TAILQ_FOREACH(pe
, commitable_paths
, entry
) {
5399 struct got_commitable
*ct
= pe
->data
;
5400 char *child_path
= NULL
, *slash
;
5402 if ((ct
->status
!= GOT_STATUS_ADD
&&
5403 ct
->staged_status
!= GOT_STATUS_ADD
) ||
5404 (ct
->flags
& GOT_COMMITABLE_ADDED
))
5407 if (!got_path_is_child(ct
->in_repo_path
, path_base_tree
,
5408 strlen(path_base_tree
)))
5411 err
= got_path_skip_common_ancestor(&child_path
, path_base_tree
,
5416 slash
= strchr(child_path
, '/');
5417 if (slash
== NULL
) {
5418 err
= alloc_added_blob_tree_entry(&new_te
, ct
);
5421 err
= report_ct_status(ct
, status_cb
, status_arg
);
5424 ct
->flags
|= GOT_COMMITABLE_ADDED
;
5425 err
= insert_tree_entry(new_te
, &paths
);
5430 *slash
= '\0'; /* trim trailing path components */
5431 if (base_tree
== NULL
||
5432 got_object_tree_find_entry(base_tree
, child_path
)
5434 err
= make_subtree_for_added_blob(&new_te
,
5435 child_path
, path_base_tree
,
5436 commitable_paths
, status_cb
, status_arg
,
5440 err
= insert_tree_entry(new_te
, &paths
);
5449 int i
, nbase_entries
;
5450 /* Handle modified and deleted entries. */
5451 nbase_entries
= got_object_tree_get_nentries(base_tree
);
5452 for (i
= 0; i
< nbase_entries
; i
++) {
5453 struct got_commitable
*ct
= NULL
;
5455 te
= got_object_tree_get_entry(base_tree
, i
);
5456 if (got_object_tree_entry_is_submodule(te
)) {
5457 /* Entry is a submodule; just copy it. */
5458 err
= got_object_tree_entry_dup(&new_te
, te
);
5461 err
= insert_tree_entry(new_te
, &paths
);
5468 if (S_ISDIR(te
->mode
)) {
5470 err
= got_object_tree_entry_dup(&new_te
, te
);
5473 err
= match_modified_subtree(&modified
, te
,
5474 path_base_tree
, commitable_paths
);
5477 /* Avoid recursion into unmodified subtrees. */
5479 struct got_object_id
*new_id
;
5481 err
= write_subtree(&new_id
,
5483 path_base_tree
, commitable_paths
,
5484 status_cb
, status_arg
, repo
);
5487 if (nsubentries
== 0) {
5488 /* All entries were deleted. */
5492 memcpy(&new_te
->id
, new_id
,
5493 sizeof(new_te
->id
));
5496 err
= insert_tree_entry(new_te
, &paths
);
5503 err
= match_deleted_or_modified_ct(&ct
, te
,
5504 path_base_tree
, commitable_paths
);
5508 /* NB: Deleted entries get dropped here. */
5509 if (ct
->status
== GOT_STATUS_MODIFY
||
5510 ct
->status
== GOT_STATUS_MODE_CHANGE
||
5511 ct
->staged_status
== GOT_STATUS_MODIFY
) {
5512 err
= alloc_modified_blob_tree_entry(
5516 err
= insert_tree_entry(new_te
, &paths
);
5521 err
= report_ct_status(ct
, status_cb
,
5526 /* Entry is unchanged; just copy it. */
5527 err
= got_object_tree_entry_dup(&new_te
, te
);
5530 err
= insert_tree_entry(new_te
, &paths
);
5538 /* Write new list of entries; deleted entries have been dropped. */
5539 err
= got_object_tree_create(new_tree_id
, &paths
, *nentries
, repo
);
5541 got_pathlist_free(&paths
);
5545 static const struct got_error
*
5546 update_fileindex_after_commit(struct got_worktree
*worktree
,
5547 struct got_pathlist_head
*commitable_paths
,
5548 struct got_object_id
*new_base_commit_id
,
5549 struct got_fileindex
*fileindex
, int have_staged_files
)
5551 const struct got_error
*err
= NULL
;
5552 struct got_pathlist_entry
*pe
;
5553 char *relpath
= NULL
;
5555 TAILQ_FOREACH(pe
, commitable_paths
, entry
) {
5556 struct got_fileindex_entry
*ie
;
5557 struct got_commitable
*ct
= pe
->data
;
5559 ie
= got_fileindex_entry_get(fileindex
, pe
->path
, pe
->path_len
);
5561 err
= got_path_skip_common_ancestor(&relpath
,
5562 worktree
->root_path
, ct
->ondisk_path
);
5567 if (ct
->status
== GOT_STATUS_DELETE
||
5568 ct
->staged_status
== GOT_STATUS_DELETE
) {
5569 got_fileindex_entry_remove(fileindex
, ie
);
5570 } else if (ct
->staged_status
== GOT_STATUS_ADD
||
5571 ct
->staged_status
== GOT_STATUS_MODIFY
) {
5572 got_fileindex_entry_stage_set(ie
,
5573 GOT_FILEIDX_STAGE_NONE
);
5574 got_fileindex_entry_staged_filetype_set(ie
, 0);
5576 err
= got_fileindex_entry_update(ie
,
5577 worktree
->root_fd
, relpath
,
5578 ct
->staged_blob_id
->sha1
,
5579 new_base_commit_id
->sha1
,
5580 !have_staged_files
);
5582 err
= got_fileindex_entry_update(ie
,
5583 worktree
->root_fd
, relpath
,
5585 new_base_commit_id
->sha1
,
5586 !have_staged_files
);
5588 err
= got_fileindex_entry_alloc(&ie
, pe
->path
);
5591 err
= got_fileindex_entry_update(ie
,
5592 worktree
->root_fd
, relpath
, ct
->blob_id
->sha1
,
5593 new_base_commit_id
->sha1
, 1);
5595 got_fileindex_entry_free(ie
);
5598 err
= got_fileindex_entry_add(fileindex
, ie
);
5600 got_fileindex_entry_free(ie
);
5613 static const struct got_error
*
5614 check_out_of_date(const char *in_repo_path
, unsigned char status
,
5615 unsigned char staged_status
, struct got_object_id
*base_blob_id
,
5616 struct got_object_id
*base_commit_id
,
5617 struct got_object_id
*head_commit_id
, struct got_repository
*repo
,
5620 const struct got_error
*err
= NULL
;
5621 struct got_commit_object
*commit
= NULL
;
5622 struct got_object_id
*id
= NULL
;
5624 if (status
!= GOT_STATUS_ADD
&& staged_status
!= GOT_STATUS_ADD
) {
5625 /* Trivial case: base commit == head commit */
5626 if (got_object_id_cmp(base_commit_id
, head_commit_id
) == 0)
5629 * Ensure file content which local changes were based
5630 * on matches file content in the branch head.
5632 err
= got_object_open_as_commit(&commit
, repo
, head_commit_id
);
5635 err
= got_object_id_by_path(&id
, repo
, commit
, in_repo_path
);
5637 if (err
->code
== GOT_ERR_NO_TREE_ENTRY
)
5638 err
= got_error(ood_errcode
);
5640 } else if (got_object_id_cmp(id
, base_blob_id
) != 0)
5641 err
= got_error(ood_errcode
);
5643 /* Require that added files don't exist in the branch head. */
5644 err
= got_object_open_as_commit(&commit
, repo
, head_commit_id
);
5647 err
= got_object_id_by_path(&id
, repo
, commit
, in_repo_path
);
5648 if (err
&& err
->code
!= GOT_ERR_NO_TREE_ENTRY
)
5650 err
= id
? got_error(ood_errcode
) : NULL
;
5655 got_object_commit_close(commit
);
5659 static const struct got_error
*
5660 commit_worktree(struct got_object_id
**new_commit_id
,
5661 struct got_pathlist_head
*commitable_paths
,
5662 struct got_object_id
*head_commit_id
,
5663 struct got_object_id
*parent_id2
,
5664 struct got_worktree
*worktree
,
5665 const char *author
, const char *committer
,
5666 got_worktree_commit_msg_cb commit_msg_cb
, void *commit_arg
,
5667 got_worktree_status_cb status_cb
, void *status_arg
,
5668 struct got_repository
*repo
)
5670 const struct got_error
*err
= NULL
, *unlockerr
= NULL
;
5671 struct got_pathlist_entry
*pe
;
5672 const char *head_ref_name
= NULL
;
5673 struct got_commit_object
*head_commit
= NULL
;
5674 struct got_reference
*head_ref2
= NULL
;
5675 struct got_object_id
*head_commit_id2
= NULL
;
5676 struct got_tree_object
*head_tree
= NULL
;
5677 struct got_object_id
*new_tree_id
= NULL
;
5678 int nentries
, nparents
= 0;
5679 struct got_object_id_queue parent_ids
;
5680 struct got_object_qid
*pid
= NULL
;
5681 char *logmsg
= NULL
;
5683 *new_commit_id
= NULL
;
5685 STAILQ_INIT(&parent_ids
);
5687 err
= got_object_open_as_commit(&head_commit
, repo
, head_commit_id
);
5691 err
= got_object_open_as_tree(&head_tree
, repo
, head_commit
->tree_id
);
5695 if (commit_msg_cb
!= NULL
) {
5696 err
= commit_msg_cb(commitable_paths
, &logmsg
, commit_arg
);
5701 if (logmsg
== NULL
|| strlen(logmsg
) == 0) {
5702 err
= got_error(GOT_ERR_COMMIT_MSG_EMPTY
);
5706 /* Create blobs from added and modified files and record their IDs. */
5707 TAILQ_FOREACH(pe
, commitable_paths
, entry
) {
5708 struct got_commitable
*ct
= pe
->data
;
5711 /* Blobs for staged files already exist. */
5712 if (ct
->staged_status
== GOT_STATUS_ADD
||
5713 ct
->staged_status
== GOT_STATUS_MODIFY
)
5716 if (ct
->status
!= GOT_STATUS_ADD
&&
5717 ct
->status
!= GOT_STATUS_MODIFY
&&
5718 ct
->status
!= GOT_STATUS_MODE_CHANGE
)
5721 if (asprintf(&ondisk_path
, "%s/%s",
5722 worktree
->root_path
, pe
->path
) == -1) {
5723 err
= got_error_from_errno("asprintf");
5726 err
= got_object_blob_create(&ct
->blob_id
, ondisk_path
, repo
);
5732 /* Recursively write new tree objects. */
5733 err
= write_tree(&new_tree_id
, &nentries
, head_tree
, "/",
5734 commitable_paths
, status_cb
, status_arg
, repo
);
5738 err
= got_object_qid_alloc(&pid
, worktree
->base_commit_id
);
5741 STAILQ_INSERT_TAIL(&parent_ids
, pid
, entry
);
5744 err
= got_object_qid_alloc(&pid
, parent_id2
);
5747 STAILQ_INSERT_TAIL(&parent_ids
, pid
, entry
);
5750 err
= got_object_commit_create(new_commit_id
, new_tree_id
, &parent_ids
,
5751 nparents
, author
, time(NULL
), committer
, time(NULL
), logmsg
, repo
);
5757 /* Check if a concurrent commit to our branch has occurred. */
5758 head_ref_name
= got_worktree_get_head_ref_name(worktree
);
5759 if (head_ref_name
== NULL
) {
5760 err
= got_error_from_errno("got_worktree_get_head_ref_name");
5763 /* Lock the reference here to prevent concurrent modification. */
5764 err
= got_ref_open(&head_ref2
, repo
, head_ref_name
, 1);
5767 err
= got_ref_resolve(&head_commit_id2
, repo
, head_ref2
);
5770 if (got_object_id_cmp(head_commit_id
, head_commit_id2
) != 0) {
5771 err
= got_error(GOT_ERR_COMMIT_HEAD_CHANGED
);
5774 /* Update branch head in repository. */
5775 err
= got_ref_change_ref(head_ref2
, *new_commit_id
);
5778 err
= got_ref_write(head_ref2
, repo
);
5782 err
= got_worktree_set_base_commit_id(worktree
, repo
, *new_commit_id
);
5786 err
= ref_base_commit(worktree
, repo
);
5790 got_object_id_queue_free(&parent_ids
);
5792 got_object_tree_close(head_tree
);
5794 got_object_commit_close(head_commit
);
5795 free(head_commit_id2
);
5797 unlockerr
= got_ref_unlock(head_ref2
);
5798 if (unlockerr
&& err
== NULL
)
5800 got_ref_close(head_ref2
);
5805 static const struct got_error
*
5806 check_path_is_commitable(const char *path
,
5807 struct got_pathlist_head
*commitable_paths
)
5809 struct got_pathlist_entry
*cpe
= NULL
;
5810 size_t path_len
= strlen(path
);
5812 TAILQ_FOREACH(cpe
, commitable_paths
, entry
) {
5813 struct got_commitable
*ct
= cpe
->data
;
5814 const char *ct_path
= ct
->path
;
5816 while (ct_path
[0] == '/')
5819 if (strcmp(path
, ct_path
) == 0 ||
5820 got_path_is_child(ct_path
, path
, path_len
))
5825 return got_error_path(path
, GOT_ERR_BAD_PATH
);
5830 static const struct got_error
*
5831 check_staged_file(void *arg
, struct got_fileindex_entry
*ie
)
5833 int *have_staged_files
= arg
;
5835 if (got_fileindex_entry_stage_get(ie
) != GOT_FILEIDX_STAGE_NONE
) {
5836 *have_staged_files
= 1;
5837 return got_error(GOT_ERR_CANCELLED
);
5843 static const struct got_error
*
5844 check_non_staged_files(struct got_fileindex
*fileindex
,
5845 struct got_pathlist_head
*paths
)
5847 struct got_pathlist_entry
*pe
;
5848 struct got_fileindex_entry
*ie
;
5850 TAILQ_FOREACH(pe
, paths
, entry
) {
5851 if (pe
->path
[0] == '\0')
5853 ie
= got_fileindex_entry_get(fileindex
, pe
->path
, pe
->path_len
);
5855 return got_error_path(pe
->path
, GOT_ERR_BAD_PATH
);
5856 if (got_fileindex_entry_stage_get(ie
) == GOT_FILEIDX_STAGE_NONE
)
5857 return got_error_path(pe
->path
,
5858 GOT_ERR_FILE_NOT_STAGED
);
5864 const struct got_error
*
5865 got_worktree_commit(struct got_object_id
**new_commit_id
,
5866 struct got_worktree
*worktree
, struct got_pathlist_head
*paths
,
5867 const char *author
, const char *committer
, int allow_bad_symlinks
,
5868 got_worktree_commit_msg_cb commit_msg_cb
, void *commit_arg
,
5869 got_worktree_status_cb status_cb
, void *status_arg
,
5870 struct got_repository
*repo
)
5872 const struct got_error
*err
= NULL
, *unlockerr
= NULL
, *sync_err
;
5873 struct got_fileindex
*fileindex
= NULL
;
5874 char *fileindex_path
= NULL
;
5875 struct got_pathlist_head commitable_paths
;
5876 struct collect_commitables_arg cc_arg
;
5877 struct got_pathlist_entry
*pe
;
5878 struct got_reference
*head_ref
= NULL
;
5879 struct got_object_id
*head_commit_id
= NULL
;
5880 int have_staged_files
= 0;
5882 *new_commit_id
= NULL
;
5884 TAILQ_INIT(&commitable_paths
);
5886 err
= lock_worktree(worktree
, LOCK_EX
);
5890 err
= got_ref_open(&head_ref
, repo
, worktree
->head_ref_name
, 0);
5894 err
= got_ref_resolve(&head_commit_id
, repo
, head_ref
);
5898 err
= open_fileindex(&fileindex
, &fileindex_path
, worktree
);
5902 err
= got_fileindex_for_each_entry_safe(fileindex
, check_staged_file
,
5903 &have_staged_files
);
5904 if (err
&& err
->code
!= GOT_ERR_CANCELLED
)
5906 if (have_staged_files
) {
5907 err
= check_non_staged_files(fileindex
, paths
);
5912 cc_arg
.commitable_paths
= &commitable_paths
;
5913 cc_arg
.worktree
= worktree
;
5914 cc_arg
.fileindex
= fileindex
;
5916 cc_arg
.have_staged_files
= have_staged_files
;
5917 cc_arg
.allow_bad_symlinks
= allow_bad_symlinks
;
5918 TAILQ_FOREACH(pe
, paths
, entry
) {
5919 err
= worktree_status(worktree
, pe
->path
, fileindex
, repo
,
5920 collect_commitables
, &cc_arg
, NULL
, NULL
, 1, 0);
5925 if (TAILQ_EMPTY(&commitable_paths
)) {
5926 err
= got_error(GOT_ERR_COMMIT_NO_CHANGES
);
5930 TAILQ_FOREACH(pe
, paths
, entry
) {
5931 err
= check_path_is_commitable(pe
->path
, &commitable_paths
);
5936 TAILQ_FOREACH(pe
, &commitable_paths
, entry
) {
5937 struct got_commitable
*ct
= pe
->data
;
5938 const char *ct_path
= ct
->in_repo_path
;
5940 while (ct_path
[0] == '/')
5942 err
= check_out_of_date(ct_path
, ct
->status
,
5943 ct
->staged_status
, ct
->base_blob_id
, ct
->base_commit_id
,
5944 head_commit_id
, repo
, GOT_ERR_COMMIT_OUT_OF_DATE
);
5950 err
= commit_worktree(new_commit_id
, &commitable_paths
,
5951 head_commit_id
, NULL
, worktree
, author
, committer
,
5952 commit_msg_cb
, commit_arg
, status_cb
, status_arg
, repo
);
5956 err
= update_fileindex_after_commit(worktree
, &commitable_paths
,
5957 *new_commit_id
, fileindex
, have_staged_files
);
5958 sync_err
= sync_fileindex(fileindex
, fileindex_path
);
5959 if (sync_err
&& err
== NULL
)
5963 got_fileindex_free(fileindex
);
5964 free(fileindex_path
);
5965 unlockerr
= lock_worktree(worktree
, LOCK_SH
);
5966 if (unlockerr
&& err
== NULL
)
5968 TAILQ_FOREACH(pe
, &commitable_paths
, entry
) {
5969 struct got_commitable
*ct
= pe
->data
;
5970 free_commitable(ct
);
5972 got_pathlist_free(&commitable_paths
);
5977 got_commitable_get_path(struct got_commitable
*ct
)
5983 got_commitable_get_status(struct got_commitable
*ct
)
5988 struct check_rebase_ok_arg
{
5989 struct got_worktree
*worktree
;
5990 struct got_repository
*repo
;
5993 static const struct got_error
*
5994 check_rebase_ok(void *arg
, struct got_fileindex_entry
*ie
)
5996 const struct got_error
*err
= NULL
;
5997 struct check_rebase_ok_arg
*a
= arg
;
5998 unsigned char status
;
6002 /* Reject rebase of a work tree with mixed base commits. */
6003 if (memcmp(ie
->commit_sha1
, a
->worktree
->base_commit_id
->sha1
,
6004 SHA1_DIGEST_LENGTH
))
6005 return got_error(GOT_ERR_MIXED_COMMITS
);
6007 if (asprintf(&ondisk_path
, "%s/%s", a
->worktree
->root_path
, ie
->path
)
6009 return got_error_from_errno("asprintf");
6011 /* Reject rebase of a work tree with modified or staged files. */
6012 err
= get_file_status(&status
, &sb
, ie
, ondisk_path
, -1, NULL
, a
->repo
);
6017 if (status
!= GOT_STATUS_NO_CHANGE
)
6018 return got_error(GOT_ERR_MODIFIED
);
6019 if (get_staged_status(ie
) != GOT_STATUS_NO_CHANGE
)
6020 return got_error_path(ie
->path
, GOT_ERR_FILE_STAGED
);
6025 const struct got_error
*
6026 got_worktree_rebase_prepare(struct got_reference
**new_base_branch_ref
,
6027 struct got_reference
**tmp_branch
, struct got_fileindex
**fileindex
,
6028 struct got_worktree
*worktree
, struct got_reference
*branch
,
6029 struct got_repository
*repo
)
6031 const struct got_error
*err
= NULL
;
6032 char *tmp_branch_name
= NULL
, *new_base_branch_ref_name
= NULL
;
6033 char *branch_ref_name
= NULL
;
6034 char *fileindex_path
= NULL
;
6035 struct check_rebase_ok_arg ok_arg
;
6036 struct got_reference
*wt_branch
= NULL
, *branch_ref
= NULL
;
6037 struct got_object_id
*wt_branch_tip
= NULL
;
6039 *new_base_branch_ref
= NULL
;
6043 err
= lock_worktree(worktree
, LOCK_EX
);
6047 err
= open_fileindex(fileindex
, &fileindex_path
, worktree
);
6051 ok_arg
.worktree
= worktree
;
6053 err
= got_fileindex_for_each_entry_safe(*fileindex
, check_rebase_ok
,
6058 err
= get_rebase_tmp_ref_name(&tmp_branch_name
, worktree
);
6062 err
= get_newbase_symref_name(&new_base_branch_ref_name
, worktree
);
6066 err
= get_rebase_branch_symref_name(&branch_ref_name
, worktree
);
6070 err
= got_ref_open(&wt_branch
, repo
, worktree
->head_ref_name
,
6075 err
= got_ref_resolve(&wt_branch_tip
, repo
, wt_branch
);
6078 if (got_object_id_cmp(worktree
->base_commit_id
, wt_branch_tip
) != 0) {
6079 err
= got_error(GOT_ERR_REBASE_OUT_OF_DATE
);
6083 err
= got_ref_alloc_symref(new_base_branch_ref
,
6084 new_base_branch_ref_name
, wt_branch
);
6087 err
= got_ref_write(*new_base_branch_ref
, repo
);
6091 /* TODO Lock original branch's ref while rebasing? */
6093 err
= got_ref_alloc_symref(&branch_ref
, branch_ref_name
, branch
);
6097 err
= got_ref_write(branch_ref
, repo
);
6101 err
= got_ref_alloc(tmp_branch
, tmp_branch_name
,
6102 worktree
->base_commit_id
);
6105 err
= got_ref_write(*tmp_branch
, repo
);
6109 err
= got_worktree_set_head_ref(worktree
, *tmp_branch
);
6113 free(fileindex_path
);
6114 free(tmp_branch_name
);
6115 free(new_base_branch_ref_name
);
6116 free(branch_ref_name
);
6118 got_ref_close(branch_ref
);
6120 got_ref_close(wt_branch
);
6121 free(wt_branch_tip
);
6123 if (*new_base_branch_ref
) {
6124 got_ref_close(*new_base_branch_ref
);
6125 *new_base_branch_ref
= NULL
;
6128 got_ref_close(*tmp_branch
);
6132 got_fileindex_free(*fileindex
);
6135 lock_worktree(worktree
, LOCK_SH
);
6140 const struct got_error
*
6141 got_worktree_rebase_continue(struct got_object_id
**commit_id
,
6142 struct got_reference
**new_base_branch
, struct got_reference
**tmp_branch
,
6143 struct got_reference
**branch
, struct got_fileindex
**fileindex
,
6144 struct got_worktree
*worktree
, struct got_repository
*repo
)
6146 const struct got_error
*err
;
6147 char *commit_ref_name
= NULL
, *new_base_branch_ref_name
= NULL
;
6148 char *tmp_branch_name
= NULL
, *branch_ref_name
= NULL
;
6149 struct got_reference
*commit_ref
= NULL
, *branch_ref
= NULL
;
6150 char *fileindex_path
= NULL
;
6151 int have_staged_files
= 0;
6154 *new_base_branch
= NULL
;
6159 err
= lock_worktree(worktree
, LOCK_EX
);
6163 err
= open_fileindex(fileindex
, &fileindex_path
, worktree
);
6167 err
= got_fileindex_for_each_entry_safe(*fileindex
, check_staged_file
,
6168 &have_staged_files
);
6169 if (err
&& err
->code
!= GOT_ERR_CANCELLED
)
6171 if (have_staged_files
) {
6172 err
= got_error(GOT_ERR_STAGED_PATHS
);
6176 err
= get_rebase_tmp_ref_name(&tmp_branch_name
, worktree
);
6180 err
= get_rebase_branch_symref_name(&branch_ref_name
, worktree
);
6184 err
= get_rebase_commit_ref_name(&commit_ref_name
, worktree
);
6188 err
= get_newbase_symref_name(&new_base_branch_ref_name
, worktree
);
6192 err
= got_ref_open(&branch_ref
, repo
, branch_ref_name
, 0);
6196 err
= got_ref_open(branch
, repo
,
6197 got_ref_get_symref_target(branch_ref
), 0);
6201 err
= got_ref_open(&commit_ref
, repo
, commit_ref_name
, 0);
6205 err
= got_ref_resolve(commit_id
, repo
, commit_ref
);
6209 err
= got_ref_open(new_base_branch
, repo
,
6210 new_base_branch_ref_name
, 0);
6214 err
= got_ref_open(tmp_branch
, repo
, tmp_branch_name
, 0);
6218 free(commit_ref_name
);
6219 free(branch_ref_name
);
6220 free(fileindex_path
);
6222 got_ref_close(commit_ref
);
6224 got_ref_close(branch_ref
);
6229 got_ref_close(*tmp_branch
);
6232 if (*new_base_branch
) {
6233 got_ref_close(*new_base_branch
);
6234 *new_base_branch
= NULL
;
6237 got_ref_close(*branch
);
6241 got_fileindex_free(*fileindex
);
6244 lock_worktree(worktree
, LOCK_SH
);
6249 const struct got_error
*
6250 got_worktree_rebase_in_progress(int *in_progress
, struct got_worktree
*worktree
)
6252 const struct got_error
*err
;
6253 char *tmp_branch_name
= NULL
;
6255 err
= get_rebase_tmp_ref_name(&tmp_branch_name
, worktree
);
6259 *in_progress
= (strcmp(tmp_branch_name
, worktree
->head_ref_name
) == 0);
6260 free(tmp_branch_name
);
6264 static const struct got_error
*
6265 collect_rebase_commit_msg(struct got_pathlist_head
*commitable_paths
,
6266 char **logmsg
, void *arg
)
6272 static const struct got_error
*
6273 rebase_status(void *arg
, unsigned char status
, unsigned char staged_status
,
6274 const char *path
, struct got_object_id
*blob_id
,
6275 struct got_object_id
*staged_blob_id
, struct got_object_id
*commit_id
,
6276 int dirfd
, const char *de_name
)
6281 struct collect_merged_paths_arg
{
6282 got_worktree_checkout_cb progress_cb
;
6284 struct got_pathlist_head
*merged_paths
;
6287 static const struct got_error
*
6288 collect_merged_paths(void *arg
, unsigned char status
, const char *path
)
6290 const struct got_error
*err
;
6291 struct collect_merged_paths_arg
*a
= arg
;
6293 struct got_pathlist_entry
*new;
6295 err
= (*a
->progress_cb
)(a
->progress_arg
, status
, path
);
6299 if (status
!= GOT_STATUS_MERGE
&&
6300 status
!= GOT_STATUS_ADD
&&
6301 status
!= GOT_STATUS_DELETE
&&
6302 status
!= GOT_STATUS_CONFLICT
)
6307 return got_error_from_errno("strdup");
6309 err
= got_pathlist_insert(&new, a
->merged_paths
, p
, NULL
);
6310 if (err
|| new == NULL
)
6316 got_worktree_rebase_pathlist_free(struct got_pathlist_head
*merged_paths
)
6318 struct got_pathlist_entry
*pe
;
6320 TAILQ_FOREACH(pe
, merged_paths
, entry
)
6321 free((char *)pe
->path
);
6323 got_pathlist_free(merged_paths
);
6326 static const struct got_error
*
6327 store_commit_id(const char *commit_ref_name
, struct got_object_id
*commit_id
,
6328 int is_rebase
, struct got_repository
*repo
)
6330 const struct got_error
*err
;
6331 struct got_reference
*commit_ref
= NULL
;
6333 err
= got_ref_open(&commit_ref
, repo
, commit_ref_name
, 0);
6335 if (err
->code
!= GOT_ERR_NOT_REF
)
6337 err
= got_ref_alloc(&commit_ref
, commit_ref_name
, commit_id
);
6340 err
= got_ref_write(commit_ref
, repo
);
6343 } else if (is_rebase
) {
6344 struct got_object_id
*stored_id
;
6347 err
= got_ref_resolve(&stored_id
, repo
, commit_ref
);
6350 cmp
= got_object_id_cmp(commit_id
, stored_id
);
6353 err
= got_error(GOT_ERR_REBASE_COMMITID
);
6359 got_ref_close(commit_ref
);
6363 static const struct got_error
*
6364 rebase_merge_files(struct got_pathlist_head
*merged_paths
,
6365 const char *commit_ref_name
, struct got_worktree
*worktree
,
6366 struct got_fileindex
*fileindex
, struct got_object_id
*parent_commit_id
,
6367 struct got_object_id
*commit_id
, struct got_repository
*repo
,
6368 got_worktree_checkout_cb progress_cb
, void *progress_arg
,
6369 got_cancel_cb cancel_cb
, void *cancel_arg
)
6371 const struct got_error
*err
;
6372 struct got_reference
*commit_ref
= NULL
;
6373 struct collect_merged_paths_arg cmp_arg
;
6374 char *fileindex_path
;
6376 /* Work tree is locked/unlocked during rebase preparation/teardown. */
6378 err
= get_fileindex_path(&fileindex_path
, worktree
);
6382 cmp_arg
.progress_cb
= progress_cb
;
6383 cmp_arg
.progress_arg
= progress_arg
;
6384 cmp_arg
.merged_paths
= merged_paths
;
6385 err
= merge_files(worktree
, fileindex
, fileindex_path
,
6386 parent_commit_id
, commit_id
, repo
, collect_merged_paths
,
6387 &cmp_arg
, cancel_cb
, cancel_arg
);
6389 got_ref_close(commit_ref
);
6393 const struct got_error
*
6394 got_worktree_rebase_merge_files(struct got_pathlist_head
*merged_paths
,
6395 struct got_worktree
*worktree
, struct got_fileindex
*fileindex
,
6396 struct got_object_id
*parent_commit_id
, struct got_object_id
*commit_id
,
6397 struct got_repository
*repo
,
6398 got_worktree_checkout_cb progress_cb
, void *progress_arg
,
6399 got_cancel_cb cancel_cb
, void *cancel_arg
)
6401 const struct got_error
*err
;
6402 char *commit_ref_name
;
6404 err
= get_rebase_commit_ref_name(&commit_ref_name
, worktree
);
6408 err
= store_commit_id(commit_ref_name
, commit_id
, 1, repo
);
6412 err
= rebase_merge_files(merged_paths
, commit_ref_name
, worktree
,
6413 fileindex
, parent_commit_id
, commit_id
, repo
, progress_cb
,
6414 progress_arg
, cancel_cb
, cancel_arg
);
6416 free(commit_ref_name
);
6420 const struct got_error
*
6421 got_worktree_histedit_merge_files(struct got_pathlist_head
*merged_paths
,
6422 struct got_worktree
*worktree
, struct got_fileindex
*fileindex
,
6423 struct got_object_id
*parent_commit_id
, struct got_object_id
*commit_id
,
6424 struct got_repository
*repo
,
6425 got_worktree_checkout_cb progress_cb
, void *progress_arg
,
6426 got_cancel_cb cancel_cb
, void *cancel_arg
)
6428 const struct got_error
*err
;
6429 char *commit_ref_name
;
6431 err
= get_histedit_commit_ref_name(&commit_ref_name
, worktree
);
6435 err
= store_commit_id(commit_ref_name
, commit_id
, 0, repo
);
6439 err
= rebase_merge_files(merged_paths
, commit_ref_name
, worktree
,
6440 fileindex
, parent_commit_id
, commit_id
, repo
, progress_cb
,
6441 progress_arg
, cancel_cb
, cancel_arg
);
6443 free(commit_ref_name
);
6447 static const struct got_error
*
6448 rebase_commit(struct got_object_id
**new_commit_id
,
6449 struct got_pathlist_head
*merged_paths
, struct got_reference
*commit_ref
,
6450 struct got_worktree
*worktree
, struct got_fileindex
*fileindex
,
6451 struct got_reference
*tmp_branch
, struct got_commit_object
*orig_commit
,
6452 const char *new_logmsg
, struct got_repository
*repo
)
6454 const struct got_error
*err
, *sync_err
;
6455 struct got_pathlist_head commitable_paths
;
6456 struct collect_commitables_arg cc_arg
;
6457 char *fileindex_path
= NULL
;
6458 struct got_reference
*head_ref
= NULL
;
6459 struct got_object_id
*head_commit_id
= NULL
;
6460 char *logmsg
= NULL
;
6462 TAILQ_INIT(&commitable_paths
);
6463 *new_commit_id
= NULL
;
6465 /* Work tree is locked/unlocked during rebase preparation/teardown. */
6467 err
= get_fileindex_path(&fileindex_path
, worktree
);
6471 cc_arg
.commitable_paths
= &commitable_paths
;
6472 cc_arg
.worktree
= worktree
;
6474 cc_arg
.have_staged_files
= 0;
6476 * If possible get the status of individual files directly to
6477 * avoid crawling the entire work tree once per rebased commit.
6479 * Ideally, merged_paths would contain a list of commitables
6480 * we could use so we could skip worktree_status() entirely.
6481 * However, we would then need carefully keep track of cumulative
6482 * effects of operations such as file additions and deletions
6483 * in 'got histedit -f' (folding multiple commits into one),
6484 * and this extra complexity is not really worth it.
6487 struct got_pathlist_entry
*pe
;
6488 TAILQ_FOREACH(pe
, merged_paths
, entry
) {
6489 err
= worktree_status(worktree
, pe
->path
, fileindex
,
6490 repo
, collect_commitables
, &cc_arg
, NULL
, NULL
, 1,
6496 err
= worktree_status(worktree
, "", fileindex
, repo
,
6497 collect_commitables
, &cc_arg
, NULL
, NULL
, 1, 0);
6502 if (TAILQ_EMPTY(&commitable_paths
)) {
6503 /* No-op change; commit will be elided. */
6504 err
= got_ref_delete(commit_ref
, repo
);
6507 err
= got_error(GOT_ERR_COMMIT_NO_CHANGES
);
6511 err
= got_ref_open(&head_ref
, repo
, worktree
->head_ref_name
, 0);
6515 err
= got_ref_resolve(&head_commit_id
, repo
, head_ref
);
6520 logmsg
= strdup(new_logmsg
);
6521 if (logmsg
== NULL
) {
6522 err
= got_error_from_errno("strdup");
6526 err
= got_object_commit_get_logmsg(&logmsg
, orig_commit
);
6531 /* NB: commit_worktree will call free(logmsg) */
6532 err
= commit_worktree(new_commit_id
, &commitable_paths
, head_commit_id
,
6533 NULL
, worktree
, got_object_commit_get_author(orig_commit
),
6534 got_object_commit_get_committer(orig_commit
),
6535 collect_rebase_commit_msg
, logmsg
, rebase_status
, NULL
, repo
);
6539 err
= got_ref_change_ref(tmp_branch
, *new_commit_id
);
6543 err
= got_ref_delete(commit_ref
, repo
);
6547 err
= update_fileindex_after_commit(worktree
, &commitable_paths
,
6548 *new_commit_id
, fileindex
, 0);
6549 sync_err
= sync_fileindex(fileindex
, fileindex_path
);
6550 if (sync_err
&& err
== NULL
)
6553 free(fileindex_path
);
6554 free(head_commit_id
);
6556 got_ref_close(head_ref
);
6558 free(*new_commit_id
);
6559 *new_commit_id
= NULL
;
6564 const struct got_error
*
6565 got_worktree_rebase_commit(struct got_object_id
**new_commit_id
,
6566 struct got_pathlist_head
*merged_paths
, struct got_worktree
*worktree
,
6567 struct got_fileindex
*fileindex
, struct got_reference
*tmp_branch
,
6568 struct got_commit_object
*orig_commit
,
6569 struct got_object_id
*orig_commit_id
, struct got_repository
*repo
)
6571 const struct got_error
*err
;
6572 char *commit_ref_name
;
6573 struct got_reference
*commit_ref
= NULL
;
6574 struct got_object_id
*commit_id
= NULL
;
6576 err
= get_rebase_commit_ref_name(&commit_ref_name
, worktree
);
6580 err
= got_ref_open(&commit_ref
, repo
, commit_ref_name
, 0);
6583 err
= got_ref_resolve(&commit_id
, repo
, commit_ref
);
6586 if (got_object_id_cmp(commit_id
, orig_commit_id
) != 0) {
6587 err
= got_error(GOT_ERR_REBASE_COMMITID
);
6591 err
= rebase_commit(new_commit_id
, merged_paths
, commit_ref
,
6592 worktree
, fileindex
, tmp_branch
, orig_commit
, NULL
, repo
);
6595 got_ref_close(commit_ref
);
6596 free(commit_ref_name
);
6601 const struct got_error
*
6602 got_worktree_histedit_commit(struct got_object_id
**new_commit_id
,
6603 struct got_pathlist_head
*merged_paths
, struct got_worktree
*worktree
,
6604 struct got_fileindex
*fileindex
, struct got_reference
*tmp_branch
,
6605 struct got_commit_object
*orig_commit
,
6606 struct got_object_id
*orig_commit_id
, const char *new_logmsg
,
6607 struct got_repository
*repo
)
6609 const struct got_error
*err
;
6610 char *commit_ref_name
;
6611 struct got_reference
*commit_ref
= NULL
;
6613 err
= get_histedit_commit_ref_name(&commit_ref_name
, worktree
);
6617 err
= got_ref_open(&commit_ref
, repo
, commit_ref_name
, 0);
6621 err
= rebase_commit(new_commit_id
, merged_paths
, commit_ref
,
6622 worktree
, fileindex
, tmp_branch
, orig_commit
, new_logmsg
, repo
);
6625 got_ref_close(commit_ref
);
6626 free(commit_ref_name
);
6630 const struct got_error
*
6631 got_worktree_rebase_postpone(struct got_worktree
*worktree
,
6632 struct got_fileindex
*fileindex
)
6635 got_fileindex_free(fileindex
);
6636 return lock_worktree(worktree
, LOCK_SH
);
6639 static const struct got_error
*
6640 delete_ref(const char *name
, struct got_repository
*repo
)
6642 const struct got_error
*err
;
6643 struct got_reference
*ref
;
6645 err
= got_ref_open(&ref
, repo
, name
, 0);
6647 if (err
->code
== GOT_ERR_NOT_REF
)
6652 err
= got_ref_delete(ref
, repo
);
6657 static const struct got_error
*
6658 delete_rebase_refs(struct got_worktree
*worktree
, struct got_repository
*repo
)
6660 const struct got_error
*err
;
6661 char *tmp_branch_name
= NULL
, *new_base_branch_ref_name
= NULL
;
6662 char *branch_ref_name
= NULL
, *commit_ref_name
= NULL
;
6664 err
= get_rebase_tmp_ref_name(&tmp_branch_name
, worktree
);
6667 err
= delete_ref(tmp_branch_name
, repo
);
6671 err
= get_newbase_symref_name(&new_base_branch_ref_name
, worktree
);
6674 err
= delete_ref(new_base_branch_ref_name
, repo
);
6678 err
= get_rebase_branch_symref_name(&branch_ref_name
, worktree
);
6681 err
= delete_ref(branch_ref_name
, repo
);
6685 err
= get_rebase_commit_ref_name(&commit_ref_name
, worktree
);
6688 err
= delete_ref(commit_ref_name
, repo
);
6693 free(tmp_branch_name
);
6694 free(new_base_branch_ref_name
);
6695 free(branch_ref_name
);
6696 free(commit_ref_name
);
6700 static const struct got_error
*
6701 create_backup_ref(const char *backup_ref_prefix
, struct got_reference
*branch
,
6702 struct got_object_id
*new_commit_id
, struct got_repository
*repo
)
6704 const struct got_error
*err
;
6705 struct got_reference
*ref
= NULL
;
6706 struct got_object_id
*old_commit_id
= NULL
;
6707 const char *branch_name
= NULL
;
6708 char *new_id_str
= NULL
;
6709 char *refname
= NULL
;
6711 branch_name
= got_ref_get_name(branch
);
6712 if (strncmp(branch_name
, "refs/heads/", 11) != 0)
6713 return got_error(GOT_ERR_BAD_REF_NAME
); /* should not happen */
6716 err
= got_object_id_str(&new_id_str
, new_commit_id
);
6720 if (asprintf(&refname
, "%s/%s/%s", backup_ref_prefix
, branch_name
,
6721 new_id_str
) == -1) {
6722 err
= got_error_from_errno("asprintf");
6726 err
= got_ref_resolve(&old_commit_id
, repo
, branch
);
6730 err
= got_ref_alloc(&ref
, refname
, old_commit_id
);
6734 err
= got_ref_write(ref
, repo
);
6738 free(old_commit_id
);
6744 const struct got_error
*
6745 got_worktree_rebase_complete(struct got_worktree
*worktree
,
6746 struct got_fileindex
*fileindex
, struct got_reference
*new_base_branch
,
6747 struct got_reference
*tmp_branch
, struct got_reference
*rebased_branch
,
6748 struct got_repository
*repo
, int create_backup
)
6750 const struct got_error
*err
, *unlockerr
, *sync_err
;
6751 struct got_object_id
*new_head_commit_id
= NULL
;
6752 char *fileindex_path
= NULL
;
6754 err
= got_ref_resolve(&new_head_commit_id
, repo
, tmp_branch
);
6758 if (create_backup
) {
6759 err
= create_backup_ref(GOT_WORKTREE_REBASE_BACKUP_REF_PREFIX
,
6760 rebased_branch
, new_head_commit_id
, repo
);
6765 err
= got_ref_change_ref(rebased_branch
, new_head_commit_id
);
6769 err
= got_ref_write(rebased_branch
, repo
);
6773 err
= got_worktree_set_head_ref(worktree
, rebased_branch
);
6777 err
= delete_rebase_refs(worktree
, repo
);
6781 err
= get_fileindex_path(&fileindex_path
, worktree
);
6784 err
= bump_base_commit_id_everywhere(worktree
, fileindex
, NULL
, NULL
);
6785 sync_err
= sync_fileindex(fileindex
, fileindex_path
);
6786 if (sync_err
&& err
== NULL
)
6789 got_fileindex_free(fileindex
);
6790 free(fileindex_path
);
6791 free(new_head_commit_id
);
6792 unlockerr
= lock_worktree(worktree
, LOCK_SH
);
6793 if (unlockerr
&& err
== NULL
)
6798 const struct got_error
*
6799 got_worktree_rebase_abort(struct got_worktree
*worktree
,
6800 struct got_fileindex
*fileindex
, struct got_repository
*repo
,
6801 struct got_reference
*new_base_branch
,
6802 got_worktree_checkout_cb progress_cb
, void *progress_arg
)
6804 const struct got_error
*err
, *unlockerr
, *sync_err
;
6805 struct got_reference
*resolved
= NULL
;
6806 struct got_object_id
*commit_id
= NULL
;
6807 struct got_commit_object
*commit
= NULL
;
6808 char *fileindex_path
= NULL
;
6809 struct revert_file_args rfa
;
6810 struct got_object_id
*tree_id
= NULL
;
6812 err
= lock_worktree(worktree
, LOCK_EX
);
6816 err
= got_object_open_as_commit(&commit
, repo
,
6817 worktree
->base_commit_id
);
6821 err
= got_ref_open(&resolved
, repo
,
6822 got_ref_get_symref_target(new_base_branch
), 0);
6826 err
= got_worktree_set_head_ref(worktree
, resolved
);
6831 * XXX commits to the base branch could have happened while
6832 * we were busy rebasing; should we store the original commit ID
6833 * when rebase begins and read it back here?
6835 err
= got_ref_resolve(&commit_id
, repo
, resolved
);
6839 err
= got_worktree_set_base_commit_id(worktree
, repo
, commit_id
);
6843 err
= got_object_id_by_path(&tree_id
, repo
, commit
,
6844 worktree
->path_prefix
);
6848 err
= delete_rebase_refs(worktree
, repo
);
6852 err
= get_fileindex_path(&fileindex_path
, worktree
);
6856 rfa
.worktree
= worktree
;
6857 rfa
.fileindex
= fileindex
;
6858 rfa
.progress_cb
= progress_cb
;
6859 rfa
.progress_arg
= progress_arg
;
6860 rfa
.patch_cb
= NULL
;
6861 rfa
.patch_arg
= NULL
;
6863 rfa
.unlink_added_files
= 0;
6864 err
= worktree_status(worktree
, "", fileindex
, repo
,
6865 revert_file
, &rfa
, NULL
, NULL
, 1, 0);
6869 err
= checkout_files(worktree
, fileindex
, "", tree_id
, NULL
,
6870 repo
, progress_cb
, progress_arg
, NULL
, NULL
);
6872 sync_err
= sync_fileindex(fileindex
, fileindex_path
);
6873 if (sync_err
&& err
== NULL
)
6876 got_ref_close(resolved
);
6880 got_object_commit_close(commit
);
6882 got_fileindex_free(fileindex
);
6883 free(fileindex_path
);
6885 unlockerr
= lock_worktree(worktree
, LOCK_SH
);
6886 if (unlockerr
&& err
== NULL
)
6891 const struct got_error
*
6892 got_worktree_histedit_prepare(struct got_reference
**tmp_branch
,
6893 struct got_reference
**branch_ref
, struct got_object_id
**base_commit_id
,
6894 struct got_fileindex
**fileindex
, struct got_worktree
*worktree
,
6895 struct got_repository
*repo
)
6897 const struct got_error
*err
= NULL
;
6898 char *tmp_branch_name
= NULL
;
6899 char *branch_ref_name
= NULL
;
6900 char *base_commit_ref_name
= NULL
;
6901 char *fileindex_path
= NULL
;
6902 struct check_rebase_ok_arg ok_arg
;
6903 struct got_reference
*wt_branch
= NULL
;
6904 struct got_reference
*base_commit_ref
= NULL
;
6908 *base_commit_id
= NULL
;
6911 err
= lock_worktree(worktree
, LOCK_EX
);
6915 err
= open_fileindex(fileindex
, &fileindex_path
, worktree
);
6919 ok_arg
.worktree
= worktree
;
6921 err
= got_fileindex_for_each_entry_safe(*fileindex
, check_rebase_ok
,
6926 err
= get_histedit_tmp_ref_name(&tmp_branch_name
, worktree
);
6930 err
= get_histedit_branch_symref_name(&branch_ref_name
, worktree
);
6934 err
= get_histedit_base_commit_ref_name(&base_commit_ref_name
,
6939 err
= got_ref_open(&wt_branch
, repo
, worktree
->head_ref_name
,
6944 err
= got_ref_alloc_symref(branch_ref
, branch_ref_name
, wt_branch
);
6948 err
= got_ref_write(*branch_ref
, repo
);
6952 err
= got_ref_alloc(&base_commit_ref
, base_commit_ref_name
,
6953 worktree
->base_commit_id
);
6956 err
= got_ref_write(base_commit_ref
, repo
);
6959 *base_commit_id
= got_object_id_dup(worktree
->base_commit_id
);
6960 if (*base_commit_id
== NULL
) {
6961 err
= got_error_from_errno("got_object_id_dup");
6965 err
= got_ref_alloc(tmp_branch
, tmp_branch_name
,
6966 worktree
->base_commit_id
);
6969 err
= got_ref_write(*tmp_branch
, repo
);
6973 err
= got_worktree_set_head_ref(worktree
, *tmp_branch
);
6977 free(fileindex_path
);
6978 free(tmp_branch_name
);
6979 free(branch_ref_name
);
6980 free(base_commit_ref_name
);
6982 got_ref_close(wt_branch
);
6985 got_ref_close(*branch_ref
);
6989 got_ref_close(*tmp_branch
);
6992 free(*base_commit_id
);
6994 got_fileindex_free(*fileindex
);
6997 lock_worktree(worktree
, LOCK_SH
);
7002 const struct got_error
*
7003 got_worktree_histedit_postpone(struct got_worktree
*worktree
,
7004 struct got_fileindex
*fileindex
)
7007 got_fileindex_free(fileindex
);
7008 return lock_worktree(worktree
, LOCK_SH
);
7011 const struct got_error
*
7012 got_worktree_histedit_in_progress(int *in_progress
,
7013 struct got_worktree
*worktree
)
7015 const struct got_error
*err
;
7016 char *tmp_branch_name
= NULL
;
7018 err
= get_histedit_tmp_ref_name(&tmp_branch_name
, worktree
);
7022 *in_progress
= (strcmp(tmp_branch_name
, worktree
->head_ref_name
) == 0);
7023 free(tmp_branch_name
);
7027 const struct got_error
*
7028 got_worktree_histedit_continue(struct got_object_id
**commit_id
,
7029 struct got_reference
**tmp_branch
, struct got_reference
**branch_ref
,
7030 struct got_object_id
**base_commit_id
, struct got_fileindex
**fileindex
,
7031 struct got_worktree
*worktree
, struct got_repository
*repo
)
7033 const struct got_error
*err
;
7034 char *commit_ref_name
= NULL
, *base_commit_ref_name
= NULL
;
7035 char *tmp_branch_name
= NULL
, *branch_ref_name
= NULL
;
7036 struct got_reference
*commit_ref
= NULL
;
7037 struct got_reference
*base_commit_ref
= NULL
;
7038 char *fileindex_path
= NULL
;
7039 int have_staged_files
= 0;
7043 *base_commit_id
= NULL
;
7046 err
= lock_worktree(worktree
, LOCK_EX
);
7050 err
= open_fileindex(fileindex
, &fileindex_path
, worktree
);
7054 err
= got_fileindex_for_each_entry_safe(*fileindex
, check_staged_file
,
7055 &have_staged_files
);
7056 if (err
&& err
->code
!= GOT_ERR_CANCELLED
)
7058 if (have_staged_files
) {
7059 err
= got_error(GOT_ERR_STAGED_PATHS
);
7063 err
= get_histedit_tmp_ref_name(&tmp_branch_name
, worktree
);
7067 err
= get_histedit_branch_symref_name(&branch_ref_name
, worktree
);
7071 err
= get_histedit_commit_ref_name(&commit_ref_name
, worktree
);
7075 err
= get_histedit_base_commit_ref_name(&base_commit_ref_name
,
7080 err
= got_ref_open(branch_ref
, repo
, branch_ref_name
, 0);
7084 err
= got_ref_open(&commit_ref
, repo
, commit_ref_name
, 0);
7087 err
= got_ref_resolve(commit_id
, repo
, commit_ref
);
7091 err
= got_ref_open(&base_commit_ref
, repo
, base_commit_ref_name
, 0);
7094 err
= got_ref_resolve(base_commit_id
, repo
, base_commit_ref
);
7098 err
= got_ref_open(tmp_branch
, repo
, tmp_branch_name
, 0);
7102 free(commit_ref_name
);
7103 free(branch_ref_name
);
7104 free(fileindex_path
);
7106 got_ref_close(commit_ref
);
7107 if (base_commit_ref
)
7108 got_ref_close(base_commit_ref
);
7112 free(*base_commit_id
);
7113 *base_commit_id
= NULL
;
7115 got_ref_close(*tmp_branch
);
7119 got_fileindex_free(*fileindex
);
7122 lock_worktree(worktree
, LOCK_EX
);
7127 static const struct got_error
*
7128 delete_histedit_refs(struct got_worktree
*worktree
, struct got_repository
*repo
)
7130 const struct got_error
*err
;
7131 char *tmp_branch_name
= NULL
, *base_commit_ref_name
= NULL
;
7132 char *branch_ref_name
= NULL
, *commit_ref_name
= NULL
;
7134 err
= get_histedit_tmp_ref_name(&tmp_branch_name
, worktree
);
7137 err
= delete_ref(tmp_branch_name
, repo
);
7141 err
= get_histedit_base_commit_ref_name(&base_commit_ref_name
,
7145 err
= delete_ref(base_commit_ref_name
, repo
);
7149 err
= get_histedit_branch_symref_name(&branch_ref_name
, worktree
);
7152 err
= delete_ref(branch_ref_name
, repo
);
7156 err
= get_histedit_commit_ref_name(&commit_ref_name
, worktree
);
7159 err
= delete_ref(commit_ref_name
, repo
);
7163 free(tmp_branch_name
);
7164 free(base_commit_ref_name
);
7165 free(branch_ref_name
);
7166 free(commit_ref_name
);
7170 const struct got_error
*
7171 got_worktree_histedit_abort(struct got_worktree
*worktree
,
7172 struct got_fileindex
*fileindex
, struct got_repository
*repo
,
7173 struct got_reference
*branch
, struct got_object_id
*base_commit_id
,
7174 got_worktree_checkout_cb progress_cb
, void *progress_arg
)
7176 const struct got_error
*err
, *unlockerr
, *sync_err
;
7177 struct got_reference
*resolved
= NULL
;
7178 char *fileindex_path
= NULL
;
7179 struct got_commit_object
*commit
= NULL
;
7180 struct got_object_id
*tree_id
= NULL
;
7181 struct revert_file_args rfa
;
7183 err
= lock_worktree(worktree
, LOCK_EX
);
7187 err
= got_object_open_as_commit(&commit
, repo
,
7188 worktree
->base_commit_id
);
7192 err
= got_ref_open(&resolved
, repo
,
7193 got_ref_get_symref_target(branch
), 0);
7197 err
= got_worktree_set_head_ref(worktree
, resolved
);
7201 err
= got_worktree_set_base_commit_id(worktree
, repo
, base_commit_id
);
7205 err
= got_object_id_by_path(&tree_id
, repo
, commit
,
7206 worktree
->path_prefix
);
7210 err
= delete_histedit_refs(worktree
, repo
);
7214 err
= get_fileindex_path(&fileindex_path
, worktree
);
7218 rfa
.worktree
= worktree
;
7219 rfa
.fileindex
= fileindex
;
7220 rfa
.progress_cb
= progress_cb
;
7221 rfa
.progress_arg
= progress_arg
;
7222 rfa
.patch_cb
= NULL
;
7223 rfa
.patch_arg
= NULL
;
7225 rfa
.unlink_added_files
= 0;
7226 err
= worktree_status(worktree
, "", fileindex
, repo
,
7227 revert_file
, &rfa
, NULL
, NULL
, 1, 0);
7231 err
= checkout_files(worktree
, fileindex
, "", tree_id
, NULL
,
7232 repo
, progress_cb
, progress_arg
, NULL
, NULL
);
7234 sync_err
= sync_fileindex(fileindex
, fileindex_path
);
7235 if (sync_err
&& err
== NULL
)
7238 got_ref_close(resolved
);
7240 free(fileindex_path
);
7242 unlockerr
= lock_worktree(worktree
, LOCK_SH
);
7243 if (unlockerr
&& err
== NULL
)
7248 const struct got_error
*
7249 got_worktree_histedit_complete(struct got_worktree
*worktree
,
7250 struct got_fileindex
*fileindex
, struct got_reference
*tmp_branch
,
7251 struct got_reference
*edited_branch
, struct got_repository
*repo
)
7253 const struct got_error
*err
, *unlockerr
, *sync_err
;
7254 struct got_object_id
*new_head_commit_id
= NULL
;
7255 struct got_reference
*resolved
= NULL
;
7256 char *fileindex_path
= NULL
;
7258 err
= got_ref_resolve(&new_head_commit_id
, repo
, tmp_branch
);
7262 err
= got_ref_open(&resolved
, repo
,
7263 got_ref_get_symref_target(edited_branch
), 0);
7267 err
= create_backup_ref(GOT_WORKTREE_HISTEDIT_BACKUP_REF_PREFIX
,
7268 resolved
, new_head_commit_id
, repo
);
7272 err
= got_ref_change_ref(resolved
, new_head_commit_id
);
7276 err
= got_ref_write(resolved
, repo
);
7280 err
= got_worktree_set_head_ref(worktree
, resolved
);
7284 err
= delete_histedit_refs(worktree
, repo
);
7288 err
= get_fileindex_path(&fileindex_path
, worktree
);
7291 err
= bump_base_commit_id_everywhere(worktree
, fileindex
, NULL
, NULL
);
7292 sync_err
= sync_fileindex(fileindex
, fileindex_path
);
7293 if (sync_err
&& err
== NULL
)
7296 got_fileindex_free(fileindex
);
7297 free(fileindex_path
);
7298 free(new_head_commit_id
);
7299 unlockerr
= lock_worktree(worktree
, LOCK_SH
);
7300 if (unlockerr
&& err
== NULL
)
7305 const struct got_error
*
7306 got_worktree_histedit_skip_commit(struct got_worktree
*worktree
,
7307 struct got_object_id
*commit_id
, struct got_repository
*repo
)
7309 const struct got_error
*err
;
7310 char *commit_ref_name
;
7312 err
= get_histedit_commit_ref_name(&commit_ref_name
, worktree
);
7316 err
= store_commit_id(commit_ref_name
, commit_id
, 0, repo
);
7320 err
= delete_ref(commit_ref_name
, repo
);
7322 free(commit_ref_name
);
7326 const struct got_error
*
7327 got_worktree_integrate_prepare(struct got_fileindex
**fileindex
,
7328 struct got_reference
**branch_ref
, struct got_reference
**base_branch_ref
,
7329 struct got_worktree
*worktree
, const char *refname
,
7330 struct got_repository
*repo
)
7332 const struct got_error
*err
= NULL
;
7333 char *fileindex_path
= NULL
;
7334 struct check_rebase_ok_arg ok_arg
;
7338 *base_branch_ref
= NULL
;
7340 err
= lock_worktree(worktree
, LOCK_EX
);
7344 if (strcmp(refname
, got_worktree_get_head_ref_name(worktree
)) == 0) {
7345 err
= got_error_msg(GOT_ERR_SAME_BRANCH
,
7346 "cannot integrate a branch into itself; "
7347 "update -b or different branch name required");
7351 err
= open_fileindex(fileindex
, &fileindex_path
, worktree
);
7355 /* Preconditions are the same as for rebase. */
7356 ok_arg
.worktree
= worktree
;
7358 err
= got_fileindex_for_each_entry_safe(*fileindex
, check_rebase_ok
,
7363 err
= got_ref_open(branch_ref
, repo
, refname
, 1);
7367 err
= got_ref_open(base_branch_ref
, repo
,
7368 got_worktree_get_head_ref_name(worktree
), 1);
7372 got_ref_close(*branch_ref
);
7375 if (*base_branch_ref
) {
7376 got_ref_close(*base_branch_ref
);
7377 *base_branch_ref
= NULL
;
7380 got_fileindex_free(*fileindex
);
7383 lock_worktree(worktree
, LOCK_SH
);
7388 const struct got_error
*
7389 got_worktree_integrate_continue(struct got_worktree
*worktree
,
7390 struct got_fileindex
*fileindex
, struct got_repository
*repo
,
7391 struct got_reference
*branch_ref
, struct got_reference
*base_branch_ref
,
7392 got_worktree_checkout_cb progress_cb
, void *progress_arg
,
7393 got_cancel_cb cancel_cb
, void *cancel_arg
)
7395 const struct got_error
*err
= NULL
, *sync_err
, *unlockerr
;
7396 char *fileindex_path
= NULL
;
7397 struct got_object_id
*tree_id
= NULL
, *commit_id
= NULL
;
7398 struct got_commit_object
*commit
= NULL
;
7400 err
= get_fileindex_path(&fileindex_path
, worktree
);
7404 err
= got_ref_resolve(&commit_id
, repo
, branch_ref
);
7408 err
= got_object_open_as_commit(&commit
, repo
, commit_id
);
7412 err
= got_object_id_by_path(&tree_id
, repo
, commit
,
7413 worktree
->path_prefix
);
7417 err
= got_worktree_set_base_commit_id(worktree
, repo
, commit_id
);
7421 err
= checkout_files(worktree
, fileindex
, "", tree_id
, NULL
, repo
,
7422 progress_cb
, progress_arg
, cancel_cb
, cancel_arg
);
7426 err
= got_ref_change_ref(base_branch_ref
, commit_id
);
7430 err
= got_ref_write(base_branch_ref
, repo
);
7434 err
= bump_base_commit_id_everywhere(worktree
, fileindex
, NULL
, NULL
);
7436 sync_err
= sync_fileindex(fileindex
, fileindex_path
);
7437 if (sync_err
&& err
== NULL
)
7441 unlockerr
= got_ref_unlock(branch_ref
);
7442 if (unlockerr
&& err
== NULL
)
7444 got_ref_close(branch_ref
);
7446 unlockerr
= got_ref_unlock(base_branch_ref
);
7447 if (unlockerr
&& err
== NULL
)
7449 got_ref_close(base_branch_ref
);
7451 got_fileindex_free(fileindex
);
7452 free(fileindex_path
);
7455 got_object_commit_close(commit
);
7457 unlockerr
= lock_worktree(worktree
, LOCK_SH
);
7458 if (unlockerr
&& err
== NULL
)
7463 const struct got_error
*
7464 got_worktree_integrate_abort(struct got_worktree
*worktree
,
7465 struct got_fileindex
*fileindex
, struct got_repository
*repo
,
7466 struct got_reference
*branch_ref
, struct got_reference
*base_branch_ref
)
7468 const struct got_error
*err
= NULL
, *unlockerr
= NULL
;
7470 got_fileindex_free(fileindex
);
7472 err
= lock_worktree(worktree
, LOCK_SH
);
7474 unlockerr
= got_ref_unlock(branch_ref
);
7475 if (unlockerr
&& err
== NULL
)
7477 got_ref_close(branch_ref
);
7479 unlockerr
= got_ref_unlock(base_branch_ref
);
7480 if (unlockerr
&& err
== NULL
)
7482 got_ref_close(base_branch_ref
);
7487 const struct got_error
*
7488 got_worktree_merge_postpone(struct got_worktree
*worktree
,
7489 struct got_fileindex
*fileindex
)
7491 const struct got_error
*err
, *sync_err
;
7492 char *fileindex_path
= NULL
;
7494 err
= get_fileindex_path(&fileindex_path
, worktree
);
7498 sync_err
= sync_fileindex(fileindex
, fileindex_path
);
7500 err
= lock_worktree(worktree
, LOCK_SH
);
7501 if (sync_err
&& err
== NULL
)
7504 got_fileindex_free(fileindex
);
7505 free(fileindex_path
);
7509 static const struct got_error
*
7510 delete_merge_refs(struct got_worktree
*worktree
, struct got_repository
*repo
)
7512 const struct got_error
*err
;
7513 char *branch_refname
= NULL
, *commit_refname
= NULL
;
7515 err
= get_merge_branch_ref_name(&branch_refname
, worktree
);
7518 err
= delete_ref(branch_refname
, repo
);
7522 err
= get_merge_commit_ref_name(&commit_refname
, worktree
);
7525 err
= delete_ref(commit_refname
, repo
);
7530 free(branch_refname
);
7531 free(commit_refname
);
7535 struct merge_commit_msg_arg
{
7536 struct got_worktree
*worktree
;
7537 const char *branch_name
;
7540 static const struct got_error
*
7541 merge_commit_msg_cb(struct got_pathlist_head
*commitable_paths
, char **logmsg
,
7544 struct merge_commit_msg_arg
*a
= arg
;
7546 if (asprintf(logmsg
, "merge %s into %s\n", a
->branch_name
,
7547 got_worktree_get_head_ref_name(a
->worktree
)) == -1)
7548 return got_error_from_errno("asprintf");
7554 const struct got_error
*
7555 got_worktree_merge_branch(struct got_worktree
*worktree
,
7556 struct got_fileindex
*fileindex
,
7557 struct got_object_id
*yca_commit_id
,
7558 struct got_object_id
*branch_tip
,
7559 struct got_repository
*repo
, got_worktree_checkout_cb progress_cb
,
7560 void *progress_arg
, got_cancel_cb cancel_cb
, void *cancel_arg
)
7562 const struct got_error
*err
;
7563 char *fileindex_path
= NULL
;
7565 err
= get_fileindex_path(&fileindex_path
, worktree
);
7569 err
= got_fileindex_for_each_entry_safe(fileindex
, check_mixed_commits
,
7574 err
= merge_files(worktree
, fileindex
, fileindex_path
, yca_commit_id
,
7575 branch_tip
, repo
, progress_cb
, progress_arg
,
7576 cancel_cb
, cancel_arg
);
7578 free(fileindex_path
);
7582 const struct got_error
*
7583 got_worktree_merge_commit(struct got_object_id
**new_commit_id
,
7584 struct got_worktree
*worktree
, struct got_fileindex
*fileindex
,
7585 const char *author
, const char *committer
, int allow_bad_symlinks
,
7586 struct got_object_id
*branch_tip
, const char *branch_name
,
7587 struct got_repository
*repo
,
7588 got_worktree_status_cb status_cb
, void *status_arg
)
7591 const struct got_error
*err
= NULL
, *sync_err
;
7592 struct got_pathlist_head commitable_paths
;
7593 struct collect_commitables_arg cc_arg
;
7594 struct got_pathlist_entry
*pe
;
7595 struct got_reference
*head_ref
= NULL
;
7596 struct got_object_id
*head_commit_id
= NULL
;
7597 int have_staged_files
= 0;
7598 struct merge_commit_msg_arg mcm_arg
;
7599 char *fileindex_path
= NULL
;
7601 *new_commit_id
= NULL
;
7603 TAILQ_INIT(&commitable_paths
);
7605 err
= get_fileindex_path(&fileindex_path
, worktree
);
7609 err
= got_ref_open(&head_ref
, repo
, worktree
->head_ref_name
, 0);
7613 err
= got_ref_resolve(&head_commit_id
, repo
, head_ref
);
7617 err
= got_fileindex_for_each_entry_safe(fileindex
, check_staged_file
,
7618 &have_staged_files
);
7619 if (err
&& err
->code
!= GOT_ERR_CANCELLED
)
7621 if (have_staged_files
) {
7622 err
= got_error(GOT_ERR_MERGE_STAGED_PATHS
);
7626 cc_arg
.commitable_paths
= &commitable_paths
;
7627 cc_arg
.worktree
= worktree
;
7628 cc_arg
.fileindex
= fileindex
;
7630 cc_arg
.have_staged_files
= have_staged_files
;
7631 cc_arg
.allow_bad_symlinks
= allow_bad_symlinks
;
7632 err
= worktree_status(worktree
, "", fileindex
, repo
,
7633 collect_commitables
, &cc_arg
, NULL
, NULL
, 1, 0);
7637 if (TAILQ_EMPTY(&commitable_paths
)) {
7638 err
= got_error_fmt(GOT_ERR_COMMIT_NO_CHANGES
,
7639 "merge of %s cannot proceed", branch_name
);
7643 TAILQ_FOREACH(pe
, &commitable_paths
, entry
) {
7644 struct got_commitable
*ct
= pe
->data
;
7645 const char *ct_path
= ct
->in_repo_path
;
7647 while (ct_path
[0] == '/')
7649 err
= check_out_of_date(ct_path
, ct
->status
,
7650 ct
->staged_status
, ct
->base_blob_id
, ct
->base_commit_id
,
7651 head_commit_id
, repo
, GOT_ERR_MERGE_COMMIT_OUT_OF_DATE
);
7657 mcm_arg
.worktree
= worktree
;
7658 mcm_arg
.branch_name
= branch_name
;
7659 err
= commit_worktree(new_commit_id
, &commitable_paths
,
7660 head_commit_id
, branch_tip
, worktree
, author
, committer
,
7661 merge_commit_msg_cb
, &mcm_arg
, status_cb
, status_arg
, repo
);
7665 err
= update_fileindex_after_commit(worktree
, &commitable_paths
,
7666 *new_commit_id
, fileindex
, have_staged_files
);
7667 sync_err
= sync_fileindex(fileindex
, fileindex_path
);
7668 if (sync_err
&& err
== NULL
)
7671 TAILQ_FOREACH(pe
, &commitable_paths
, entry
) {
7672 struct got_commitable
*ct
= pe
->data
;
7673 free_commitable(ct
);
7675 got_pathlist_free(&commitable_paths
);
7676 free(fileindex_path
);
7680 const struct got_error
*
7681 got_worktree_merge_complete(struct got_worktree
*worktree
,
7682 struct got_fileindex
*fileindex
, struct got_repository
*repo
)
7684 const struct got_error
*err
, *unlockerr
, *sync_err
;
7685 char *fileindex_path
= NULL
;
7687 err
= delete_merge_refs(worktree
, repo
);
7691 err
= get_fileindex_path(&fileindex_path
, worktree
);
7694 err
= bump_base_commit_id_everywhere(worktree
, fileindex
, NULL
, NULL
);
7695 sync_err
= sync_fileindex(fileindex
, fileindex_path
);
7696 if (sync_err
&& err
== NULL
)
7699 got_fileindex_free(fileindex
);
7700 free(fileindex_path
);
7701 unlockerr
= lock_worktree(worktree
, LOCK_SH
);
7702 if (unlockerr
&& err
== NULL
)
7707 const struct got_error
*
7708 got_worktree_merge_in_progress(int *in_progress
, struct got_worktree
*worktree
,
7709 struct got_repository
*repo
)
7711 const struct got_error
*err
;
7712 char *branch_refname
= NULL
;
7713 struct got_reference
*branch_ref
= NULL
;
7717 err
= get_merge_branch_ref_name(&branch_refname
, worktree
);
7720 err
= got_ref_open(&branch_ref
, repo
, branch_refname
, 0);
7721 free(branch_refname
);
7723 if (err
->code
!= GOT_ERR_NOT_REF
)
7731 const struct got_error
*got_worktree_merge_prepare(
7732 struct got_fileindex
**fileindex
, struct got_worktree
*worktree
,
7733 struct got_reference
*branch
, struct got_repository
*repo
)
7735 const struct got_error
*err
= NULL
;
7736 char *fileindex_path
= NULL
;
7737 char *branch_refname
= NULL
, *commit_refname
= NULL
;
7738 struct got_reference
*wt_branch
= NULL
, *branch_ref
= NULL
;
7739 struct got_reference
*commit_ref
= NULL
;
7740 struct got_object_id
*branch_tip
= NULL
, *wt_branch_tip
= NULL
;
7741 struct check_rebase_ok_arg ok_arg
;
7745 err
= lock_worktree(worktree
, LOCK_EX
);
7749 err
= open_fileindex(fileindex
, &fileindex_path
, worktree
);
7753 /* Preconditions are the same as for rebase. */
7754 ok_arg
.worktree
= worktree
;
7756 err
= got_fileindex_for_each_entry_safe(*fileindex
, check_rebase_ok
,
7761 err
= get_merge_branch_ref_name(&branch_refname
, worktree
);
7765 err
= get_merge_commit_ref_name(&commit_refname
, worktree
);
7769 err
= got_ref_open(&wt_branch
, repo
, worktree
->head_ref_name
,
7774 err
= got_ref_resolve(&wt_branch_tip
, repo
, wt_branch
);
7778 if (got_object_id_cmp(worktree
->base_commit_id
, wt_branch_tip
) != 0) {
7779 err
= got_error(GOT_ERR_MERGE_OUT_OF_DATE
);
7783 err
= got_ref_resolve(&branch_tip
, repo
, branch
);
7787 err
= got_ref_alloc_symref(&branch_ref
, branch_refname
, branch
);
7790 err
= got_ref_write(branch_ref
, repo
);
7794 err
= got_ref_alloc(&commit_ref
, commit_refname
, branch_tip
);
7797 err
= got_ref_write(commit_ref
, repo
);
7802 free(branch_refname
);
7803 free(commit_refname
);
7804 free(fileindex_path
);
7806 got_ref_close(branch_ref
);
7808 got_ref_close(commit_ref
);
7810 got_ref_close(wt_branch
);
7811 free(wt_branch_tip
);
7814 got_fileindex_free(*fileindex
);
7817 lock_worktree(worktree
, LOCK_SH
);
7822 const struct got_error
*
7823 got_worktree_merge_continue(char **branch_name
,
7824 struct got_object_id
**branch_tip
, struct got_fileindex
**fileindex
,
7825 struct got_worktree
*worktree
, struct got_repository
*repo
)
7827 const struct got_error
*err
;
7828 char *commit_refname
= NULL
, *branch_refname
= NULL
;
7829 struct got_reference
*commit_ref
= NULL
, *branch_ref
= NULL
;
7830 char *fileindex_path
= NULL
;
7831 int have_staged_files
= 0;
7833 *branch_name
= NULL
;
7837 err
= lock_worktree(worktree
, LOCK_EX
);
7841 err
= open_fileindex(fileindex
, &fileindex_path
, worktree
);
7845 err
= got_fileindex_for_each_entry_safe(*fileindex
, check_staged_file
,
7846 &have_staged_files
);
7847 if (err
&& err
->code
!= GOT_ERR_CANCELLED
)
7849 if (have_staged_files
) {
7850 err
= got_error(GOT_ERR_STAGED_PATHS
);
7854 err
= get_merge_branch_ref_name(&branch_refname
, worktree
);
7858 err
= get_merge_commit_ref_name(&commit_refname
, worktree
);
7862 err
= got_ref_open(&branch_ref
, repo
, branch_refname
, 0);
7866 if (!got_ref_is_symbolic(branch_ref
)) {
7867 err
= got_error_fmt(GOT_ERR_BAD_REF_TYPE
,
7868 "%s is not a symbolic reference",
7869 got_ref_get_name(branch_ref
));
7872 *branch_name
= strdup(got_ref_get_symref_target(branch_ref
));
7873 if (*branch_name
== NULL
) {
7874 err
= got_error_from_errno("strdup");
7878 err
= got_ref_open(&commit_ref
, repo
, commit_refname
, 0);
7882 err
= got_ref_resolve(branch_tip
, repo
, commit_ref
);
7886 free(commit_refname
);
7887 free(branch_refname
);
7888 free(fileindex_path
);
7890 got_ref_close(commit_ref
);
7892 got_ref_close(branch_ref
);
7896 *branch_name
= NULL
;
7901 got_fileindex_free(*fileindex
);
7904 lock_worktree(worktree
, LOCK_SH
);
7909 const struct got_error
*
7910 got_worktree_merge_abort(struct got_worktree
*worktree
,
7911 struct got_fileindex
*fileindex
, struct got_repository
*repo
,
7912 got_worktree_checkout_cb progress_cb
, void *progress_arg
)
7914 const struct got_error
*err
, *unlockerr
, *sync_err
;
7915 struct got_object_id
*commit_id
= NULL
;
7916 struct got_commit_object
*commit
= NULL
;
7917 char *fileindex_path
= NULL
;
7918 struct revert_file_args rfa
;
7919 struct got_object_id
*tree_id
= NULL
;
7921 err
= got_object_open_as_commit(&commit
, repo
,
7922 worktree
->base_commit_id
);
7926 err
= got_object_id_by_path(&tree_id
, repo
, commit
,
7927 worktree
->path_prefix
);
7931 err
= delete_merge_refs(worktree
, repo
);
7935 err
= get_fileindex_path(&fileindex_path
, worktree
);
7939 rfa
.worktree
= worktree
;
7940 rfa
.fileindex
= fileindex
;
7941 rfa
.progress_cb
= progress_cb
;
7942 rfa
.progress_arg
= progress_arg
;
7943 rfa
.patch_cb
= NULL
;
7944 rfa
.patch_arg
= NULL
;
7946 rfa
.unlink_added_files
= 1;
7947 err
= worktree_status(worktree
, "", fileindex
, repo
,
7948 revert_file
, &rfa
, NULL
, NULL
, 1, 0);
7952 err
= checkout_files(worktree
, fileindex
, "", tree_id
, NULL
,
7953 repo
, progress_cb
, progress_arg
, NULL
, NULL
);
7955 sync_err
= sync_fileindex(fileindex
, fileindex_path
);
7956 if (sync_err
&& err
== NULL
)
7962 got_object_commit_close(commit
);
7964 got_fileindex_free(fileindex
);
7965 free(fileindex_path
);
7967 unlockerr
= lock_worktree(worktree
, LOCK_SH
);
7968 if (unlockerr
&& err
== NULL
)
7973 struct check_stage_ok_arg
{
7974 struct got_object_id
*head_commit_id
;
7975 struct got_worktree
*worktree
;
7976 struct got_fileindex
*fileindex
;
7977 struct got_repository
*repo
;
7981 static const struct got_error
*
7982 check_stage_ok(void *arg
, unsigned char status
,
7983 unsigned char staged_status
, const char *relpath
,
7984 struct got_object_id
*blob_id
, struct got_object_id
*staged_blob_id
,
7985 struct got_object_id
*commit_id
, int dirfd
, const char *de_name
)
7987 struct check_stage_ok_arg
*a
= arg
;
7988 const struct got_error
*err
= NULL
;
7989 struct got_fileindex_entry
*ie
;
7990 struct got_object_id base_commit_id
;
7991 struct got_object_id
*base_commit_idp
= NULL
;
7992 char *in_repo_path
= NULL
, *p
;
7994 if (status
== GOT_STATUS_UNVERSIONED
||
7995 status
== GOT_STATUS_NO_CHANGE
)
7997 if (status
== GOT_STATUS_NONEXISTENT
)
7998 return got_error_set_errno(ENOENT
, relpath
);
8000 ie
= got_fileindex_entry_get(a
->fileindex
, relpath
, strlen(relpath
));
8002 return got_error_path(relpath
, GOT_ERR_FILE_STATUS
);
8004 if (asprintf(&in_repo_path
, "%s%s%s", a
->worktree
->path_prefix
,
8005 got_path_is_root_dir(a
->worktree
->path_prefix
) ? "" : "/",
8007 return got_error_from_errno("asprintf");
8009 if (got_fileindex_entry_has_commit(ie
)) {
8010 memcpy(base_commit_id
.sha1
, ie
->commit_sha1
,
8011 SHA1_DIGEST_LENGTH
);
8012 base_commit_idp
= &base_commit_id
;
8015 if (status
== GOT_STATUS_CONFLICT
) {
8016 err
= got_error_path(ie
->path
, GOT_ERR_STAGE_CONFLICT
);
8018 } else if (status
!= GOT_STATUS_ADD
&&
8019 status
!= GOT_STATUS_MODIFY
&&
8020 status
!= GOT_STATUS_DELETE
) {
8021 err
= got_error_path(ie
->path
, GOT_ERR_FILE_STATUS
);
8025 a
->have_changes
= 1;
8030 err
= check_out_of_date(p
, status
, staged_status
,
8031 blob_id
, base_commit_idp
, a
->head_commit_id
, a
->repo
,
8032 GOT_ERR_STAGE_OUT_OF_DATE
);
8038 struct stage_path_arg
{
8039 struct got_worktree
*worktree
;
8040 struct got_fileindex
*fileindex
;
8041 struct got_repository
*repo
;
8042 got_worktree_status_cb status_cb
;
8044 got_worktree_patch_cb patch_cb
;
8046 int staged_something
;
8047 int allow_bad_symlinks
;
8050 static const struct got_error
*
8051 stage_path(void *arg
, unsigned char status
,
8052 unsigned char staged_status
, const char *relpath
,
8053 struct got_object_id
*blob_id
, struct got_object_id
*staged_blob_id
,
8054 struct got_object_id
*commit_id
, int dirfd
, const char *de_name
)
8056 struct stage_path_arg
*a
= arg
;
8057 const struct got_error
*err
= NULL
;
8058 struct got_fileindex_entry
*ie
;
8059 char *ondisk_path
= NULL
, *path_content
= NULL
;
8061 struct got_object_id
*new_staged_blob_id
= NULL
;
8064 if (status
== GOT_STATUS_UNVERSIONED
)
8067 ie
= got_fileindex_entry_get(a
->fileindex
, relpath
, strlen(relpath
));
8069 return got_error_path(relpath
, GOT_ERR_FILE_STATUS
);
8071 if (asprintf(&ondisk_path
, "%s/%s", a
->worktree
->root_path
,
8073 return got_error_from_errno("asprintf");
8076 case GOT_STATUS_ADD
:
8077 case GOT_STATUS_MODIFY
:
8078 /* XXX could sb.st_mode be passed in by our caller? */
8079 if (lstat(ondisk_path
, &sb
) == -1) {
8080 err
= got_error_from_errno2("lstat", ondisk_path
);
8084 if (status
== GOT_STATUS_ADD
) {
8085 int choice
= GOT_PATCH_CHOICE_NONE
;
8086 err
= (*a
->patch_cb
)(&choice
, a
->patch_arg
,
8087 status
, ie
->path
, NULL
, 1, 1);
8090 if (choice
!= GOT_PATCH_CHOICE_YES
)
8093 err
= create_patched_content(&path_content
, 0,
8094 staged_blob_id
? staged_blob_id
: blob_id
,
8095 ondisk_path
, dirfd
, de_name
, ie
->path
,
8096 a
->repo
, a
->patch_cb
, a
->patch_arg
);
8097 if (err
|| path_content
== NULL
)
8101 err
= got_object_blob_create(&new_staged_blob_id
,
8102 path_content
? path_content
: ondisk_path
, a
->repo
);
8105 memcpy(ie
->staged_blob_sha1
, new_staged_blob_id
->sha1
,
8106 SHA1_DIGEST_LENGTH
);
8107 if (status
== GOT_STATUS_ADD
|| staged_status
== GOT_STATUS_ADD
)
8108 stage
= GOT_FILEIDX_STAGE_ADD
;
8110 stage
= GOT_FILEIDX_STAGE_MODIFY
;
8111 got_fileindex_entry_stage_set(ie
, stage
);
8112 if (S_ISLNK(sb
.st_mode
)) {
8113 int is_bad_symlink
= 0;
8114 if (!a
->allow_bad_symlinks
) {
8115 char target_path
[PATH_MAX
];
8117 target_len
= readlink(ondisk_path
, target_path
,
8118 sizeof(target_path
));
8119 if (target_len
== -1) {
8120 err
= got_error_from_errno2("readlink",
8124 err
= is_bad_symlink_target(&is_bad_symlink
,
8125 target_path
, target_len
, ondisk_path
,
8126 a
->worktree
->root_path
);
8129 if (is_bad_symlink
) {
8130 err
= got_error_path(ondisk_path
,
8131 GOT_ERR_BAD_SYMLINK
);
8136 got_fileindex_entry_staged_filetype_set(ie
,
8137 GOT_FILEIDX_MODE_BAD_SYMLINK
);
8139 got_fileindex_entry_staged_filetype_set(ie
,
8140 GOT_FILEIDX_MODE_SYMLINK
);
8142 got_fileindex_entry_staged_filetype_set(ie
,
8143 GOT_FILEIDX_MODE_REGULAR_FILE
);
8145 a
->staged_something
= 1;
8146 if (a
->status_cb
== NULL
)
8148 err
= (*a
->status_cb
)(a
->status_arg
, GOT_STATUS_NO_CHANGE
,
8149 get_staged_status(ie
), relpath
, blob_id
,
8150 new_staged_blob_id
, NULL
, dirfd
, de_name
);
8154 * When staging the reverse of the staged diff,
8155 * implicitly unstage the file.
8157 if (memcmp(ie
->staged_blob_sha1
, ie
->blob_sha1
,
8158 sizeof(ie
->blob_sha1
)) == 0) {
8159 got_fileindex_entry_stage_set(ie
,
8160 GOT_FILEIDX_STAGE_NONE
);
8163 case GOT_STATUS_DELETE
:
8164 if (staged_status
== GOT_STATUS_DELETE
)
8167 int choice
= GOT_PATCH_CHOICE_NONE
;
8168 err
= (*a
->patch_cb
)(&choice
, a
->patch_arg
, status
,
8169 ie
->path
, NULL
, 1, 1);
8172 if (choice
== GOT_PATCH_CHOICE_NO
)
8174 if (choice
!= GOT_PATCH_CHOICE_YES
) {
8175 err
= got_error(GOT_ERR_PATCH_CHOICE
);
8179 stage
= GOT_FILEIDX_STAGE_DELETE
;
8180 got_fileindex_entry_stage_set(ie
, stage
);
8181 a
->staged_something
= 1;
8182 if (a
->status_cb
== NULL
)
8184 err
= (*a
->status_cb
)(a
->status_arg
, GOT_STATUS_NO_CHANGE
,
8185 get_staged_status(ie
), relpath
, NULL
, NULL
, NULL
, dirfd
,
8188 case GOT_STATUS_NO_CHANGE
:
8190 case GOT_STATUS_CONFLICT
:
8191 err
= got_error_path(relpath
, GOT_ERR_STAGE_CONFLICT
);
8193 case GOT_STATUS_NONEXISTENT
:
8194 err
= got_error_set_errno(ENOENT
, relpath
);
8197 err
= got_error_path(relpath
, GOT_ERR_FILE_STATUS
);
8201 if (path_content
&& unlink(path_content
) == -1 && err
== NULL
)
8202 err
= got_error_from_errno2("unlink", path_content
);
8205 free(new_staged_blob_id
);
8209 const struct got_error
*
8210 got_worktree_stage(struct got_worktree
*worktree
,
8211 struct got_pathlist_head
*paths
,
8212 got_worktree_status_cb status_cb
, void *status_arg
,
8213 got_worktree_patch_cb patch_cb
, void *patch_arg
,
8214 int allow_bad_symlinks
, struct got_repository
*repo
)
8216 const struct got_error
*err
= NULL
, *sync_err
, *unlockerr
;
8217 struct got_pathlist_entry
*pe
;
8218 struct got_fileindex
*fileindex
= NULL
;
8219 char *fileindex_path
= NULL
;
8220 struct got_reference
*head_ref
= NULL
;
8221 struct got_object_id
*head_commit_id
= NULL
;
8222 struct check_stage_ok_arg oka
;
8223 struct stage_path_arg spa
;
8225 err
= lock_worktree(worktree
, LOCK_EX
);
8229 err
= got_ref_open(&head_ref
, repo
,
8230 got_worktree_get_head_ref_name(worktree
), 0);
8233 err
= got_ref_resolve(&head_commit_id
, repo
, head_ref
);
8236 err
= open_fileindex(&fileindex
, &fileindex_path
, worktree
);
8240 /* Check pre-conditions before staging anything. */
8241 oka
.head_commit_id
= head_commit_id
;
8242 oka
.worktree
= worktree
;
8243 oka
.fileindex
= fileindex
;
8245 oka
.have_changes
= 0;
8246 TAILQ_FOREACH(pe
, paths
, entry
) {
8247 err
= worktree_status(worktree
, pe
->path
, fileindex
, repo
,
8248 check_stage_ok
, &oka
, NULL
, NULL
, 1, 0);
8252 if (!oka
.have_changes
) {
8253 err
= got_error(GOT_ERR_STAGE_NO_CHANGE
);
8257 spa
.worktree
= worktree
;
8258 spa
.fileindex
= fileindex
;
8260 spa
.patch_cb
= patch_cb
;
8261 spa
.patch_arg
= patch_arg
;
8262 spa
.status_cb
= status_cb
;
8263 spa
.status_arg
= status_arg
;
8264 spa
.staged_something
= 0;
8265 spa
.allow_bad_symlinks
= allow_bad_symlinks
;
8266 TAILQ_FOREACH(pe
, paths
, entry
) {
8267 err
= worktree_status(worktree
, pe
->path
, fileindex
, repo
,
8268 stage_path
, &spa
, NULL
, NULL
, 1, 0);
8272 if (!spa
.staged_something
) {
8273 err
= got_error(GOT_ERR_STAGE_NO_CHANGE
);
8277 sync_err
= sync_fileindex(fileindex
, fileindex_path
);
8278 if (sync_err
&& err
== NULL
)
8282 got_ref_close(head_ref
);
8283 free(head_commit_id
);
8284 free(fileindex_path
);
8286 got_fileindex_free(fileindex
);
8287 unlockerr
= lock_worktree(worktree
, LOCK_SH
);
8288 if (unlockerr
&& err
== NULL
)
8293 struct unstage_path_arg
{
8294 struct got_worktree
*worktree
;
8295 struct got_fileindex
*fileindex
;
8296 struct got_repository
*repo
;
8297 got_worktree_checkout_cb progress_cb
;
8299 got_worktree_patch_cb patch_cb
;
8303 static const struct got_error
*
8304 create_unstaged_content(char **path_unstaged_content
,
8305 char **path_new_staged_content
, struct got_object_id
*blob_id
,
8306 struct got_object_id
*staged_blob_id
, const char *relpath
,
8307 struct got_repository
*repo
,
8308 got_worktree_patch_cb patch_cb
, void *patch_arg
)
8310 const struct got_error
*err
, *free_err
;
8311 struct got_blob_object
*blob
= NULL
, *staged_blob
= NULL
;
8312 FILE *f1
= NULL
, *f2
= NULL
, *outfile
= NULL
, *rejectfile
= NULL
;
8313 char *path1
= NULL
, *path2
= NULL
, *label1
= NULL
;
8314 struct got_diffreg_result
*diffreg_result
= NULL
;
8315 int line_cur1
= 1, line_cur2
= 1, n
= 0, nchunks_used
= 0;
8316 int have_content
= 0, have_rejected_content
= 0, i
= 0, nchanges
= 0;
8317 int fd1
= -1, fd2
= -1;
8319 *path_unstaged_content
= NULL
;
8320 *path_new_staged_content
= NULL
;
8322 err
= got_object_id_str(&label1
, blob_id
);
8326 fd1
= got_opentempfd();
8328 err
= got_error_from_errno("got_opentempfd");
8331 fd2
= got_opentempfd();
8333 err
= got_error_from_errno("got_opentempfd");
8337 err
= got_object_open_as_blob(&blob
, repo
, blob_id
, 8192, fd1
);
8341 err
= got_opentemp_named(&path1
, &f1
, "got-unstage-blob-base");
8345 err
= got_object_blob_dump_to_file(NULL
, NULL
, NULL
, f1
, blob
);
8349 err
= got_object_open_as_blob(&staged_blob
, repo
, staged_blob_id
, 8192,
8354 err
= got_opentemp_named(&path2
, &f2
, "got-unstage-blob-staged");
8358 err
= got_object_blob_dump_to_file(NULL
, NULL
, NULL
, f2
, staged_blob
);
8362 err
= got_diff_files(&diffreg_result
, f1
, 1, label1
, f2
, 1,
8363 path2
, 3, 0, 1, NULL
, GOT_DIFF_ALGORITHM_MYERS
);
8367 err
= got_opentemp_named(path_unstaged_content
, &outfile
,
8368 "got-unstaged-content");
8371 err
= got_opentemp_named(path_new_staged_content
, &rejectfile
,
8372 "got-new-staged-content");
8376 if (fseek(f1
, 0L, SEEK_SET
) == -1) {
8377 err
= got_ferror(f1
, GOT_ERR_IO
);
8380 if (fseek(f2
, 0L, SEEK_SET
) == -1) {
8381 err
= got_ferror(f2
, GOT_ERR_IO
);
8384 /* Count the number of actual changes in the diff result. */
8385 for (n
= 0; n
< diffreg_result
->result
->chunks
.len
; n
+= nchunks_used
) {
8386 struct diff_chunk_context cc
= {};
8387 diff_chunk_context_load_change(&cc
, &nchunks_used
,
8388 diffreg_result
->result
, n
, 0);
8391 for (n
= 0; n
< diffreg_result
->result
->chunks
.len
; n
+= nchunks_used
) {
8393 err
= apply_or_reject_change(&choice
, &nchunks_used
,
8394 diffreg_result
->result
, n
, relpath
, f1
, f2
,
8395 &line_cur1
, &line_cur2
,
8396 outfile
, rejectfile
, ++i
, nchanges
, patch_cb
, patch_arg
);
8399 if (choice
== GOT_PATCH_CHOICE_YES
)
8402 have_rejected_content
= 1;
8403 if (choice
== GOT_PATCH_CHOICE_QUIT
)
8406 if (have_content
|| have_rejected_content
)
8407 err
= copy_remaining_content(f1
, f2
, &line_cur1
, &line_cur2
,
8408 outfile
, rejectfile
);
8411 if (fd1
!= -1 && close(fd1
) == -1 && err
== NULL
)
8412 err
= got_error_from_errno("close");
8414 got_object_blob_close(blob
);
8415 if (fd2
!= -1 && close(fd2
) == -1 && err
== NULL
)
8416 err
= got_error_from_errno("close");
8418 got_object_blob_close(staged_blob
);
8419 free_err
= got_diffreg_result_free(diffreg_result
);
8420 if (free_err
&& err
== NULL
)
8422 if (f1
&& fclose(f1
) == EOF
&& err
== NULL
)
8423 err
= got_error_from_errno2("fclose", path1
);
8424 if (f2
&& fclose(f2
) == EOF
&& err
== NULL
)
8425 err
= got_error_from_errno2("fclose", path2
);
8426 if (outfile
&& fclose(outfile
) == EOF
&& err
== NULL
)
8427 err
= got_error_from_errno2("fclose", *path_unstaged_content
);
8428 if (rejectfile
&& fclose(rejectfile
) == EOF
&& err
== NULL
)
8429 err
= got_error_from_errno2("fclose", *path_new_staged_content
);
8430 if (path1
&& unlink(path1
) == -1 && err
== NULL
)
8431 err
= got_error_from_errno2("unlink", path1
);
8432 if (path2
&& unlink(path2
) == -1 && err
== NULL
)
8433 err
= got_error_from_errno2("unlink", path2
);
8434 if (err
|| !have_content
) {
8435 if (*path_unstaged_content
&&
8436 unlink(*path_unstaged_content
) == -1 && err
== NULL
)
8437 err
= got_error_from_errno2("unlink",
8438 *path_unstaged_content
);
8439 free(*path_unstaged_content
);
8440 *path_unstaged_content
= NULL
;
8442 if (err
|| !have_content
|| !have_rejected_content
) {
8443 if (*path_new_staged_content
&&
8444 unlink(*path_new_staged_content
) == -1 && err
== NULL
)
8445 err
= got_error_from_errno2("unlink",
8446 *path_new_staged_content
);
8447 free(*path_new_staged_content
);
8448 *path_new_staged_content
= NULL
;
8455 static const struct got_error
*
8456 unstage_hunks(struct got_object_id
*staged_blob_id
,
8457 struct got_blob_object
*blob_base
,
8458 struct got_object_id
*blob_id
, struct got_fileindex_entry
*ie
,
8459 const char *ondisk_path
, const char *label_orig
,
8460 struct got_worktree
*worktree
, struct got_repository
*repo
,
8461 got_worktree_patch_cb patch_cb
, void *patch_arg
,
8462 got_worktree_checkout_cb progress_cb
, void *progress_arg
)
8464 const struct got_error
*err
= NULL
;
8465 char *path_unstaged_content
= NULL
;
8466 char *path_new_staged_content
= NULL
;
8467 char *parent
= NULL
, *base_path
= NULL
;
8468 char *blob_base_path
= NULL
;
8469 struct got_object_id
*new_staged_blob_id
= NULL
;
8470 FILE *f
= NULL
, *f_base
= NULL
, *f_deriv2
= NULL
;
8473 err
= create_unstaged_content(&path_unstaged_content
,
8474 &path_new_staged_content
, blob_id
, staged_blob_id
,
8475 ie
->path
, repo
, patch_cb
, patch_arg
);
8479 if (path_unstaged_content
== NULL
)
8482 if (path_new_staged_content
) {
8483 err
= got_object_blob_create(&new_staged_blob_id
,
8484 path_new_staged_content
, repo
);
8489 f
= fopen(path_unstaged_content
, "re");
8491 err
= got_error_from_errno2("fopen",
8492 path_unstaged_content
);
8495 if (fstat(fileno(f
), &sb
) == -1) {
8496 err
= got_error_from_errno2("fstat", path_unstaged_content
);
8499 if (got_fileindex_entry_staged_filetype_get(ie
) ==
8500 GOT_FILEIDX_MODE_SYMLINK
&& sb
.st_size
< PATH_MAX
) {
8501 char link_target
[PATH_MAX
];
8503 r
= fread(link_target
, 1, sizeof(link_target
), f
);
8504 if (r
== 0 && ferror(f
)) {
8505 err
= got_error_from_errno("fread");
8508 if (r
>= sizeof(link_target
)) { /* should not happen */
8509 err
= got_error(GOT_ERR_NO_SPACE
);
8512 link_target
[r
] = '\0';
8513 err
= merge_symlink(worktree
, blob_base
,
8514 ondisk_path
, ie
->path
, label_orig
, link_target
,
8515 worktree
->base_commit_id
, repo
, progress_cb
,
8518 int local_changes_subsumed
;
8520 err
= got_path_dirname(&parent
, ondisk_path
);
8524 if (asprintf(&base_path
, "%s/got-unstage-blob-orig",
8526 err
= got_error_from_errno("asprintf");
8531 err
= got_opentemp_named(&blob_base_path
, &f_base
, base_path
);
8534 err
= got_object_blob_dump_to_file(NULL
, NULL
, NULL
, f_base
,
8540 * In order the run a 3-way merge with a symlink we copy the symlink's
8541 * target path into a temporary file and use that file with diff3.
8543 if (S_ISLNK(got_fileindex_perms_to_st(ie
))) {
8544 err
= dump_symlink_target_path_to_file(&f_deriv2
,
8550 fd
= open(ondisk_path
,
8551 O_RDONLY
| O_NOFOLLOW
| O_CLOEXEC
);
8553 err
= got_error_from_errno2("open", ondisk_path
);
8556 f_deriv2
= fdopen(fd
, "r");
8557 if (f_deriv2
== NULL
) {
8558 err
= got_error_from_errno2("fdopen", ondisk_path
);
8564 err
= merge_file(&local_changes_subsumed
, worktree
,
8565 f_base
, f
, f_deriv2
, ondisk_path
, ie
->path
,
8566 got_fileindex_perms_to_st(ie
),
8567 label_orig
, "unstaged", NULL
, GOT_DIFF_ALGORITHM_MYERS
,
8568 repo
, progress_cb
, progress_arg
);
8573 if (new_staged_blob_id
) {
8574 memcpy(ie
->staged_blob_sha1
, new_staged_blob_id
->sha1
,
8575 SHA1_DIGEST_LENGTH
);
8577 got_fileindex_entry_stage_set(ie
, GOT_FILEIDX_STAGE_NONE
);
8578 got_fileindex_entry_staged_filetype_set(ie
, 0);
8581 free(new_staged_blob_id
);
8582 if (path_unstaged_content
&&
8583 unlink(path_unstaged_content
) == -1 && err
== NULL
)
8584 err
= got_error_from_errno2("unlink", path_unstaged_content
);
8585 if (path_new_staged_content
&&
8586 unlink(path_new_staged_content
) == -1 && err
== NULL
)
8587 err
= got_error_from_errno2("unlink", path_new_staged_content
);
8588 if (blob_base_path
&& unlink(blob_base_path
) == -1 && err
== NULL
)
8589 err
= got_error_from_errno2("unlink", blob_base_path
);
8590 if (f_base
&& fclose(f_base
) == EOF
&& err
== NULL
)
8591 err
= got_error_from_errno2("fclose", path_unstaged_content
);
8592 if (f
&& fclose(f
) == EOF
&& err
== NULL
)
8593 err
= got_error_from_errno2("fclose", path_unstaged_content
);
8594 if (f_deriv2
&& fclose(f_deriv2
) == EOF
&& err
== NULL
)
8595 err
= got_error_from_errno2("fclose", ondisk_path
);
8596 free(path_unstaged_content
);
8597 free(path_new_staged_content
);
8598 free(blob_base_path
);
8604 static const struct got_error
*
8605 unstage_path(void *arg
, unsigned char status
,
8606 unsigned char staged_status
, const char *relpath
,
8607 struct got_object_id
*blob_id
, struct got_object_id
*staged_blob_id
,
8608 struct got_object_id
*commit_id
, int dirfd
, const char *de_name
)
8610 const struct got_error
*err
= NULL
;
8611 struct unstage_path_arg
*a
= arg
;
8612 struct got_fileindex_entry
*ie
;
8613 struct got_blob_object
*blob_base
= NULL
, *blob_staged
= NULL
;
8614 char *ondisk_path
= NULL
;
8615 char *id_str
= NULL
, *label_orig
= NULL
;
8616 int local_changes_subsumed
;
8618 int fd1
= -1, fd2
= -1;
8620 if (staged_status
!= GOT_STATUS_ADD
&&
8621 staged_status
!= GOT_STATUS_MODIFY
&&
8622 staged_status
!= GOT_STATUS_DELETE
)
8625 ie
= got_fileindex_entry_get(a
->fileindex
, relpath
, strlen(relpath
));
8627 return got_error_path(relpath
, GOT_ERR_FILE_STATUS
);
8629 if (asprintf(&ondisk_path
, "%s/%s", a
->worktree
->root_path
, relpath
)
8631 return got_error_from_errno("asprintf");
8633 err
= got_object_id_str(&id_str
,
8634 commit_id
? commit_id
: a
->worktree
->base_commit_id
);
8637 if (asprintf(&label_orig
, "%s: commit %s", GOT_MERGE_LABEL_BASE
,
8639 err
= got_error_from_errno("asprintf");
8643 fd1
= got_opentempfd();
8645 err
= got_error_from_errno("got_opentempfd");
8648 fd2
= got_opentempfd();
8650 err
= got_error_from_errno("got_opentempfd");
8654 switch (staged_status
) {
8655 case GOT_STATUS_MODIFY
:
8656 err
= got_object_open_as_blob(&blob_base
, a
->repo
,
8657 blob_id
, 8192, fd1
);
8661 case GOT_STATUS_ADD
:
8663 if (staged_status
== GOT_STATUS_ADD
) {
8664 int choice
= GOT_PATCH_CHOICE_NONE
;
8665 err
= (*a
->patch_cb
)(&choice
, a
->patch_arg
,
8666 staged_status
, ie
->path
, NULL
, 1, 1);
8669 if (choice
!= GOT_PATCH_CHOICE_YES
)
8672 err
= unstage_hunks(staged_blob_id
,
8673 blob_base
, blob_id
, ie
, ondisk_path
,
8674 label_orig
, a
->worktree
, a
->repo
,
8675 a
->patch_cb
, a
->patch_arg
,
8676 a
->progress_cb
, a
->progress_arg
);
8677 break; /* Done with this file. */
8680 err
= got_object_open_as_blob(&blob_staged
, a
->repo
,
8681 staged_blob_id
, 8192, fd2
);
8684 switch (got_fileindex_entry_staged_filetype_get(ie
)) {
8685 case GOT_FILEIDX_MODE_BAD_SYMLINK
:
8686 case GOT_FILEIDX_MODE_REGULAR_FILE
:
8687 err
= merge_blob(&local_changes_subsumed
, a
->worktree
,
8688 blob_base
, ondisk_path
, relpath
,
8689 got_fileindex_perms_to_st(ie
), label_orig
,
8690 blob_staged
, commit_id
? commit_id
:
8691 a
->worktree
->base_commit_id
, a
->repo
,
8692 a
->progress_cb
, a
->progress_arg
);
8694 case GOT_FILEIDX_MODE_SYMLINK
:
8695 if (S_ISLNK(got_fileindex_perms_to_st(ie
))) {
8696 char *staged_target
;
8697 err
= got_object_blob_read_to_str(
8698 &staged_target
, blob_staged
);
8701 err
= merge_symlink(a
->worktree
, blob_base
,
8702 ondisk_path
, relpath
, label_orig
,
8703 staged_target
, commit_id
? commit_id
:
8704 a
->worktree
->base_commit_id
,
8705 a
->repo
, a
->progress_cb
, a
->progress_arg
);
8706 free(staged_target
);
8708 err
= merge_blob(&local_changes_subsumed
,
8709 a
->worktree
, blob_base
, ondisk_path
,
8710 relpath
, got_fileindex_perms_to_st(ie
),
8711 label_orig
, blob_staged
,
8712 commit_id
? commit_id
:
8713 a
->worktree
->base_commit_id
, a
->repo
,
8714 a
->progress_cb
, a
->progress_arg
);
8718 err
= got_error_path(relpath
, GOT_ERR_BAD_FILETYPE
);
8722 got_fileindex_entry_stage_set(ie
,
8723 GOT_FILEIDX_STAGE_NONE
);
8724 got_fileindex_entry_staged_filetype_set(ie
, 0);
8727 case GOT_STATUS_DELETE
:
8729 int choice
= GOT_PATCH_CHOICE_NONE
;
8730 err
= (*a
->patch_cb
)(&choice
, a
->patch_arg
,
8731 staged_status
, ie
->path
, NULL
, 1, 1);
8734 if (choice
== GOT_PATCH_CHOICE_NO
)
8736 if (choice
!= GOT_PATCH_CHOICE_YES
) {
8737 err
= got_error(GOT_ERR_PATCH_CHOICE
);
8741 got_fileindex_entry_stage_set(ie
, GOT_FILEIDX_STAGE_NONE
);
8742 got_fileindex_entry_staged_filetype_set(ie
, 0);
8743 err
= get_file_status(&status
, &sb
, ie
, ondisk_path
,
8744 dirfd
, de_name
, a
->repo
);
8747 err
= (*a
->progress_cb
)(a
->progress_arg
, status
, relpath
);
8752 if (fd1
!= -1 && close(fd1
) == -1 && err
== NULL
)
8753 err
= got_error_from_errno("close");
8755 got_object_blob_close(blob_base
);
8756 if (fd2
!= -1 && close(fd2
) == -1 && err
== NULL
)
8757 err
= got_error_from_errno("close");
8759 got_object_blob_close(blob_staged
);
8765 const struct got_error
*
8766 got_worktree_unstage(struct got_worktree
*worktree
,
8767 struct got_pathlist_head
*paths
,
8768 got_worktree_checkout_cb progress_cb
, void *progress_arg
,
8769 got_worktree_patch_cb patch_cb
, void *patch_arg
,
8770 struct got_repository
*repo
)
8772 const struct got_error
*err
= NULL
, *sync_err
, *unlockerr
;
8773 struct got_pathlist_entry
*pe
;
8774 struct got_fileindex
*fileindex
= NULL
;
8775 char *fileindex_path
= NULL
;
8776 struct unstage_path_arg upa
;
8778 err
= lock_worktree(worktree
, LOCK_EX
);
8782 err
= open_fileindex(&fileindex
, &fileindex_path
, worktree
);
8786 upa
.worktree
= worktree
;
8787 upa
.fileindex
= fileindex
;
8789 upa
.progress_cb
= progress_cb
;
8790 upa
.progress_arg
= progress_arg
;
8791 upa
.patch_cb
= patch_cb
;
8792 upa
.patch_arg
= patch_arg
;
8793 TAILQ_FOREACH(pe
, paths
, entry
) {
8794 err
= worktree_status(worktree
, pe
->path
, fileindex
, repo
,
8795 unstage_path
, &upa
, NULL
, NULL
, 1, 0);
8800 sync_err
= sync_fileindex(fileindex
, fileindex_path
);
8801 if (sync_err
&& err
== NULL
)
8804 free(fileindex_path
);
8806 got_fileindex_free(fileindex
);
8807 unlockerr
= lock_worktree(worktree
, LOCK_SH
);
8808 if (unlockerr
&& err
== NULL
)
8813 struct report_file_info_arg
{
8814 struct got_worktree
*worktree
;
8815 got_worktree_path_info_cb info_cb
;
8817 struct got_pathlist_head
*paths
;
8818 got_cancel_cb cancel_cb
;
8822 static const struct got_error
*
8823 report_file_info(void *arg
, struct got_fileindex_entry
*ie
)
8825 struct report_file_info_arg
*a
= arg
;
8826 struct got_pathlist_entry
*pe
;
8827 struct got_object_id blob_id
, staged_blob_id
, commit_id
;
8828 struct got_object_id
*blob_idp
= NULL
, *staged_blob_idp
= NULL
;
8829 struct got_object_id
*commit_idp
= NULL
;
8832 if (a
->cancel_cb
&& a
->cancel_cb(a
->cancel_arg
))
8833 return got_error(GOT_ERR_CANCELLED
);
8835 TAILQ_FOREACH(pe
, a
->paths
, entry
) {
8836 if (pe
->path_len
== 0 || strcmp(pe
->path
, ie
->path
) == 0 ||
8837 got_path_is_child(ie
->path
, pe
->path
, pe
->path_len
))
8840 if (pe
== NULL
) /* not found */
8843 if (got_fileindex_entry_has_blob(ie
)) {
8844 memcpy(blob_id
.sha1
, ie
->blob_sha1
, SHA1_DIGEST_LENGTH
);
8845 blob_idp
= &blob_id
;
8847 stage
= got_fileindex_entry_stage_get(ie
);
8848 if (stage
== GOT_FILEIDX_STAGE_MODIFY
||
8849 stage
== GOT_FILEIDX_STAGE_ADD
) {
8850 memcpy(staged_blob_id
.sha1
, ie
->staged_blob_sha1
,
8851 SHA1_DIGEST_LENGTH
);
8852 staged_blob_idp
= &staged_blob_id
;
8855 if (got_fileindex_entry_has_commit(ie
)) {
8856 memcpy(commit_id
.sha1
, ie
->commit_sha1
, SHA1_DIGEST_LENGTH
);
8857 commit_idp
= &commit_id
;
8860 return a
->info_cb(a
->info_arg
, ie
->path
, got_fileindex_perms_to_st(ie
),
8861 (time_t)ie
->mtime_sec
, blob_idp
, staged_blob_idp
, commit_idp
);
8864 const struct got_error
*
8865 got_worktree_path_info(struct got_worktree
*worktree
,
8866 struct got_pathlist_head
*paths
,
8867 got_worktree_path_info_cb info_cb
, void *info_arg
,
8868 got_cancel_cb cancel_cb
, void *cancel_arg
)
8871 const struct got_error
*err
= NULL
, *unlockerr
;
8872 struct got_fileindex
*fileindex
= NULL
;
8873 char *fileindex_path
= NULL
;
8874 struct report_file_info_arg arg
;
8876 err
= lock_worktree(worktree
, LOCK_SH
);
8880 err
= open_fileindex(&fileindex
, &fileindex_path
, worktree
);
8884 arg
.worktree
= worktree
;
8885 arg
.info_cb
= info_cb
;
8886 arg
.info_arg
= info_arg
;
8888 arg
.cancel_cb
= cancel_cb
;
8889 arg
.cancel_arg
= cancel_arg
;
8890 err
= got_fileindex_for_each_entry_safe(fileindex
, report_file_info
,
8893 free(fileindex_path
);
8895 got_fileindex_free(fileindex
);
8896 unlockerr
= lock_worktree(worktree
, LOCK_UN
);
8897 if (unlockerr
&& err
== NULL
)
8902 static const struct got_error
*
8903 patch_check_path(const char *p
, char **path
, unsigned char *status
,
8904 unsigned char *staged_status
, struct got_fileindex
*fileindex
,
8905 struct got_worktree
*worktree
, struct got_repository
*repo
)
8907 const struct got_error
*err
;
8908 struct got_fileindex_entry
*ie
;
8910 char *ondisk_path
= NULL
;
8912 err
= got_worktree_resolve_path(path
, worktree
, p
);
8916 if (asprintf(&ondisk_path
, "%s%s%s", worktree
->root_path
,
8917 *path
[0] ? "/" : "", *path
) == -1)
8918 return got_error_from_errno("asprintf");
8920 ie
= got_fileindex_entry_get(fileindex
, *path
, strlen(*path
));
8922 *staged_status
= get_staged_status(ie
);
8923 err
= get_file_status(status
, &sb
, ie
, ondisk_path
, -1, NULL
,
8928 *staged_status
= GOT_STATUS_NO_CHANGE
;
8929 *status
= GOT_STATUS_UNVERSIONED
;
8930 if (lstat(ondisk_path
, &sb
) == -1) {
8931 if (errno
!= ENOENT
) {
8932 err
= got_error_from_errno2("lstat",
8936 *status
= GOT_STATUS_NONEXISTENT
;
8945 static const struct got_error
*
8946 patch_can_rm(const char *path
, unsigned char status
,
8947 unsigned char staged_status
)
8949 if (status
== GOT_STATUS_NONEXISTENT
)
8950 return got_error_set_errno(ENOENT
, path
);
8951 if (status
!= GOT_STATUS_NO_CHANGE
&&
8952 status
!= GOT_STATUS_ADD
&&
8953 status
!= GOT_STATUS_MODIFY
&&
8954 status
!= GOT_STATUS_MODE_CHANGE
)
8955 return got_error_path(path
, GOT_ERR_FILE_STATUS
);
8956 if (staged_status
== GOT_STATUS_DELETE
)
8957 return got_error_path(path
, GOT_ERR_FILE_STATUS
);
8961 static const struct got_error
*
8962 patch_can_add(const char *path
, unsigned char status
)
8964 if (status
!= GOT_STATUS_NONEXISTENT
)
8965 return got_error_path(path
, GOT_ERR_FILE_STATUS
);
8969 static const struct got_error
*
8970 patch_can_edit(const char *path
, unsigned char status
,
8971 unsigned char staged_status
)
8973 if (status
== GOT_STATUS_NONEXISTENT
)
8974 return got_error_set_errno(ENOENT
, path
);
8975 if (status
!= GOT_STATUS_NO_CHANGE
&&
8976 status
!= GOT_STATUS_ADD
&&
8977 status
!= GOT_STATUS_MODIFY
)
8978 return got_error_path(path
, GOT_ERR_FILE_STATUS
);
8979 if (staged_status
== GOT_STATUS_DELETE
)
8980 return got_error_path(path
, GOT_ERR_FILE_STATUS
);
8984 const struct got_error
*
8985 got_worktree_patch_prepare(struct got_fileindex
**fileindex
,
8986 char **fileindex_path
, struct got_worktree
*worktree
)
8988 return open_fileindex(fileindex
, fileindex_path
, worktree
);
8991 const struct got_error
*
8992 got_worktree_patch_check_path(const char *old
, const char *new,
8993 char **oldpath
, char **newpath
, struct got_worktree
*worktree
,
8994 struct got_repository
*repo
, struct got_fileindex
*fileindex
)
8996 const struct got_error
*err
= NULL
;
8997 int file_renamed
= 0;
8998 unsigned char status_old
, staged_status_old
;
8999 unsigned char status_new
, staged_status_new
;
9004 err
= patch_check_path(old
!= NULL
? old
: new, oldpath
,
9005 &status_old
, &staged_status_old
, fileindex
, worktree
, repo
);
9009 err
= patch_check_path(new != NULL
? new : old
, newpath
,
9010 &status_new
, &staged_status_new
, fileindex
, worktree
, repo
);
9014 if (old
!= NULL
&& new != NULL
&& strcmp(old
, new) != 0)
9017 if (old
!= NULL
&& new == NULL
)
9018 err
= patch_can_rm(*oldpath
, status_old
, staged_status_old
);
9019 else if (file_renamed
) {
9020 err
= patch_can_rm(*oldpath
, status_old
, staged_status_old
);
9022 err
= patch_can_add(*newpath
, status_new
);
9023 } else if (old
== NULL
)
9024 err
= patch_can_add(*newpath
, status_new
);
9026 err
= patch_can_edit(*newpath
, status_new
, staged_status_new
);
9038 const struct got_error
*
9039 got_worktree_patch_schedule_add(const char *path
, struct got_repository
*repo
,
9040 struct got_worktree
*worktree
, struct got_fileindex
*fileindex
,
9041 got_worktree_checkout_cb progress_cb
, void *progress_arg
)
9043 struct schedule_addition_args saa
;
9045 memset(&saa
, 0, sizeof(saa
));
9046 saa
.worktree
= worktree
;
9047 saa
.fileindex
= fileindex
;
9048 saa
.progress_cb
= progress_cb
;
9049 saa
.progress_arg
= progress_arg
;
9052 return worktree_status(worktree
, path
, fileindex
, repo
,
9053 schedule_addition
, &saa
, NULL
, NULL
, 1, 0);
9056 const struct got_error
*
9057 got_worktree_patch_schedule_rm(const char *path
, struct got_repository
*repo
,
9058 struct got_worktree
*worktree
, struct got_fileindex
*fileindex
,
9059 got_worktree_delete_cb progress_cb
, void *progress_arg
)
9061 struct schedule_deletion_args sda
;
9063 memset(&sda
, 0, sizeof(sda
));
9064 sda
.worktree
= worktree
;
9065 sda
.fileindex
= fileindex
;
9066 sda
.progress_cb
= progress_cb
;
9067 sda
.progress_arg
= progress_arg
;
9069 sda
.delete_local_mods
= 0;
9070 sda
.keep_on_disk
= 0;
9071 sda
.ignore_missing_paths
= 0;
9072 sda
.status_codes
= NULL
;
9074 return worktree_status(worktree
, path
, fileindex
, repo
,
9075 schedule_for_deletion
, &sda
, NULL
, NULL
, 1, 1);
9078 const struct got_error
*
9079 got_worktree_patch_complete(struct got_fileindex
*fileindex
,
9080 const char *fileindex_path
)
9082 const struct got_error
*err
= NULL
;
9084 err
= sync_fileindex(fileindex
, fileindex_path
);
9085 got_fileindex_free(fileindex
);