Skip to content

Commit 752b7c7

Browse files
Edward Thomsonethomson
authored andcommitted
checkout: treat files as modified if mode differs
When performing a forced checkout, treat files as modified when the workdir or the index is identical except for the mode. This ensures that force checkout will update the mode to the target. (Apply this check for regular files only, if one of the items was a file and the other was another type of item then this would be a typechange and handled independently.)
1 parent 62ac393 commit 752b7c7

File tree

1 file changed

+10
-1
lines changed

1 file changed

+10
-1
lines changed

src/checkout.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,11 @@ GIT_INLINE(bool) is_workdir_base_or_new(
159159
git_oid__cmp(&newitem->id, workdir_id) == 0);
160160
}
161161

162+
GIT_INLINE(bool) is_file_mode_changed(git_filemode_t a, git_filemode_t b)
163+
{
164+
return (S_ISREG(a) && S_ISREG(b) && a != b);
165+
}
166+
162167
static bool checkout_is_workdir_modified(
163168
checkout_data *data,
164169
const git_diff_file *baseitem,
@@ -200,7 +205,8 @@ static bool checkout_is_workdir_modified(
200205
*/
201206
if ((ie = git_index_get_bypath(data->index, wditem->path, 0)) != NULL) {
202207
if (git_index_time_eq(&wditem->mtime, &ie->mtime) &&
203-
wditem->file_size == ie->file_size)
208+
wditem->file_size == ie->file_size &&
209+
!is_file_mode_changed(wditem->mode, ie->mode))
204210
return !is_workdir_base_or_new(&ie->id, baseitem, newitem);
205211
}
206212

@@ -214,6 +220,9 @@ static bool checkout_is_workdir_modified(
214220
if (S_ISDIR(wditem->mode))
215221
return false;
216222

223+
if (is_file_mode_changed(baseitem->mode, wditem->mode))
224+
return true;
225+
217226
if (git_diff__oid_for_entry(&oid, data->diff, wditem, wditem->mode, NULL) < 0)
218227
return false;
219228

0 commit comments

Comments
 (0)