handle xbit-only changes during 'got update'
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
diff --git a/lib/worktree.c b/lib/worktree.c
index 62fe20f..edb81fa 100644
--- a/lib/worktree.c
+++ b/lib/worktree.c
@@ -1253,7 +1253,8 @@ update_blob(struct got_worktree *worktree,
goto done;
}
- if (ie && status != GOT_STATUS_MISSING) {
+ if (ie && status != GOT_STATUS_MISSING &&
+ (te->mode & S_IXUSR) == (sb.st_mode & S_IXUSR)) {
if (got_fileindex_entry_has_commit(ie) &&
memcmp(ie->commit_sha1, worktree->base_commit_id->sha1,
SHA1_DIGEST_LENGTH) == 0) {
diff --git a/regress/cmdline/update.sh b/regress/cmdline/update.sh
old mode 100744
new mode 100755
index e6d7001..4aa5679
--- a/regress/cmdline/update.sh
+++ b/regress/cmdline/update.sh
@@ -1556,6 +1556,93 @@ function test_update_tag {
test_done "$testroot" "$ret"
}
+function test_update_toggles_xbit {
+ local testroot=`test_init update_toggles_xbit 1`
+
+ touch $testroot/repo/xfile
+ chmod +x $testroot/repo/xfile
+ (cd $testroot/repo && git add .)
+ git_commit $testroot/repo -m "adding executable file"
+ local commit_id1=`git_show_head $testroot/repo`
+
+ got checkout $testroot/repo $testroot/wt > $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ ls -l $testroot/wt/xfile | grep -q '^-rwx'
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ echo "file is not executable" >&2
+ ls -l $testroot/wt/xfile >&2
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ chmod -x $testroot/wt/xfile
+ (cd $testroot/wt && got commit -m "clear x bit" >/dev/null)
+ local commit_id2=`git_show_head $testroot/repo`
+
+ echo "U xfile" > $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 -c $commit_id1 > $testroot/stdout)
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ echo "U xfile" > $testroot/stdout.expected
+ echo "Updated to commit $commit_id1" >> $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
+
+
+ ls -l $testroot/wt/xfile | grep -q '^-rwx'
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ echo "file is not executable" >&2
+ ls -l $testroot/wt/xfile >&2
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ (cd $testroot/wt && got update > $testroot/stdout)
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ echo "U xfile" > $testroot/stdout.expected
+ echo "Updated to commit $commit_id2" >> $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
+
+ ls -l $testroot/wt/xfile | grep -q '^-rw-'
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ echo "file is unexpectedly executable" >&2
+ ls -l $testroot/wt/xfile >&2
+ fi
+ test_done "$testroot" "$ret"
+}
+
run_test test_update_basic
run_test test_update_adds_file
run_test test_update_deletes_file
@@ -1586,3 +1673,4 @@ run_test test_update_to_another_branch
run_test test_update_to_commit_on_wrong_branch
run_test test_update_bumps_base_commit_id
run_test test_update_tag
+run_test test_update_toggles_xbit