commit cdc669650695cff64baae8dfcccf30a57d751f82 from: Stefan Sperling date: Mon Jan 20 11:03:02 2025 UTC skip full content comparison in 'got status' if file sizes differ Speeds up 'got status' in work trees that contain large files which are modified. This change exposes bugs in 'got revert' which now manifest as test failures. One bug where the size recorded in the file index is not updated during revert, and another where a wrong base commit is recorded in the file index entry during revert. Fix those bugs, too. ok jamsek commit - 455ae1c8c7b36f824266bd2701e931004f626875 commit + cdc669650695cff64baae8dfcccf30a57d751f82 blob - df89f493b283c3c8957846b5f60994c98756d8ae blob + 71a215359b98caf08ed6fafa8841fdd8dbd4caac --- lib/worktree.c +++ lib/worktree.c @@ -1839,8 +1839,22 @@ get_file_status(unsigned char *status, struct stat *sb goto done; } fd = -1; + + if (staged_status == GOT_STATUS_NO_CHANGE && + S_ISREG(sb->st_mode) && + got_fileindex_entry_filetype_get(ie) == + GOT_FILEIDX_MODE_REGULAR_FILE && + ie->size != (sb->st_size & 0xffffffff)) { + /* + * The size of regular files differs. We can skip the full + * content comparison loop below but still need to check + * for conflict markers. + */ + *status = GOT_STATUS_MODIFY; + } + hdrlen = got_object_blob_get_hdrlen(blob); - for (;;) { + while (*status == GOT_STATUS_NO_CHANGE) { const uint8_t *bbuf = got_object_blob_get_read_buf(blob); err = got_object_blob_read_block(&blen, blob); if (err) @@ -5355,6 +5369,11 @@ revert_file(void *arg, unsigned char status, unsigned goto done; } } + err = got_fileindex_entry_update(ie, + a->worktree->root_fd, relpath, + &blob->id, &ie->commit, 0); + if (err) + goto done; } else { int is_bad_symlink = 0; if (te && S_ISLNK(te->mode)) { @@ -5372,14 +5391,11 @@ revert_file(void *arg, unsigned char status, unsigned } if (err) goto done; - if (status == GOT_STATUS_DELETE || - status == GOT_STATUS_MODE_CHANGE) { - err = got_fileindex_entry_update(ie, - a->worktree->root_fd, relpath, - &blob->id, a->worktree->base_commit_id, 1); - if (err) - goto done; - } + err = got_fileindex_entry_update(ie, + a->worktree->root_fd, relpath, + &blob->id, &ie->commit, 0); + if (err) + goto done; if (is_bad_symlink) { got_fileindex_entry_filetype_set(ie, GOT_FILEIDX_MODE_BAD_SYMLINK);