commit - b7422a2f5c775615ff397e14c04aa9c9a41504c1
commit + ea7786be381853efad88beae518c19a391d13791
blob - cec70da8d017f316d73c553fe1f13cb015f3d6e8
blob + d94da1d659df18bb44c73bf7b04d0cfb808d6bd4
--- lib/worktree.c
+++ lib/worktree.c
goto done;
err = (*progress_cb)(progress_arg, GOT_STATUS_MERGE, path);
} else if (have_local_change && have_incoming_change) {
- err = install_symlink_conflict(deriv_target,
- deriv_base_commit_id, ancestor_target, label_orig,
- ondisk_target, ondisk_path);
- if (err)
- goto done;
- err = (*progress_cb)(progress_arg, GOT_STATUS_CONFLICT,
- path);
+ if (deriv_len == ondisk_len &&
+ memcmp(deriv_target, ondisk_target, deriv_len) == 0) {
+ /* Both sides made the same change. */
+ err = (*progress_cb)(progress_arg, GOT_STATUS_MERGE,
+ path);
+ } else {
+ err = install_symlink_conflict(deriv_target,
+ deriv_base_commit_id, ancestor_target, label_orig,
+ ondisk_target, ondisk_path);
+ if (err)
+ goto done;
+ err = (*progress_cb)(progress_arg, GOT_STATUS_CONFLICT,
+ path);
+ }
}
done:
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;
}
staged_blob_id, 8192);
if (err)
break;
- err = merge_blob(&local_changes_subsumed, a->worktree,
- blob_base, ondisk_path, relpath,
- got_fileindex_perms_to_st(ie), label_orig, blob_staged,
- commit_id ? commit_id : a->worktree->base_commit_id,
- a->repo, a->progress_cb, a->progress_arg);
+ switch (got_fileindex_entry_staged_filetype_get(ie)) {
+ case GOT_FILEIDX_MODE_BAD_SYMLINK:
+ case GOT_FILEIDX_MODE_REGULAR_FILE:
+ err = merge_blob(&local_changes_subsumed, a->worktree,
+ blob_base, ondisk_path, relpath,
+ got_fileindex_perms_to_st(ie), label_orig,
+ blob_staged, commit_id ? commit_id :
+ a->worktree->base_commit_id, a->repo,
+ a->progress_cb, a->progress_arg);
+ break;
+ case GOT_FILEIDX_MODE_SYMLINK:
+ err = merge_symlink(a->worktree, blob_base, ondisk_path,
+ relpath, got_fileindex_perms_to_st(ie), label_orig,
+ blob_staged, a->worktree->base_commit_id, a->repo,
+ a->progress_cb, a->progress_arg);
+ break;
+ default:
+ err = got_error_path(relpath, GOT_ERR_BAD_FILETYPE);
+ break;
+ }
if (err == NULL)
got_fileindex_entry_stage_set(ie,
GOT_FILEIDX_STAGE_NONE);
blob - ef2a91d696b6b381bc506f6ed946a1bfa9412d17
blob + 90b33b415f9ac6e50f34f0abf71c068ca2f81efb
--- regress/cmdline/unstage.sh
+++ regress/cmdline/unstage.sh
fi
test_done "$testroot" "$ret"
}
+
+function test_unstage_symlink {
+ local testroot=`test_init unstage_symlink`
+
+ (cd $testroot/repo && ln -s alpha alpha.link)
+ (cd $testroot/repo && ln -s epsilon epsilon.link)
+ (cd $testroot/repo && ln -s /etc/passwd passwd.link)
+ (cd $testroot/repo && ln -s ../beta epsilon/beta.link)
+ (cd $testroot/repo && ln -s nonexistent nonexistent.link)
+ (cd $testroot/repo && git add .)
+ git_commit $testroot/repo -m "add symlinks"
+ local head_commit=`git_show_head $testroot/repo`
+ got checkout $testroot/repo $testroot/wt > /dev/null
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ (cd $testroot/wt && ln -sf beta alpha.link)
+ (cd $testroot/wt && ln -sfh gamma epsilon.link)
+ (cd $testroot/wt && ln -sf ../gamma/delta epsilon/beta.link)
+ echo 'this is regular file foo' > $testroot/wt/dotgotfoo.link
+ (cd $testroot/wt && got add dotgotfoo.link > /dev/null)
+ (cd $testroot/wt && ln -sf .got/bar dotgotbar.link)
+ (cd $testroot/wt && got add dotgotbar.link > /dev/null)
+ (cd $testroot/wt && got rm nonexistent.link > /dev/null)
+ (cd $testroot/wt && ln -sf gamma/delta zeta.link)
+ (cd $testroot/wt && got add zeta.link > /dev/null)
+
+ (cd $testroot/wt && got stage > /dev/null)
+
+ (cd $testroot/wt && got status > $testroot/stdout)
+ cat > $testroot/stdout.expected <<EOF
+ M alpha.link
+ A dotgotbar.link
+ A dotgotfoo.link
+ M epsilon/beta.link
+ M epsilon.link
+ D nonexistent.link
+ A zeta.link
+EOF
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ (cd $testroot/wt && got unstage > $testroot/stdout)
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ echo "got unstage command failed unexpectedly" >&2
+ test_done "$testroot" "1"
+ return 1
+ fi
+
+ cat > $testroot/stdout.expected <<EOF
+G alpha.link
+G dotgotbar.link
+G dotgotfoo.link
+G epsilon/beta.link
+G epsilon.link
+D nonexistent.link
+G zeta.link
+EOF
+
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ if [ ! -h $testroot/wt/alpha.link ]; then
+ echo "alpha.link is not 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
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ if [ ! -h $testroot/wt/epsilon.link ]; then
+ echo "epsilon.link is not a symlink"
+ test_done "$testroot" "1"
+ return 1
+ fi
+
+ readlink $testroot/wt/epsilon.link > $testroot/stdout
+ echo "gamma" > $testroot/stdout.expected
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ if [ ! -h $testroot/wt/epsilon/beta.link ]; then
+ echo "epsilon/beta.link is not a symlink"
+ test_done "$testroot" "1"
+ return 1
+ fi
+
+ readlink $testroot/wt/epsilon/beta.link > $testroot/stdout
+ echo "../gamma/delta" > $testroot/stdout.expected
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ if [ ! -f $testroot/wt/dotgotfoo.link ]; then
+ echo "dotgotfoo.link is a symlink"
+ test_done "$testroot" "1"
+ return 1
+ fi
+
+ echo "this is regular file foo" > $testroot/content.expected
+ cp $testroot/wt/dotgotfoo.link $testroot/content
+ cmp -s $testroot/content.expected $testroot/content
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/content.expected $testroot/content
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ # bad symlinks are allowed as-is for commit and stage/unstage
+ if [ ! -h $testroot/wt/dotgotbar.link ]; then
+ echo "dotgotbar.link is not a symlink"
+ test_done "$testroot" "1"
+ return 1
+ fi
+
+ readlink $testroot/wt/dotgotbar.link > $testroot/stdout
+ echo ".got/bar" > $testroot/stdout.expected
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ if [ -e $testroot/wt/nonexistent.link ]; then
+ echo "nonexistent.link exists on disk"
+ test_done "$testroot" "1"
+ return 1
+ fi
+
+ if [ ! -h $testroot/wt/zeta.link ]; then
+ echo "zeta.link is not a symlink"
+ test_done "$testroot" "1"
+ return 1
+ fi
+
+ readlink $testroot/wt/zeta.link > $testroot/stdout
+ echo "gamma/delta" > $testroot/stdout.expected
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ test_done "$testroot" "0"
+}
+
run_test test_unstage_basic
run_test test_unstage_unversioned
run_test test_unstage_nonexistent
run_test test_unstage_patch_added
run_test test_unstage_patch_removed
run_test test_unstage_patch_quit
+run_test test_unstage_symlink