Skip to content

Commit ece7b74

Browse files
dschogitster
authored andcommitted
apply --index-info: fall back to current index for mode changes
"git diff" does not record index lines for pure mode changes (i.e. no lines changed). Therefore, apply --index-info would call out a bogus error. Instead, fall back to reading the info from the current index. Incidentally, this fixes an error where git-rebase would not rebase a commit including a pure mode change, and changes requiring a threeway merge. Noticed and later tested by Chris Shoemaker. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent f3caeb9 commit ece7b74

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

builtin-apply.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2227,6 +2227,20 @@ static int check_patch_list(struct patch *patch)
22272227
return err;
22282228
}
22292229

2230+
/* This function tries to read the sha1 from the current index */
2231+
static int get_current_sha1(const char *path, unsigned char *sha1)
2232+
{
2233+
int pos;
2234+
2235+
if (read_cache() < 0)
2236+
return -1;
2237+
pos = cache_name_pos(path, strlen(path));
2238+
if (pos < 0)
2239+
return -1;
2240+
hashcpy(sha1, active_cache[pos]->sha1);
2241+
return 0;
2242+
}
2243+
22302244
static void show_index_list(struct patch *list)
22312245
{
22322246
struct patch *patch;
@@ -2243,8 +2257,16 @@ static void show_index_list(struct patch *list)
22432257
if (0 < patch->is_new)
22442258
sha1_ptr = null_sha1;
22452259
else if (get_sha1(patch->old_sha1_prefix, sha1))
2246-
die("sha1 information is lacking or useless (%s).",
2247-
name);
2260+
/* git diff has no index line for mode/type changes */
2261+
if (!patch->lines_added && !patch->lines_deleted) {
2262+
if (get_current_sha1(patch->new_name, sha1) ||
2263+
get_current_sha1(patch->old_name, sha1))
2264+
die("mode change for %s, which is not "
2265+
"in current HEAD", name);
2266+
sha1_ptr = sha1;
2267+
} else
2268+
die("sha1 information is lacking or useless "
2269+
"(%s).", name);
22482270
else
22492271
sha1_ptr = sha1;
22502272

t/t3400-rebase.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,19 @@ test_expect_success \
6868
test 3 = $(git rev-list master.. | wc -l)
6969
'
7070

71+
test_expect_success 'rebase a single mode change' '
72+
git checkout master &&
73+
echo 1 > X &&
74+
git add X &&
75+
test_tick &&
76+
git commit -m prepare &&
77+
git checkout -b modechange HEAD^ &&
78+
echo 1 > X &&
79+
git add X &&
80+
chmod a+x A &&
81+
test_tick &&
82+
git commit -m modechange A X &&
83+
GIT_TRACE=1 git rebase master
84+
'
85+
7186
test_done

0 commit comments

Comments
 (0)