Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c214ba1

Browse files
committed
checkout: respect core.filemode when comparing filemodes
Fixes libgit2#4504
1 parent 275693e commit c214ba1

File tree

1 file changed

+21
-13
lines changed

1 file changed

+21
-13
lines changed

src/checkout.c

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ typedef struct {
7070
git_buf tmp;
7171
unsigned int strategy;
7272
int can_symlink;
73+
int respect_filemode;
7374
bool reload_submodules;
7475
size_t total_steps;
7576
size_t completed_steps;
@@ -159,17 +160,20 @@ GIT_INLINE(bool) is_workdir_base_or_new(
159160
git_oid__cmp(&newitem->id, workdir_id) == 0);
160161
}
161162

162-
GIT_INLINE(bool) is_file_mode_changed(git_filemode_t a, git_filemode_t b)
163+
GIT_INLINE(bool) is_filemode_changed(git_filemode_t a, git_filemode_t b, int respect_filemode)
163164
{
164-
#ifdef GIT_WIN32
165-
/*
166-
* On Win32 we do not support the executable bit; the file will
167-
* always be 0100644 on disk, don't bother doing a test.
168-
*/
169-
return false;
170-
#else
171-
return (S_ISREG(a) && S_ISREG(b) && a != b);
172-
#endif
165+
/* If core.filemode = false, ignore links in the repository and executable bit changes */
166+
if (!respect_filemode) {
167+
if (a == S_IFLNK)
168+
a = GIT_FILEMODE_BLOB;
169+
if (b == S_IFLNK)
170+
b = GIT_FILEMODE_BLOB;
171+
172+
a &= ~0111;
173+
b &= ~0111;
174+
}
175+
176+
return (a != b);
173177
}
174178

175179
static bool checkout_is_workdir_modified(
@@ -217,11 +221,11 @@ static bool checkout_is_workdir_modified(
217221
if (ie != NULL &&
218222
git_index_time_eq(&wditem->mtime, &ie->mtime) &&
219223
wditem->file_size == ie->file_size &&
220-
!is_file_mode_changed(wditem->mode, ie->mode)) {
224+
!is_filemode_changed(wditem->mode, ie->mode, data->respect_filemode)) {
221225

222226
/* The workdir is modified iff the index entry is modified */
223227
return !is_workdir_base_or_new(&ie->id, baseitem, newitem) ||
224-
is_file_mode_changed(baseitem->mode, ie->mode);
228+
is_filemode_changed(baseitem->mode, ie->mode, data->respect_filemode);
225229
}
226230

227231
/* depending on where base is coming from, we may or may not know
@@ -234,7 +238,7 @@ static bool checkout_is_workdir_modified(
234238
if (S_ISDIR(wditem->mode))
235239
return false;
236240

237-
if (is_file_mode_changed(baseitem->mode, wditem->mode))
241+
if (is_filemode_changed(baseitem->mode, wditem->mode, data->respect_filemode))
238242
return true;
239243

240244
if (git_diff__oid_for_entry(&oid, data->diff, wditem, wditem->mode, NULL) < 0)
@@ -2454,6 +2458,10 @@ static int checkout_data_init(
24542458
&data->can_symlink, repo, GIT_CVAR_SYMLINKS)) < 0)
24552459
goto cleanup;
24562460

2461+
if ((error = git_repository__cvar(
2462+
&data->respect_filemode, repo, GIT_CVAR_FILEMODE)) < 0)
2463+
goto cleanup;
2464+
24572465
if (!data->opts.baseline && !data->opts.baseline_index) {
24582466
data->opts_free_baseline = true;
24592467
error = 0;

0 commit comments

Comments
 (0)