commit - bd4792ec812265a57f6e881d9bff1f297d325749
commit + 21908da4c3cfc3f2d04dd511bd59c1c877f92b14
blob - 70174aa3d9e1dc0477a3ceb497937b6acca741a4
blob + a1d12e6dbe2e63177e9e709a1659d4073b8db842
--- lib/fileindex.c
+++ lib/fileindex.c
if (!in_same_subdir(ie, parent_path, te)) {
cmp = strncmp(ie->path, parent_path, parent_len);
- if (cmp == 0)
- cmp = strcmp(ie->path + parent_len, te->name);
+ if (cmp == 0) {
+ char *ie_name = ie->path + parent_len;
+ while (ie_name[0] == '/')
+ ie_name++;
+ cmp = strcmp(ie_name, te->name);
+ }
} else {
char *ie_name = ie->path + parent_len;
while (ie_name[0] == '/')
blob - 2438bbf344f4501b2177c6b04e1a90e016407f2f
blob + 62fe285a54aaefa790d4d2c759df4e4733ec5fd0
--- lib/worktree.c
+++ lib/worktree.c
}
static const struct got_error *
+make_parent_dirs(const char *abspath)
+{
+ const struct got_error *err = NULL;
+
+ char *parent = dirname(abspath);
+ if (parent == NULL)
+ return NULL;
+
+ if (mkdir(parent, GOT_DEFAULT_DIR_MODE) == -1) {
+ if (errno == ENOENT) {
+ err = make_parent_dirs(parent);
+ if (err)
+ return err;
+ } else
+ return got_error_from_errno();
+ }
+
+ return NULL;
+}
+
+static const struct got_error *
add_dir_on_disk(struct got_worktree *worktree, const char *path)
{
const struct got_error *err = NULL;
if (mkdir(abspath, GOT_DEFAULT_DIR_MODE) == -1) {
struct stat sb;
- if (errno != EEXIST) {
- err = got_error_from_errno();
- goto done;
+ if (errno == EEXIST) {
+ if (lstat(abspath, &sb) == -1) {
+ err = got_error_from_errno();
+ goto done;
+ }
+
+ if (!S_ISDIR(sb.st_mode)) {
+ /* TODO directory is obstructed; do something */
+ return got_error(GOT_ERR_FILE_OBSTRUCTED);
+ }
+
+ return NULL;
}
- if (lstat(abspath, &sb) == -1) {
+ if (errno == ENOENT) {
+ err = make_parent_dirs(abspath);
+ if (err)
+ return err;
+ if (mkdir(abspath, GOT_DEFAULT_DIR_MODE) == 0)
+ return NULL;
+ } else {
err = got_error_from_errno();
goto done;
}
-
- if (!S_ISDIR(sb.st_mode)) {
- /* TODO directory is obstructed; do something */
- return got_error(GOT_ERR_FILE_OBSTRUCTED);
- }
}
done:
fd = open(ondisk_path, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW,
GOT_DEFAULT_FILE_MODE);
if (fd == -1) {
- if (errno == EEXIST) {
+ if (errno == ENOENT) {
+ char *parent = dirname(path);
+ if (parent == NULL)
+ return got_error_from_errno();
+ err = add_dir_on_disk(worktree, parent);
+ if (err)
+ return err;
+ fd = open(ondisk_path,
+ O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW,
+ GOT_DEFAULT_FILE_MODE);
+ if (fd == -1)
+ return got_error_from_errno();
+ } else if (errno == EEXIST) {
struct stat sb;
if (lstat(ondisk_path, &sb) == -1) {
err = got_error_from_errno();
blob - b121574a4f98dd2f74a69c2a49cd1b5f6081c721
blob + 61f3c4d796ad5f9b6b1d8d33f6594411e2d40b22
--- regress/cmdline/update.sh
+++ regress/cmdline/update.sh
(cd $testroot/repo && git mv epsilon/psi/chi/tau epsilon/psi/tau)
git_commit $testroot/repo -m "moving files upwards"
- echo "D epsilon/psi/chi/tau" > $testroot/stdout.expected
+ echo "A epsilon/mu" > $testroot/stdout.expected
+ echo "D epsilon/psi/chi/tau" >> $testroot/stdout.expected
echo "D epsilon/psi/mu" >> $testroot/stdout.expected
- echo "A epsilon/mu" >> $testroot/stdout.expected
echo "A epsilon/psi/tau" >> $testroot/stdout.expected
echo -n "Updated to commit " >> $testroot/stdout.expected
git_show_head $testroot/repo >> $testroot/stdout.expected
test_done "$testroot" "0"
}
+
+function test_update_file_in_subsubdir {
+ local testroot=`test_init update_fle_in_subsubdir no_tree`
+ touch $testroot/repo/Makefile
+ mkdir -p $testroot/repo/altq
+ touch $testroot/repo/altq/if_altq.h
+ mkdir -p $testroot/repo/arch/alpha
+ touch $testroot/repo/arch/alpha/Makefile
+ (cd $testroot/repo && git add .)
+ git_commit $testroot/repo -m "adding initial tree"
+
+ got checkout $testroot/repo $testroot/wt > /dev/null
+ if [ "$?" != "0" ]; then
+ test_done "$testroot" "$?"
+ return 1
+ fi
+
+ echo change > $testroot/repo/arch/alpha/Makefile
+ (cd $testroot/repo && git add .)
+ git_commit $testroot/repo -m "changed a file"
+
+ echo "U arch/alpha/Makefile" > $testroot/stdout.expected
+ echo -n "Updated to commit " >> $testroot/stdout.expected
+ git_show_head $testroot/repo >> $testroot/stdout.expected
+ echo >> $testroot/stdout.expected
+
+ (cd $testroot/wt && got update > $testroot/stdout)
+
+ cmp $testroot/stdout.expected $testroot/stdout
+ if [ "$?" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$?"
+ return 1
+ fi
+
+ test_done "$testroot" "0"
+}
+
run_test test_update_basic
run_test test_update_adds_file
run_test test_update_deletes_file
run_test test_update_moves_files_to_new_dir
run_test test_update_creates_missing_parent
run_test test_update_creates_missing_parent_with_subdir
+run_test test_update_file_in_subsubdir