| 444 | } |
| 445 | |
| 446 | int ie_modified(struct index_state *istate, |
| 447 | const struct cache_entry *ce, |
| 448 | struct stat *st, unsigned int options) |
| 449 | { |
| 450 | int changed, changed_fs; |
| 451 | |
| 452 | changed = ie_match_stat(istate, ce, st, options); |
| 453 | if (!changed) |
| 454 | return 0; |
| 455 | /* |
| 456 | * If the mode or type has changed, there's no point in trying |
| 457 | * to refresh the entry - it's not going to match |
| 458 | */ |
| 459 | if (changed & (MODE_CHANGED | TYPE_CHANGED)) |
| 460 | return changed; |
| 461 | |
| 462 | /* |
| 463 | * Immediately after read-tree or update-index --cacheinfo, |
| 464 | * the length field is zero, as we have never even read the |
| 465 | * lstat(2) information once, and we cannot trust DATA_CHANGED |
| 466 | * returned by ie_match_stat() which in turn was returned by |
| 467 | * ce_match_stat_basic() to signal that the filesize of the |
| 468 | * blob changed. We have to actually go to the filesystem to |
| 469 | * see if the contents match, and if so, should answer "unchanged". |
| 470 | * |
| 471 | * The logic does not apply to gitlinks, as ce_match_stat_basic() |
| 472 | * already has checked the actual HEAD from the filesystem in the |
| 473 | * subproject. If ie_match_stat() already said it is different, |
| 474 | * then we know it is. |
| 475 | */ |
| 476 | if ((changed & DATA_CHANGED) && |
| 477 | #ifdef GIT_WINDOWS_NATIVE |
| 478 | /* |
| 479 | * Work around Git for Windows v2.27.0 fixing a bug where symlinks' |
| 480 | * target path lengths were not read at all, and instead recorded |
| 481 | * as 4096: now, all symlinks would appear as modified. |
| 482 | * |
| 483 | * So let's just special-case symlinks with a target path length |
| 484 | * (i.e. `sd_size`) of 4096 and force them to be re-checked. |
| 485 | */ |
| 486 | (!S_ISLNK(st->st_mode) || ce->ce_stat_data.sd_size != MAX_PATH) && |
| 487 | #endif |
| 488 | (S_ISGITLINK(ce->ce_mode) || ce->ce_stat_data.sd_size != 0)) |
| 489 | return changed; |
| 490 | |
| 491 | changed_fs = ce_modified_check_fs(istate, ce, st); |
| 492 | if (changed_fs) |
| 493 | return changed | changed_fs; |
| 494 | return 0; |
| 495 | } |
| 496 | |
| 497 | static int cache_name_stage_compare(const char *name1, int len1, int stage1, |
| 498 | const char *name2, int len2, int stage2) |
no test coverage detected