commit - e60e7f5bf0d3d27834b9712529836b42207853c8
commit + a378724ff7c52fed47ca10ec7bb827ad4955ce57
blob - 914b39fda8d355979f18027abf6b0d7b7091aa65
blob + 1ce550db674eb7b48feb8bd5c8e48a2ed6f537c6
--- got/got.1
+++ got/got.1
.It D Ta file was deleted
.It A Ta new file was added
.It ~ Ta versioned file is obstructed by a non-regular file
+.It ! Ta a missing versioned file was restored
.El
.Pp
If the
blob - 755f467c2aa1a389cc6240409b367803b91565a5
blob + 709848c071063737c6e2c461124cc38e2ec0eac9
--- got/got.c
+++ got/got.c
if (status == GOT_STATUS_EXISTS)
return;
- *did_something = 1;
+ if (status != GOT_STATUS_MISSING)
+ *did_something = 1;
while (path[0] == '/')
path++;
printf("%c %s\n", status, path);
blob - f8449d38ccd31e85697d762976525f415268ccb9
blob + 893ba6cf0e45a7e3252f09fe1a4bfe287009aba3
--- lib/worktree.c
+++ lib/worktree.c
static const struct got_error *
install_blob(struct got_worktree *worktree, struct got_fileindex *fileindex,
struct got_fileindex_entry *entry, const char *ondisk_path, const char *path,
- uint16_t mode, struct got_blob_object *blob,
+ uint16_t mode, struct got_blob_object *blob, int restoring_missing_file,
struct got_repository *repo, got_worktree_checkout_cb progress_cb,
void *progress_arg)
{
return got_error_from_errno();
}
- (*progress_cb)(progress_arg,
- update ? GOT_STATUS_UPDATE : GOT_STATUS_ADD, path);
+ if (restoring_missing_file)
+ (*progress_cb)(progress_arg, GOT_STATUS_MISSING, path);
+ else
+ (*progress_cb)(progress_arg,
+ update ? GOT_STATUS_UPDATE : GOT_STATUS_ADD, path);
hdrlen = got_object_blob_get_hdrlen(blob);
do {
*status = GOT_STATUS_NO_CHANGE;
- if (lstat(abspath, &sb) == -1)
+ if (lstat(abspath, &sb) == -1) {
+ if (errno == ENOENT) {
+ *status = GOT_STATUS_MISSING;
+ return NULL;
+ }
return got_error_from_errno();
+ }
if (!S_ISREG(sb.st_mode)) {
*status = GOT_STATUS_OBSTRUCTED;
return got_error_from_errno();
if (ie) {
- if (memcmp(ie->commit_sha1, worktree->base_commit_id->sha1,
- SHA1_DIGEST_LENGTH) == 0) {
- (*progress_cb)(progress_arg, GOT_STATUS_EXISTS,
- path);
- goto done;
- }
- if (memcmp(ie->blob_sha1,
- te->id->sha1, SHA1_DIGEST_LENGTH) == 0)
- goto done;
-
err = get_file_status(&status, ie, ondisk_path, repo);
if (err)
goto done;
if (status == GOT_STATUS_OBSTRUCTED) {
(*progress_cb)(progress_arg, status, path);
goto done;
+ }
+
+ if (status == GOT_STATUS_NO_CHANGE) {
+ if (memcmp(ie->commit_sha1,
+ worktree->base_commit_id->sha1,
+ SHA1_DIGEST_LENGTH) == 0) {
+ (*progress_cb)(progress_arg, GOT_STATUS_EXISTS,
+ path);
+ goto done;
+ }
+ if (memcmp(ie->blob_sha1,
+ te->id->sha1, SHA1_DIGEST_LENGTH) == 0)
+ goto done;
}
}
te->mode, blob, repo, progress_cb, progress_arg);
else
err = install_blob(worktree, fileindex, ie, ondisk_path, path,
- te->mode, blob, repo, progress_cb, progress_arg);
+ te->mode, blob, status == GOT_STATUS_MISSING, repo,
+ progress_cb, progress_arg);
got_object_blob_close(blob);
done:
blob - e7ae6c144216594739f0afb77723057f5bf22b17
blob + 3267b8ed203708fea01289cbeae3ed1131275e5e
--- regress/cmdline/update.sh
+++ regress/cmdline/update.sh
fi
test_done "$testroot" "$ret"
}
+
+function test_update_restores_missing_file {
+ local testroot=`test_init update_restores_missing_file`
+
+ got checkout $testroot/repo $testroot/wt > /dev/null
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+ rm $testroot/wt/alpha
+
+ echo "! alpha" > $testroot/stdout.expected
+ echo "Already up-to-date" >> $testroot/stdout.expected
+ (cd $testroot/wt && got update > $testroot/stdout)
+
+ cmp $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ echo "alpha" > $testroot/content.expected
+
+ cat $testroot/wt/alpha > $testroot/content
+
+ cmp $testroot/content.expected $testroot/content
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/content.expected $testroot/content
+ fi
+ test_done "$testroot" "$ret"
+}
+
run_test test_update_basic
run_test test_update_adds_file
run_test test_update_deletes_file
run_test test_update_merges_file_edits
run_test test_update_keeps_xbit
run_test test_update_clears_xbit
+run_test test_update_restores_missing_file