commit - c631b1152565e4c18cb2123e1d3d7c08d513c02f
commit + 0aeb8099a04ea427eff4a7b6cb52b1cba62a87b0
blob - 3132285fde2f86c533ea3117e76a6f577c8fcb05
blob + 55184665f7b445e704a80de758c82371bc3a475b
--- lib/fileindex.c
+++ lib/fileindex.c
#define GOT_FILEIDX_MAX_ENTRIES INT_MAX
};
-static mode_t
-fileindex_entry_perms_get(struct got_fileindex_entry *ie)
+mode_t
+got_fileindex_entry_perms_get(struct got_fileindex_entry *ie)
{
return ((ie->mode & GOT_FILEIDX_MODE_PERMS) >>
GOT_FILEIDX_MODE_PERMS_SHIFT);
mode_t
got_fileindex_perms_to_st(struct got_fileindex_entry *ie)
{
- mode_t perms = fileindex_entry_perms_get(ie);
+ mode_t perms = got_fileindex_entry_perms_get(ie);
int type = got_fileindex_entry_filetype_get(ie);
uint32_t ftype;
blob - 8535201970c1361dcc48c9404c68333b0a77b2c5
blob + f10058320f24affa0531641620b65ac3641a9b6f
--- lib/got_lib_fileindex.h
+++ lib/got_lib_fileindex.h
uint8_t sha1[SHA1_DIGEST_LENGTH]; /* checksum of above on-disk data */
};
+mode_t got_fileindex_entry_perms_get(struct got_fileindex_entry *);
uint16_t got_fileindex_perms_from_st(struct stat *);
mode_t got_fileindex_perms_to_st(struct got_fileindex_entry *);
blob - bde4162e571552b42ca8aea844c0fb7d81ee59e3
blob + a24230cc8594d13472a3bcf7b8a5fb461cab1138
--- lib/worktree.c
+++ lib/worktree.c
struct got_pathlist_head *commitable_paths;
struct got_repository *repo;
struct got_worktree *worktree;
+ struct got_fileindex *fileindex;
int have_staged_files;
};
err = got_error_from_errno("asprintf");
goto done;
}
- if (status == GOT_STATUS_DELETE || staged_status == GOT_STATUS_DELETE) {
- sb.st_mode = GOT_DEFAULT_FILE_MODE;
- } else {
+
+ if (staged_status == GOT_STATUS_ADD ||
+ staged_status == GOT_STATUS_MODIFY) {
+ struct got_fileindex_entry *ie;
+ ie = got_fileindex_entry_get(a->fileindex, path, strlen(path));
+ switch (got_fileindex_entry_staged_filetype_get(ie)) {
+ case GOT_FILEIDX_MODE_REGULAR_FILE:
+ case GOT_FILEIDX_MODE_BAD_SYMLINK:
+ ct->mode = S_IFREG;
+ break;
+ case GOT_FILEIDX_MODE_SYMLINK:
+ ct->mode = S_IFLNK;
+ break;
+ default:
+ fprintf(stderr, "got: ie mode is 0x%x\n", ie->mode);
+ err = got_error_path(path, GOT_ERR_BAD_FILETYPE);
+ goto done;
+ }
+ ct->mode |= got_fileindex_entry_perms_get(ie);
+ } else if (status != GOT_STATUS_DELETE &&
+ staged_status != GOT_STATUS_DELETE) {
if (dirfd != -1) {
if (fstatat(dirfd, de_name, &sb,
AT_SYMLINK_NOFOLLOW) == -1) {
static const struct got_error *
reinstall_symlink_after_commit(int *is_bad_symlink, struct got_commitable *ct,
struct got_object_id *new_base_commit_id, struct got_worktree *worktree,
- struct got_repository *repo)
+ struct got_fileindex_entry *ie, struct got_repository *repo)
{
const struct got_error *err = NULL;
struct got_blob_object *blob = NULL;
struct got_tree_object *tree = NULL;
struct got_tree_entry *te;
char *entry_name;
+ unsigned char status;
+ struct stat sb;
+
+ err = get_file_status(&status, &sb, ie, ct->ondisk_path,
+ -1, NULL, repo);
+ if (err)
+ return err;
+ if (status != GOT_STATUS_NO_CHANGE)
+ return NULL;
if (ct->staged_status == GOT_STATUS_ADD ||
ct->staged_status == GOT_STATUS_MODIFY) {
ct->status == GOT_STATUS_DELETE)
continue;
+ ie = got_fileindex_entry_get(fileindex, ct->path,
+ strlen(ct->path));
+ if (ie == NULL) {
+ err = got_error_path(ct->path, GOT_ERR_BAD_PATH);
+ break;
+ }
err = reinstall_symlink_after_commit(&is_bad_symlink,
- ct, new_base_commit_id, worktree, repo);
+ ct, new_base_commit_id, worktree, ie, repo);
if (err)
break;
- ie = got_fileindex_entry_get(fileindex, ct->path,
- strlen(ct->path));
if (ie && is_bad_symlink) {
got_fileindex_entry_filetype_set(ie,
GOT_FILEIDX_MODE_BAD_SYMLINK);
cc_arg.commitable_paths = &commitable_paths;
cc_arg.worktree = worktree;
+ cc_arg.fileindex = fileindex;
cc_arg.repo = repo;
cc_arg.have_staged_files = have_staged_files;
TAILQ_FOREACH(pe, paths, entry) {
char *ondisk_path = NULL, *path_content = NULL;
uint32_t stage;
struct got_object_id *new_staged_blob_id = NULL;
+ struct stat sb;
if (status == GOT_STATUS_UNVERSIONED)
return NULL;
switch (status) {
case GOT_STATUS_ADD:
case GOT_STATUS_MODIFY:
+ /* XXX could sb.st_mode be passed in by our caller? */
+ if (lstat(ondisk_path, &sb) == -1) {
+ err = got_error_from_errno2("lstat", ondisk_path);
+ break;
+ }
if (a->patch_cb) {
if (status == GOT_STATUS_ADD) {
int choice = GOT_PATCH_CHOICE_NONE;
else
stage = GOT_FILEIDX_STAGE_MODIFY;
got_fileindex_entry_stage_set(ie, stage);
+ if (S_ISLNK(sb.st_mode)) {
+ got_fileindex_entry_staged_filetype_set(ie,
+ GOT_FILEIDX_MODE_SYMLINK);
+ } else {
+ got_fileindex_entry_staged_filetype_set(ie,
+ GOT_FILEIDX_MODE_REGULAR_FILE);
+ }
a->staged_something = 1;
if (a->status_cb == NULL)
break;
blob - 199eaf6bbf1859c535e340a5c5f30777378ba090
blob + cf4a6d0c34ede0224a4b154ee7f65844ddf9f51a
--- regress/cmdline/stage.sh
+++ regress/cmdline/stage.sh
test_done "$testroot" "$ret"
return 1
fi
+
+ rm $testroot/wt/alpha.link
+ echo 'this is regular file alpha.link' > $testroot/wt/alpha.link
(cd $testroot/wt && got diff -s > $testroot/stdout)
return 1
fi
- if ! [ -h $testroot/wt/alpha.link ]; then
- echo "alpha.link is not a symlink"
+ if [ -h $testroot/wt/alpha.link ]; then
+ echo "alpha.link is a symlink"
test_done "$testroot" "1"
return 1
fi
- readlink $testroot/wt/alpha.link > $testroot/stdout
- echo "beta" > $testroot/stdout.expected
- cmp -s $testroot/stdout.expected $testroot/stdout
+ echo 'this is regular file alpha.link' > $testroot/content.expected
+ cp $testroot/wt/alpha.link $testroot/content
+ cmp -s $testroot/content.expected $testroot/content
ret="$?"
if [ "$ret" != "0" ]; then
- diff -u $testroot/stdout.expected $testroot/stdout
+ diff -u $testroot/content.expected $testroot/content
test_done "$testroot" "$ret"
return 1
fi
test_done "$testroot" "1"
return 1
fi
- echo -n ".got/bar" >> $testroot/content.expected
+ echo -n ".got/bar" > $testroot/content.expected
cp $testroot/wt/dotgotbar.link $testroot/content
cmp -s $testroot/content.expected $testroot/content
ret="$?"