Download raw body.
fix 'got update' with added + obstructed file
On Fri, Sep 24, 2021 at 11:31:14PM +0200, Stefan Sperling wrote:
> When 'got update' tries to add a new file to the work tree and this
> file is obstructed by a directory on disk, the update fails like this:
>
> $ got update
> ? new
> got: new: Is a directory
> $
>
> And the work tree is not updated. The above update with error can be
> run over and over and won't proceed until the directory is removed.
> The problem here is simply that the update as a whole should succeed,
> not stop on one such file even though there might be more files to update.
>
> With the patch below this situation is properly detected as an obstruction
> and the update succeeds:
>
> $ got update
> ~ new
> Updated to refs/heads/master: c1f85b4938dc4c668a88f13df2b98a520fc077cc
> File paths obstructed by a non-regular file: 1
> $
>
> Regardless, the file 'new' will not be added to the work tree until the
> directory is moved and 'got update' is run again.
>
> And I am extending a corresponding test to cover this issue.
>
> ok?
Looks good.
>
> diff f365d76274ee1ae2b57225686a0733176fc4bfb2 /home/stsp/src/got
> blob - f5bc677438d23ddca778382674edef04e09cb939
> file + lib/worktree.c
> --- lib/worktree.c
> +++ lib/worktree.c
> @@ -1942,8 +1942,20 @@ update_blob(struct got_worktree *worktree,
> if (status == GOT_STATUS_MISSING || status == GOT_STATUS_DELETE)
> sb.st_mode = got_fileindex_perms_to_st(ie);
> } else {
> - sb.st_mode = GOT_DEFAULT_FILE_MODE;
> - status = GOT_STATUS_UNVERSIONED;
> + if (stat(ondisk_path, &sb) == -1) {
> + if (errno != ENOENT) {
> + err = got_error_from_errno2("stat",
> + ondisk_path);
> + goto done;
> + }
> + sb.st_mode = GOT_DEFAULT_FILE_MODE;
> + status = GOT_STATUS_UNVERSIONED;
> + } else {
> + if (S_ISREG(sb.st_mode) || S_ISLNK(sb.st_mode))
> + status = GOT_STATUS_UNVERSIONED;
> + else
> + status = GOT_STATUS_OBSTRUCTED;
> + }
> }
>
> if (status == GOT_STATUS_OBSTRUCTED) {
> blob - cae602420f097ed69b049e9fffb3fc46510d2de5
> file + regress/cmdline/update.sh
> --- regress/cmdline/update.sh
> +++ regress/cmdline/update.sh
> @@ -2588,6 +2588,8 @@ test_update_file_skipped_due_to_obstruction() {
> blob_id0=`get_blob_id $testroot/repo "" beta`
>
> echo "changed beta" > $testroot/repo/beta
> + echo "new file" > $testroot/repo/new
> + (cd $testroot/repo && git add new)
> git_commit $testroot/repo -m "changed beta"
> local commit_id1=`git_show_head $testroot/repo`
> blob_id1=`get_blob_id $testroot/repo "" beta`
> @@ -2617,14 +2619,22 @@ test_update_file_skipped_due_to_obstruction() {
>
> rm $testroot/wt/beta
> mkdir -p $testroot/wt/beta/psi
> + mkdir -p $testroot/wt/new
>
> - # update to the latest commit; this skips beta
> + # update to the latest commit; this skips beta and the new file
> (cd $testroot/wt && got update > $testroot/stdout)
> + ret="$?"
> + if [ "$ret" != "0" ]; then
> + echo "update failed unexpectedly" >&2
> + test_done "$testroot" "1"
> + return 1
> + fi
>
> echo "~ beta" > $testroot/stdout.expected
> + echo "~ new" >> $testroot/stdout.expected
> echo "Updated to refs/heads/master: $commit_id1" \
> >> $testroot/stdout.expected
> - echo "File paths obstructed by a non-regular file: 1" \
> + echo "File paths obstructed by a non-regular file: 2" \
> >> $testroot/stdout.expected
> cmp -s $testroot/stdout.expected $testroot/stdout
> ret="$?"
> @@ -2656,8 +2666,11 @@ test_update_file_skipped_due_to_obstruction() {
> # updating to the latest commit should now update beta
> (cd $testroot/wt && got update > $testroot/stdout)
> echo "! beta" > $testroot/stdout.expected
> + echo "~ new" >> $testroot/stdout.expected
> echo "Updated to refs/heads/master: $commit_id1" \
> >> $testroot/stdout.expected
> + echo "File paths obstructed by a non-regular file: 1" \
> + >> $testroot/stdout.expected
> cmp -s $testroot/stdout.expected $testroot/stdout
> ret="$?"
> if [ "$ret" != "0" ]; then
--
Tracey Emery
fix 'got update' with added + obstructed file