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

Skip to content

Commit 619423f

Browse files
committed
diff: test we don't update index unnecessarily
Test that workdir diffs, when presented with UPDATE_INDEX, only write the index when they actually make a change.
1 parent c0280bd commit 619423f

File tree

1 file changed

+69
-7
lines changed

1 file changed

+69
-7
lines changed

tests/diff/workdir.c

Lines changed: 69 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1544,19 +1544,21 @@ void test_diff_workdir__with_stale_index(void)
15441544

15451545
static int touch_file(void *payload, git_buf *path)
15461546
{
1547-
int fd;
1548-
char b;
1547+
struct stat st;
1548+
struct timeval times[2];
15491549

15501550
GIT_UNUSED(payload);
15511551
if (git_path_isdir(path->ptr))
15521552
return 0;
15531553

1554-
cl_assert((fd = p_open(path->ptr, O_RDWR)) >= 0);
1555-
cl_assert_equal_i(1, p_read(fd, &b, 1));
1556-
cl_must_pass(p_lseek(fd, 0, SEEK_SET));
1557-
cl_must_pass(p_write(fd, &b, 1));
1558-
cl_must_pass(p_close(fd));
1554+
cl_must_pass(p_stat(path->ptr, &st));
1555+
1556+
times[0].tv_sec = st.st_mtime + 3;
1557+
times[0].tv_usec = 0;
1558+
times[1].tv_sec = st.st_mtime + 3;
1559+
times[1].tv_usec = 0;
15591560

1561+
cl_must_pass(p_utimes(path->ptr, times));
15601562
return 0;
15611563
}
15621564

@@ -1783,3 +1785,63 @@ void test_diff_workdir__to_index_conflicted(void) {
17831785
git_index_free(index);
17841786
git_tree_free(a);
17851787
}
1788+
1789+
void test_diff_workdir__only_writes_index_when_necessary(void)
1790+
{
1791+
git_index *index;
1792+
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
1793+
git_diff *diff = NULL;
1794+
git_diff_perfdata perf = GIT_DIFF_PERFDATA_INIT;
1795+
git_reference *head;
1796+
git_object *head_object;
1797+
git_oid initial, first, second;
1798+
git_buf path = GIT_BUF_INIT;
1799+
struct stat st;
1800+
struct timeval times[2];
1801+
1802+
opts.flags |= GIT_DIFF_INCLUDE_UNTRACKED | GIT_DIFF_UPDATE_INDEX;
1803+
1804+
g_repo = cl_git_sandbox_init("status");
1805+
1806+
cl_git_pass(git_repository_index(&index, g_repo));
1807+
cl_git_pass(git_repository_head(&head, g_repo));
1808+
cl_git_pass(git_reference_peel(&head_object, head, GIT_OBJ_COMMIT));
1809+
1810+
cl_git_pass(git_reset(g_repo, head_object, GIT_RESET_HARD, NULL));
1811+
1812+
git_oid_cpy(&initial, git_index_checksum(index));
1813+
1814+
/* update the index timestamp to avoid raciness */
1815+
cl_must_pass(p_stat("status/.git/index", &st));
1816+
1817+
times[0].tv_sec = st.st_mtime + 5;
1818+
times[0].tv_usec = 0;
1819+
times[1].tv_sec = st.st_mtime + 5;
1820+
times[1].tv_usec = 0;
1821+
1822+
cl_must_pass(p_utimes("status/.git/index", times));
1823+
1824+
/* ensure diff doesn't touch the index */
1825+
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
1826+
git_diff_free(diff);
1827+
1828+
git_oid_cpy(&first, git_index_checksum(index));
1829+
cl_assert(!git_oid_equal(&initial, &first));
1830+
1831+
/* touch all the files so stat times are different */
1832+
cl_git_pass(git_buf_sets(&path, "status"));
1833+
cl_git_pass(git_path_direach(&path, 0, touch_file, NULL));
1834+
1835+
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
1836+
git_diff_free(diff);
1837+
1838+
/* ensure the second diff did update the index */
1839+
git_oid_cpy(&second, git_index_checksum(index));
1840+
cl_assert(!git_oid_equal(&first, &second));
1841+
1842+
git_buf_free(&path);
1843+
git_object_free(head_object);
1844+
git_reference_free(head);
1845+
git_index_free(index);
1846+
}
1847+

0 commit comments

Comments
 (0)