{"thread":{"id":"52992","subject":"[PATCH] t6022, t6046: fix flaky files-are-updated checks","startedAt":"2020-03-13T18:58:05Z","lastAt":"2020-03-13T20:03:11Z","messageCount":5,"participants":["Elijah Newren via GitGitGadget","Junio C Hamano","Elijah Newren"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"393225","messageId":"pull.725.git.git.1584125875550.gitgitgadget@gmail.com","threadId":"52992","inReplyTo":null,"subject":"[PATCH] t6022, t6046: fix flaky files-are-updated checks","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-03-13T18:57:55Z","receivedAt":"2020-03-13T18:58:05Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nSeveral tests wanted to verify that files were actually modified by a\nmerge, which it would do by checking that the mtime was updated.  In\norder to avoid problems with the merge completing so fast that the mtime\nat the beginning and end of the operation was the same, these tests\nwould first set the mtime of a file to something \"old\".  This \"old\"\nvalue was usually determined as current system clock minus one second,\ntruncated to the nearest integer.  Unfortunately, it appears the system\nclock and filesystem clock are different and comparing across the two\nruns into race problems resulting in flaky tests.\n\nFrom https://stackoverflow.com/questions/14392975/timestamp-accuracy-on-ext4-sub-millsecond:\n\n    date will call the gettimeofday system call which will always return\n    the most accurate time available based on the cached kernel time,\n    adjusted by the CPU cycle time if available to give nanosecond\n    resolution. The timestamps stored in the file system however, are\n    only based on the cached kernel time. ie The time calculated at the\n    last timer interrupt.\n\nand from https://apenwarr.ca/log/20181113:\n\n    Does mtime get set to >= the current time?\n\n    No, this depends on clock granularity. For example, gettimeofday()\n    can return times in microseconds on my system, but ext4 rounds\n    timestamps down to the previous ~10ms (but not exactly 10ms)\n    increment, with the surprising result that a newly-created file is\n    almost always created in the past:\n\n      $ python -c \"\n      import os, time\n      t0 = time.time()\n      open('testfile', 'w').close()\n      print os.stat('testfile').st_mtime - t0\n      \"\n\n      -0.00234484672546\n\nSo, instead of trying to compare across what are effectively two\ndifferent clocks, just avoid using the system clock.  Any new updates to\nfiles have to give an mtime at least as big as what is already in the\nfile, so define \"old\" as one second before the mtime found in the file\nbefore the merge starts.\n\nAlso, clarify in one test where we check the mtime of different files\nthat it really was intentional.  I totally forgot the reasons for that\nand assumed it was a bug when asked.\n\nReported-by: SZEDER Gábor <szeder.dev@gmail.com>\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n    t6022, t6046: fix flaky files-are-updated checks\n    \n    Who knew that the system clock and the filesystem clock were apparently\n    different things, causing mtime comparisons to be flaky?\n    \n    Definitely not me. Fix the flaky tests that SZEDER reported and helped\n    track down the cause of.\n\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-725%2Fnewren%2Ftest-cleanup-more-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-725/newren/test-cleanup-more-v1\nPull-Request: https://github.com/git/git/pull/725\n\n t/t6022-merge-rename.sh                | 19 ++++++++++---------\n t/t6046-merge-skip-unneeded-updates.sh | 21 +++++++--------------\n 2 files changed, 17 insertions(+), 23 deletions(-)\n\ndiff --git a/t/t6022-merge-rename.sh b/t/t6022-merge-rename.sh\nindex d97cf48495b..23d51c55c8b 100755\n--- a/t/t6022-merge-rename.sh\n+++ b/t/t6022-merge-rename.sh\n@@ -243,8 +243,7 @@ test_expect_success 'merge of identical changes in a renamed file' '\n \tgit reset --hard &&\n \tgit checkout change+rename &&\n \n-\ttest-tool chmtime =31337 B &&\n-\ttest-tool chmtime --get B >old-mtime &&\n+\ttest-tool chmtime --get -1 B >old-mtime &&\n \tGIT_MERGE_VERBOSITY=3 git merge change >out &&\n \n \ttest-tool chmtime --get B >new-mtime &&\n@@ -253,10 +252,12 @@ test_expect_success 'merge of identical changes in a renamed file' '\n \tgit reset --hard HEAD^ &&\n \tgit checkout change &&\n \n-\ttest-tool chmtime =-1 M &&\n-\ttest-tool chmtime --get M >old-mtime &&\n+\t# A will be renamed to B; we check mtimes and file presence\n+\ttest_path_is_missing B &&\n+\ttest-tool chmtime --get -1 A >old-mtime &&\n \tGIT_MERGE_VERBOSITY=3 git merge change+rename >out &&\n \n+\ttest_path_is_missing A &&\n \ttest-tool chmtime --get B >new-mtime &&\n \ttest $(cat old-mtime) -lt $(cat new-mtime)\n '\n@@ -645,7 +646,7 @@ test_expect_success 'setup avoid unnecessary update, normal rename' '\n \n test_expect_success 'avoid unnecessary update, normal rename' '\n \tgit checkout -q avoid-unnecessary-update-1^0 &&\n-\ttest-tool chmtime --get =1000000000 rename >expect &&\n+\ttest-tool chmtime --get -1 rename >expect &&\n \tgit merge merge-branch-1 &&\n \ttest-tool chmtime --get rename >actual &&\n \ttest_cmp expect actual # \"rename\" should have stayed intact\n@@ -677,7 +678,7 @@ test_expect_success 'setup to test avoiding unnecessary update, with D/F conflic\n \n test_expect_success 'avoid unnecessary update, with D/F conflict' '\n \tgit checkout -q avoid-unnecessary-update-2^0 &&\n-\ttest-tool chmtime --get =1000000000 df >expect &&\n+\ttest-tool chmtime --get -1 df >expect &&\n \tgit merge merge-branch-2 &&\n \ttest-tool chmtime --get df >actual &&\n \ttest_cmp expect actual # \"df\" should have stayed intact\n@@ -708,7 +709,7 @@ test_expect_success 'setup avoid unnecessary update, dir->(file,nothing)' '\n \n test_expect_success 'avoid unnecessary update, dir->(file,nothing)' '\n \tgit checkout -q master^0 &&\n-\ttest-tool chmtime --get =1000000000 df >expect &&\n+\ttest-tool chmtime --get -1 df >expect &&\n \tgit merge side &&\n \ttest-tool chmtime --get df >actual &&\n \ttest_cmp expect actual # \"df\" should have stayed intact\n@@ -737,7 +738,7 @@ test_expect_success 'setup avoid unnecessary update, modify/delete' '\n \n test_expect_success 'avoid unnecessary update, modify/delete' '\n \tgit checkout -q master^0 &&\n-\ttest-tool chmtime --get =1000000000 file >expect &&\n+\ttest-tool chmtime --get -1 file >expect &&\n \ttest_must_fail git merge side &&\n \ttest-tool chmtime --get file >actual &&\n \ttest_cmp expect actual # \"file\" should have stayed intact\n@@ -765,7 +766,7 @@ test_expect_success 'setup avoid unnecessary update, rename/add-dest' '\n \n test_expect_success 'avoid unnecessary update, rename/add-dest' '\n \tgit checkout -q master^0 &&\n-\ttest-tool chmtime --get =1000000000 newfile >expect &&\n+\ttest-tool chmtime --get -1 newfile >expect &&\n \tgit merge side &&\n \ttest-tool chmtime --get newfile >actual &&\n \ttest_cmp expect actual # \"file\" should have stayed intact\ndiff --git a/t/t6046-merge-skip-unneeded-updates.sh b/t/t6046-merge-skip-unneeded-updates.sh\nindex 962030ecdb6..c7d0abb4ca3 100755\n--- a/t/t6046-merge-skip-unneeded-updates.sh\n+++ b/t/t6046-merge-skip-unneeded-updates.sh\n@@ -71,8 +71,7 @@ test_expect_success '1a-L: Modify(A)/Modify(B), change on B subset of A' '\n \n \t\tgit checkout A^0 &&\n \n-\t\ttest-tool chmtime =-1 b &&\n-\t\ttest-tool chmtime --get b >old-mtime &&\n+\t\ttest-tool chmtime --get -1 b >old-mtime &&\n \n \t\tGIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&\n \n@@ -102,8 +101,7 @@ test_expect_success '1a-R: Modify(A)/Modify(B), change on B subset of A' '\n \n \t\tgit checkout B^0 &&\n \n-\t\ttest-tool chmtime =-1 b &&\n-\t\ttest-tool chmtime --get b >old-mtime &&\n+\t\ttest-tool chmtime --get -1 b >old-mtime &&\n \t\tGIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err &&\n \n \t\t# Make sure b WAS updated\n@@ -198,8 +196,7 @@ test_expect_success '2a-R: Modify/rename, merge into rename side' '\n \n \t\tgit checkout B^0 &&\n \n-\t\ttest-tool chmtime =-1 c &&\n-\t\ttest-tool chmtime --get c >old-mtime &&\n+\t\ttest-tool chmtime --get -1 c >old-mtime &&\n \t\tGIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err &&\n \n \t\t# Make sure c WAS updated\n@@ -266,8 +263,7 @@ test_expect_success '2b-L: Rename+Mod(A)/Mod(B), B mods subset of A' '\n \n \t\tgit checkout A^0 &&\n \n-\t\ttest-tool chmtime =-1 c &&\n-\t\ttest-tool chmtime --get c >old-mtime &&\n+\t\ttest-tool chmtime --get -1 c >old-mtime &&\n \t\tGIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&\n \n \t\ttest_must_be_empty err &&\n@@ -373,8 +369,7 @@ test_expect_success '2c: Modify b & add c VS rename b->c' '\n \n \t\tgit checkout A^0 &&\n \n-\t\ttest-tool chmtime =-1 c &&\n-\t\ttest-tool chmtime --get c >old-mtime &&\n+\t\ttest-tool chmtime --get -1 c >old-mtime &&\n \t\tGIT_MERGE_VERBOSITY=3 &&\n \t\texport GIT_MERGE_VERBOSITY &&\n \t\ttest_must_fail git merge -s recursive B^0 >out 2>err &&\n@@ -679,8 +674,7 @@ test_expect_failure '4a: Change on A, change on B subset of A, dirty mods presen\n \t\tgit checkout A^0 &&\n \t\techo \"File rewritten\" >b &&\n \n-\t\ttest-tool chmtime =-1 b &&\n-\t\ttest-tool chmtime --get b >old-mtime &&\n+\t\ttest-tool chmtime --get -1 b >old-mtime &&\n \n \t\tGIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&\n \n@@ -747,8 +741,7 @@ test_expect_success '4b: Rename+Mod(A)/Mod(B), change on B subset of A, dirty mo\n \t\tgit checkout A^0 &&\n \t\techo \"File rewritten\" >c &&\n \n-\t\ttest-tool chmtime =-1 c &&\n-\t\ttest-tool chmtime --get c >old-mtime &&\n+\t\ttest-tool chmtime --get -1 c >old-mtime &&\n \n \t\tGIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&\n \n\nbase-commit: 30e9940356dc67959877f4b2417da33ebdefbb79\n-- \ngitgitgadget\n"},{"id":"393229","messageId":"xmqqtv2sawsf.fsf@gitster.c.googlers.com","threadId":"52992","inReplyTo":"pull.725.git.git.1584125875550.gitgitgadget@gmail.com","subject":"Re: [PATCH] t6022, t6046: fix flaky files-are-updated checks","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-03-13T19:18:24Z","receivedAt":"2020-03-13T19:18:30Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Elijah Newren via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Elijah Newren <newren@gmail.com>\n>\n> Several tests wanted to verify that files were actually modified by a\n> merge, which it would do by checking that the mtime was updated.  In\n> order to avoid problems with the merge completing so fast that the mtime\n> at the beginning and end of the operation was the same, these tests\n> would first set the mtime of a file to something \"old\".  This \"old\"\n> value was usually determined as current system clock minus one second,\n> truncated to the nearest integer.  Unfortunately, it appears the system\n> clock and filesystem clock are different and comparing across the two\n> runs into race problems resulting in flaky tests.\n\nGood observation (and if we were doing networked filesystems, things\nwould be worse).\n\n> So, instead of trying to compare across what are effectively two\n> different clocks, just avoid using the system clock.  Any new updates to\n> files have to give an mtime at least as big as what is already in the\n> file, so define \"old\" as one second before the mtime found in the file\n> before the merge starts.\n\nIs there a reason why we prefer as small an offset as possible?  I\nam not objecting to the choice of 1 second, but am curious if\nanything bad happens if we used a larger offset, say, 2 hours.\n\nThanks.\n"},{"id":"393230","messageId":"CABPp-BHGsED9noSgAt_OH5G8iXOAvS2cjEV-MDL=hjk365=NdQ@mail.gmail.com","threadId":"52992","inReplyTo":"xmqqtv2sawsf.fsf@gitster.c.googlers.com","subject":"Re: [PATCH] t6022, t6046: fix flaky files-are-updated checks","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-03-13T19:27:18Z","receivedAt":"2020-03-13T19:27:31Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Fri, Mar 13, 2020 at 12:18 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> \"Elijah Newren via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n>\n> > From: Elijah Newren <newren@gmail.com>\n> >\n> > Several tests wanted to verify that files were actually modified by a\n> > merge, which it would do by checking that the mtime was updated.  In\n> > order to avoid problems with the merge completing so fast that the mtime\n> > at the beginning and end of the operation was the same, these tests\n> > would first set the mtime of a file to something \"old\".  This \"old\"\n> > value was usually determined as current system clock minus one second,\n> > truncated to the nearest integer.  Unfortunately, it appears the system\n> > clock and filesystem clock are different and comparing across the two\n> > runs into race problems resulting in flaky tests.\n>\n> Good observation (and if we were doing networked filesystems, things\n> would be worse).\n>\n> > So, instead of trying to compare across what are effectively two\n> > different clocks, just avoid using the system clock.  Any new updates to\n> > files have to give an mtime at least as big as what is already in the\n> > file, so define \"old\" as one second before the mtime found in the file\n> > before the merge starts.\n>\n> Is there a reason why we prefer as small an offset as possible?  I\n> am not objecting to the choice of 1 second, but am curious if\n> anything bad happens if we used a larger offset, say, 2 hours.\n\nI was thinking about putting in some magic larger number, but was\nwondering if I needed to explain it or if people might spend cycles\nthinking about the significance of the random number selected.\n\nHowever, a larger value might be useful in the face of leap seconds\nand ntp time updates, so I should probably move that direction.\n\nAny preferences on whether I should I pick something like 3600 (large\nbut easily recognizable), something more round like 10000, or\nsomething else?\n"},{"id":"393232","messageId":"xmqqlfo4avo2.fsf@gitster.c.googlers.com","threadId":"52992","inReplyTo":"CABPp-BHGsED9noSgAt_OH5G8iXOAvS2cjEV-MDL=hjk365=NdQ@mail.gmail.com","subject":"Re: [PATCH] t6022, t6046: fix flaky files-are-updated checks","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-03-13T19:42:37Z","receivedAt":"2020-03-13T19:42:46Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Elijah Newren <newren@gmail.com> writes:\n\n> However, a larger value might be useful in the face of leap seconds\n> and ntp time updates, so I should probably move that direction.\n>\n> Any preferences on whether I should I pick something like 3600 (large\n> but easily recognizable), something more round like 10000, or\n> something else?\n\nAs long as filesystem timestamp monotonically increases, any value\nthat is the same or larger than the time granularity should be OK,\nand it sounds reasonable for filesystem timestamp to have at least 1\nsecond resolution.\n\nEhh, do we still need to worry about the ones that has 2 second\nresolution or coarser?  What does \"adjust the file timestamp by\ndecrementing 1 second from the current value\" do?  Do we risk ending\nup with the same timestamp as we started with?\n\nI have no strong preference between 3600 and 10000, but to me 1\nsmells a bit iffy.  \"test-tool chmtime --get -9 file\" is still\nspelled in the same number of bytes as one second offset and has a\nlarger margin ;-)\n"},{"id":"393233","messageId":"pull.725.v2.git.git.1584129783076.gitgitgadget@gmail.com","threadId":"52992","inReplyTo":"pull.725.git.git.1584125875550.gitgitgadget@gmail.com","subject":"[PATCH v2] t6022, t6046: fix flaky files-are-updated checks","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-03-13T20:03:02Z","receivedAt":"2020-03-13T20:03:11Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nSeveral tests wanted to verify that files were actually modified by a\nmerge, which it would do by checking that the mtime was updated.  In\norder to avoid problems with the merge completing so fast that the mtime\nat the beginning and end of the operation was the same, these tests\nwould first set the mtime of a file to something \"old\".  This \"old\"\nvalue was usually determined as current system clock minus one second,\ntruncated to the nearest integer.  Unfortunately, it appears the system\nclock and filesystem clock are different and comparing across the two\nruns into race problems resulting in flaky tests.\n\nFrom https://stackoverflow.com/questions/14392975/timestamp-accuracy-on-ext4-sub-millsecond:\n\n    date will call the gettimeofday system call which will always return\n    the most accurate time available based on the cached kernel time,\n    adjusted by the CPU cycle time if available to give nanosecond\n    resolution. The timestamps stored in the file system however, are\n    only based on the cached kernel time. ie The time calculated at the\n    last timer interrupt.\n\nand from https://apenwarr.ca/log/20181113:\n\n    Does mtime get set to >= the current time?\n\n    No, this depends on clock granularity. For example, gettimeofday()\n    can return times in microseconds on my system, but ext4 rounds\n    timestamps down to the previous ~10ms (but not exactly 10ms)\n    increment, with the surprising result that a newly-created file is\n    almost always created in the past:\n\n      $ python -c \"\n      import os, time\n      t0 = time.time()\n      open('testfile', 'w').close()\n      print os.stat('testfile').st_mtime - t0\n      \"\n\n      -0.00234484672546\n\nSo, instead of trying to compare across what are effectively two\ndifferent clocks, just avoid using the system clock.  Any new updates to\nfiles have to give an mtime at least as big as what is already in the\nfile, so we could define \"old\" as one second before the mtime found in\nthe file before the merge starts.  But, to avoid problems with leap\nseconds, ntp updates, filesystems that only provide two second\nresolution, and other such weirdness, let's just pick an hour before the\nmtime found in the file before the merge starts.\n\nAlso, clarify in one test where we check the mtime of different files\nthat it really was intentional.  I totally forgot the reasons for that\nand assumed it was a bug when asked.\n\nReported-by: SZEDER Gábor <szeder.dev@gmail.com>\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n    t6022, t6046: fix flaky files-are-updated checks\n    \n    Who knew that the system clock and the filesystem clock were apparently\n    different things, causing mtime comparisons to be flaky?\n    \n    Definitely not me. Fix the flaky tests that SZEDER reported and helped\n    track down the cause of.\n\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-725%2Fnewren%2Ftest-cleanup-more-v2\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-725/newren/test-cleanup-more-v2\nPull-Request: https://github.com/git/git/pull/725\n\nRange-diff vs v1:\n\n 1:  dfe1f66112b ! 1:  6f603695093 t6022, t6046: fix flaky files-are-updated checks\n     @@ -43,8 +43,11 @@\n          So, instead of trying to compare across what are effectively two\n          different clocks, just avoid using the system clock.  Any new updates to\n          files have to give an mtime at least as big as what is already in the\n     -    file, so define \"old\" as one second before the mtime found in the file\n     -    before the merge starts.\n     +    file, so we could define \"old\" as one second before the mtime found in\n     +    the file before the merge starts.  But, to avoid problems with leap\n     +    seconds, ntp updates, filesystems that only provide two second\n     +    resolution, and other such weirdness, let's just pick an hour before the\n     +    mtime found in the file before the merge starts.\n      \n          Also, clarify in one test where we check the mtime of different files\n          that it really was intentional.  I totally forgot the reasons for that\n     @@ -62,7 +65,7 @@\n       \n      -\ttest-tool chmtime =31337 B &&\n      -\ttest-tool chmtime --get B >old-mtime &&\n     -+\ttest-tool chmtime --get -1 B >old-mtime &&\n     ++\ttest-tool chmtime --get -3600 B >old-mtime &&\n       \tGIT_MERGE_VERBOSITY=3 git merge change >out &&\n       \n       \ttest-tool chmtime --get B >new-mtime &&\n     @@ -74,7 +77,7 @@\n      -\ttest-tool chmtime --get M >old-mtime &&\n      +\t# A will be renamed to B; we check mtimes and file presence\n      +\ttest_path_is_missing B &&\n     -+\ttest-tool chmtime --get -1 A >old-mtime &&\n     ++\ttest-tool chmtime --get -3600 A >old-mtime &&\n       \tGIT_MERGE_VERBOSITY=3 git merge change+rename >out &&\n       \n      +\ttest_path_is_missing A &&\n     @@ -86,7 +89,7 @@\n       test_expect_success 'avoid unnecessary update, normal rename' '\n       \tgit checkout -q avoid-unnecessary-update-1^0 &&\n      -\ttest-tool chmtime --get =1000000000 rename >expect &&\n     -+\ttest-tool chmtime --get -1 rename >expect &&\n     ++\ttest-tool chmtime --get -3600 rename >expect &&\n       \tgit merge merge-branch-1 &&\n       \ttest-tool chmtime --get rename >actual &&\n       \ttest_cmp expect actual # \"rename\" should have stayed intact\n     @@ -95,7 +98,7 @@\n       test_expect_success 'avoid unnecessary update, with D/F conflict' '\n       \tgit checkout -q avoid-unnecessary-update-2^0 &&\n      -\ttest-tool chmtime --get =1000000000 df >expect &&\n     -+\ttest-tool chmtime --get -1 df >expect &&\n     ++\ttest-tool chmtime --get -3600 df >expect &&\n       \tgit merge merge-branch-2 &&\n       \ttest-tool chmtime --get df >actual &&\n       \ttest_cmp expect actual # \"df\" should have stayed intact\n     @@ -104,7 +107,7 @@\n       test_expect_success 'avoid unnecessary update, dir->(file,nothing)' '\n       \tgit checkout -q master^0 &&\n      -\ttest-tool chmtime --get =1000000000 df >expect &&\n     -+\ttest-tool chmtime --get -1 df >expect &&\n     ++\ttest-tool chmtime --get -3600 df >expect &&\n       \tgit merge side &&\n       \ttest-tool chmtime --get df >actual &&\n       \ttest_cmp expect actual # \"df\" should have stayed intact\n     @@ -113,7 +116,7 @@\n       test_expect_success 'avoid unnecessary update, modify/delete' '\n       \tgit checkout -q master^0 &&\n      -\ttest-tool chmtime --get =1000000000 file >expect &&\n     -+\ttest-tool chmtime --get -1 file >expect &&\n     ++\ttest-tool chmtime --get -3600 file >expect &&\n       \ttest_must_fail git merge side &&\n       \ttest-tool chmtime --get file >actual &&\n       \ttest_cmp expect actual # \"file\" should have stayed intact\n     @@ -122,7 +125,7 @@\n       test_expect_success 'avoid unnecessary update, rename/add-dest' '\n       \tgit checkout -q master^0 &&\n      -\ttest-tool chmtime --get =1000000000 newfile >expect &&\n     -+\ttest-tool chmtime --get -1 newfile >expect &&\n     ++\ttest-tool chmtime --get -3600 newfile >expect &&\n       \tgit merge side &&\n       \ttest-tool chmtime --get newfile >actual &&\n       \ttest_cmp expect actual # \"file\" should have stayed intact\n     @@ -136,7 +139,7 @@\n       \n      -\t\ttest-tool chmtime =-1 b &&\n      -\t\ttest-tool chmtime --get b >old-mtime &&\n     -+\t\ttest-tool chmtime --get -1 b >old-mtime &&\n     ++\t\ttest-tool chmtime --get -3600 b >old-mtime &&\n       \n       \t\tGIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&\n       \n     @@ -146,7 +149,7 @@\n       \n      -\t\ttest-tool chmtime =-1 b &&\n      -\t\ttest-tool chmtime --get b >old-mtime &&\n     -+\t\ttest-tool chmtime --get -1 b >old-mtime &&\n     ++\t\ttest-tool chmtime --get -3600 b >old-mtime &&\n       \t\tGIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err &&\n       \n       \t\t# Make sure b WAS updated\n     @@ -156,7 +159,7 @@\n       \n      -\t\ttest-tool chmtime =-1 c &&\n      -\t\ttest-tool chmtime --get c >old-mtime &&\n     -+\t\ttest-tool chmtime --get -1 c >old-mtime &&\n     ++\t\ttest-tool chmtime --get -3600 c >old-mtime &&\n       \t\tGIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err &&\n       \n       \t\t# Make sure c WAS updated\n     @@ -166,7 +169,7 @@\n       \n      -\t\ttest-tool chmtime =-1 c &&\n      -\t\ttest-tool chmtime --get c >old-mtime &&\n     -+\t\ttest-tool chmtime --get -1 c >old-mtime &&\n     ++\t\ttest-tool chmtime --get -3600 c >old-mtime &&\n       \t\tGIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&\n       \n       \t\ttest_must_be_empty err &&\n     @@ -176,7 +179,7 @@\n       \n      -\t\ttest-tool chmtime =-1 c &&\n      -\t\ttest-tool chmtime --get c >old-mtime &&\n     -+\t\ttest-tool chmtime --get -1 c >old-mtime &&\n     ++\t\ttest-tool chmtime --get -3600 c >old-mtime &&\n       \t\tGIT_MERGE_VERBOSITY=3 &&\n       \t\texport GIT_MERGE_VERBOSITY &&\n       \t\ttest_must_fail git merge -s recursive B^0 >out 2>err &&\n     @@ -186,7 +189,7 @@\n       \n      -\t\ttest-tool chmtime =-1 b &&\n      -\t\ttest-tool chmtime --get b >old-mtime &&\n     -+\t\ttest-tool chmtime --get -1 b >old-mtime &&\n     ++\t\ttest-tool chmtime --get -3600 b >old-mtime &&\n       \n       \t\tGIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&\n       \n     @@ -196,7 +199,7 @@\n       \n      -\t\ttest-tool chmtime =-1 c &&\n      -\t\ttest-tool chmtime --get c >old-mtime &&\n     -+\t\ttest-tool chmtime --get -1 c >old-mtime &&\n     ++\t\ttest-tool chmtime --get -3600 c >old-mtime &&\n       \n       \t\tGIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&\n       \n\n\n t/t6022-merge-rename.sh                | 19 ++++++++++---------\n t/t6046-merge-skip-unneeded-updates.sh | 21 +++++++--------------\n 2 files changed, 17 insertions(+), 23 deletions(-)\n\ndiff --git a/t/t6022-merge-rename.sh b/t/t6022-merge-rename.sh\nindex d97cf48495b..bbbba3dcbf0 100755\n--- a/t/t6022-merge-rename.sh\n+++ b/t/t6022-merge-rename.sh\n@@ -243,8 +243,7 @@ test_expect_success 'merge of identical changes in a renamed file' '\n \tgit reset --hard &&\n \tgit checkout change+rename &&\n \n-\ttest-tool chmtime =31337 B &&\n-\ttest-tool chmtime --get B >old-mtime &&\n+\ttest-tool chmtime --get -3600 B >old-mtime &&\n \tGIT_MERGE_VERBOSITY=3 git merge change >out &&\n \n \ttest-tool chmtime --get B >new-mtime &&\n@@ -253,10 +252,12 @@ test_expect_success 'merge of identical changes in a renamed file' '\n \tgit reset --hard HEAD^ &&\n \tgit checkout change &&\n \n-\ttest-tool chmtime =-1 M &&\n-\ttest-tool chmtime --get M >old-mtime &&\n+\t# A will be renamed to B; we check mtimes and file presence\n+\ttest_path_is_missing B &&\n+\ttest-tool chmtime --get -3600 A >old-mtime &&\n \tGIT_MERGE_VERBOSITY=3 git merge change+rename >out &&\n \n+\ttest_path_is_missing A &&\n \ttest-tool chmtime --get B >new-mtime &&\n \ttest $(cat old-mtime) -lt $(cat new-mtime)\n '\n@@ -645,7 +646,7 @@ test_expect_success 'setup avoid unnecessary update, normal rename' '\n \n test_expect_success 'avoid unnecessary update, normal rename' '\n \tgit checkout -q avoid-unnecessary-update-1^0 &&\n-\ttest-tool chmtime --get =1000000000 rename >expect &&\n+\ttest-tool chmtime --get -3600 rename >expect &&\n \tgit merge merge-branch-1 &&\n \ttest-tool chmtime --get rename >actual &&\n \ttest_cmp expect actual # \"rename\" should have stayed intact\n@@ -677,7 +678,7 @@ test_expect_success 'setup to test avoiding unnecessary update, with D/F conflic\n \n test_expect_success 'avoid unnecessary update, with D/F conflict' '\n \tgit checkout -q avoid-unnecessary-update-2^0 &&\n-\ttest-tool chmtime --get =1000000000 df >expect &&\n+\ttest-tool chmtime --get -3600 df >expect &&\n \tgit merge merge-branch-2 &&\n \ttest-tool chmtime --get df >actual &&\n \ttest_cmp expect actual # \"df\" should have stayed intact\n@@ -708,7 +709,7 @@ test_expect_success 'setup avoid unnecessary update, dir->(file,nothing)' '\n \n test_expect_success 'avoid unnecessary update, dir->(file,nothing)' '\n \tgit checkout -q master^0 &&\n-\ttest-tool chmtime --get =1000000000 df >expect &&\n+\ttest-tool chmtime --get -3600 df >expect &&\n \tgit merge side &&\n \ttest-tool chmtime --get df >actual &&\n \ttest_cmp expect actual # \"df\" should have stayed intact\n@@ -737,7 +738,7 @@ test_expect_success 'setup avoid unnecessary update, modify/delete' '\n \n test_expect_success 'avoid unnecessary update, modify/delete' '\n \tgit checkout -q master^0 &&\n-\ttest-tool chmtime --get =1000000000 file >expect &&\n+\ttest-tool chmtime --get -3600 file >expect &&\n \ttest_must_fail git merge side &&\n \ttest-tool chmtime --get file >actual &&\n \ttest_cmp expect actual # \"file\" should have stayed intact\n@@ -765,7 +766,7 @@ test_expect_success 'setup avoid unnecessary update, rename/add-dest' '\n \n test_expect_success 'avoid unnecessary update, rename/add-dest' '\n \tgit checkout -q master^0 &&\n-\ttest-tool chmtime --get =1000000000 newfile >expect &&\n+\ttest-tool chmtime --get -3600 newfile >expect &&\n \tgit merge side &&\n \ttest-tool chmtime --get newfile >actual &&\n \ttest_cmp expect actual # \"file\" should have stayed intact\ndiff --git a/t/t6046-merge-skip-unneeded-updates.sh b/t/t6046-merge-skip-unneeded-updates.sh\nindex 962030ecdb6..1ddc9e6626b 100755\n--- a/t/t6046-merge-skip-unneeded-updates.sh\n+++ b/t/t6046-merge-skip-unneeded-updates.sh\n@@ -71,8 +71,7 @@ test_expect_success '1a-L: Modify(A)/Modify(B), change on B subset of A' '\n \n \t\tgit checkout A^0 &&\n \n-\t\ttest-tool chmtime =-1 b &&\n-\t\ttest-tool chmtime --get b >old-mtime &&\n+\t\ttest-tool chmtime --get -3600 b >old-mtime &&\n \n \t\tGIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&\n \n@@ -102,8 +101,7 @@ test_expect_success '1a-R: Modify(A)/Modify(B), change on B subset of A' '\n \n \t\tgit checkout B^0 &&\n \n-\t\ttest-tool chmtime =-1 b &&\n-\t\ttest-tool chmtime --get b >old-mtime &&\n+\t\ttest-tool chmtime --get -3600 b >old-mtime &&\n \t\tGIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err &&\n \n \t\t# Make sure b WAS updated\n@@ -198,8 +196,7 @@ test_expect_success '2a-R: Modify/rename, merge into rename side' '\n \n \t\tgit checkout B^0 &&\n \n-\t\ttest-tool chmtime =-1 c &&\n-\t\ttest-tool chmtime --get c >old-mtime &&\n+\t\ttest-tool chmtime --get -3600 c >old-mtime &&\n \t\tGIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err &&\n \n \t\t# Make sure c WAS updated\n@@ -266,8 +263,7 @@ test_expect_success '2b-L: Rename+Mod(A)/Mod(B), B mods subset of A' '\n \n \t\tgit checkout A^0 &&\n \n-\t\ttest-tool chmtime =-1 c &&\n-\t\ttest-tool chmtime --get c >old-mtime &&\n+\t\ttest-tool chmtime --get -3600 c >old-mtime &&\n \t\tGIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&\n \n \t\ttest_must_be_empty err &&\n@@ -373,8 +369,7 @@ test_expect_success '2c: Modify b & add c VS rename b->c' '\n \n \t\tgit checkout A^0 &&\n \n-\t\ttest-tool chmtime =-1 c &&\n-\t\ttest-tool chmtime --get c >old-mtime &&\n+\t\ttest-tool chmtime --get -3600 c >old-mtime &&\n \t\tGIT_MERGE_VERBOSITY=3 &&\n \t\texport GIT_MERGE_VERBOSITY &&\n \t\ttest_must_fail git merge -s recursive B^0 >out 2>err &&\n@@ -679,8 +674,7 @@ test_expect_failure '4a: Change on A, change on B subset of A, dirty mods presen\n \t\tgit checkout A^0 &&\n \t\techo \"File rewritten\" >b &&\n \n-\t\ttest-tool chmtime =-1 b &&\n-\t\ttest-tool chmtime --get b >old-mtime &&\n+\t\ttest-tool chmtime --get -3600 b >old-mtime &&\n \n \t\tGIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&\n \n@@ -747,8 +741,7 @@ test_expect_success '4b: Rename+Mod(A)/Mod(B), change on B subset of A, dirty mo\n \t\tgit checkout A^0 &&\n \t\techo \"File rewritten\" >c &&\n \n-\t\ttest-tool chmtime =-1 c &&\n-\t\ttest-tool chmtime --get c >old-mtime &&\n+\t\ttest-tool chmtime --get -3600 c >old-mtime &&\n \n \t\tGIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&\n \n\nbase-commit: 30e9940356dc67959877f4b2417da33ebdefbb79\n-- \ngitgitgadget\n"}]}