git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [RFC] git checkout $tree -- $path always rewrites files

From
Junio C Hamano <gitster@pobox.com>
Date
Nov 13, 2014, 19:15 UTC
Message-ID
<xmqqbnoa29ps.fsf@gitster.dls.corp.google.com>
In-Reply-To
<20141113183033.GA24107@peff.net>
Jeff King <peff@peff.net> writes:
Show 18 quoted lines
> On Sun, Nov 09, 2014 at 09:21:49AM -0800, Junio C Hamano wrote:
>
>> Jeff King <peff@peff.net> writes:
>> 
>> > On Fri, Nov 07, 2014 at 11:35:59PM -0800, Junio C Hamano wrote:
>> >
>> >> I think that has direct linkage; what you have in mind I think is
>> >> http://thread.gmane.org/gmane.comp.version-control.git/234903/focus=234935
>> >
>> > Thanks for that link.
>> 
>> It was one of the items in the "git blame leftover bits" list
>> (websearch for that exact phrase), so I didn't have to do any
>> digging just for this thread ;-)
>> 
>> But I made a huge typo above.  s/I think/I do not think/;
>
> Oh. That might explain some of my confusion. :)
Yeah, tells me to never type on a tablet X-<.
Show 6 quoted lines
>> I'd prefer that these two to be treated separately.
>
> Yeah, that makes sense after reading your emails. What I was really
> unclear on was whether the handling of deletion was a bug or a design
> choice, and it is the latter (if it were the former, we would not need a
> transition plan :) ).

Yeah, I think we agree to refrain from saying if that design choice was a good one or bad one at least for now.

Show 46 quoted lines
> Subject: checkout $tree: do not throw away unchanged index entries
>
> When we "git checkout $tree", we pull paths from $tree into
> the index, and then check the resulting entries out to the
> worktree. Our method for the first step is rather
> heavy-handed, though; it clobbers the entire existing index
> entry, even if the content is the same. This means we lose
> our stat information, leading checkout_entry to later
> rewrite the entire file with identical content.
>
> Instead, let's see if we have the identical entry already in
> the index, in which case we leave it in place. That lets
> checkout_entry do the right thing. Our tests cover two
> interesting cases:
>
>   1. We make sure that a file which has no changes is not
>      rewritten.
>
>   2. We make sure that we do update a file that is unchanged
>      in the index (versus $tree), but has working tree
>      changes. We keep the old index entry, and
>      checkout_entry is able to realize that our stat
>      information is out of date.
>
> Signed-off-by: Jeff King <peff@peff.net>
> ---
> Note that the test refreshes the index manually (because we are tweaking
> the timestamp of file2). In normal use this should not be necessary
> (i.e., your entries should generally be uptodate). I did wonder if
> checkout should be refreshing the index itself, but it would a bunch of
> extra lstats in the common case.
>
>  builtin/checkout.c        | 31 +++++++++++++++++++++++++------
>  t/t2022-checkout-paths.sh | 17 +++++++++++++++++
>  2 files changed, 42 insertions(+), 6 deletions(-)
>
> diff --git a/builtin/checkout.c b/builtin/checkout.c
> index 5410dac..67cab4e 100644
> --- a/builtin/checkout.c
> +++ b/builtin/checkout.c
> @@ -65,21 +65,40 @@ static int post_checkout_hook(struct commit *old, struct commit *new,
>  static int update_some(const unsigned char *sha1, const char *base, int baselen,
>  		const char *pathname, unsigned mode, int stage, void *context)
>  {
> ...
>  }

Makes sense, including the use of strbuf (otherwise you would allocate ce and then discard when it turns out that it is not needed, which is probably with the same allocation pressure, but looks uglier).

Show 16 quoted lines
> diff --git a/t/t2022-checkout-paths.sh b/t/t2022-checkout-paths.sh
> index 8e3545d..f46d049 100755
> --- a/t/t2022-checkout-paths.sh
> +++ b/t/t2022-checkout-paths.sh
> @@ -61,4 +61,21 @@ test_expect_success 'do not touch unmerged entries matching $path but not in $tr
>  	test_cmp expect.next0 actual.next0
>  '
>  
> +test_expect_success 'do not touch files that are already up-to-date' '
> +	git reset --hard &&
> +	echo one >file1 &&
> +	echo two >file2 &&
> +	git add file1 file2 &&
> +	git commit -m base &&
> +	echo modified >file1 &&
> +	test-chmtime =1000000000 file2 &&

Is the idea behind the hardcoded timestamp that this is sufficiently old (Sep 2001) that we will not get in trouble comparing with the real timestamp we get from the filesystem (which will definitely newer than that anyway) no matter when we run this test (unless you have a time-machine, that is)?

Show 10 quoted lines
> +	git update-index -q --refresh &&
> +	git checkout HEAD -- file1 file2 &&
> +	echo one >expect &&
> +	test_cmp expect file1 &&
> +	echo "1000000000	file2" >expect &&
> +	test-chmtime -v +0 file2 >actual &&
> +	test_cmp expect actual
> +'
> +
>  test_done
Previous: Jeff KingNext: Jeff King
Message 17 of 23 in “[RFC] git checkout $tree -- $path always rewrites files”
  1. Jeff KingNov 7, 2014
  2. Jeff KingNov 7, 2014
  3. Duy NguyenNov 7, 2014
  4. Junio C HamanoNov 7, 2014
  5. Jeff KingNov 7, 2014
  6. Junio C HamanoNov 7, 2014
  7. Jeff KingNov 7, 2014
  8. Martin von ZweigbergkNov 8, 2014
  9. Martin von ZweigbergkNov 8, 2014
  10. Jeff KingNov 8, 2014
  11. Jeff KingNov 8, 2014
  12. Junio C HamanoNov 9, 2014
  13. Martin von ZweigbergkNov 8, 2014
  14. Jeff KingNov 9, 2014
  15. Junio C HamanoNov 9, 2014
  16. Jeff KingNov 13, 2014
  17. Junio C HamanoNov 13, 2014
  18. Jeff KingNov 13, 2014
  19. Jeff KingNov 13, 2014
  20. Junio C HamanoNov 13, 2014
  21. Jeff KingNov 13, 2014
  22. David AguilarNov 14, 2014
  23. Junio C HamanoNov 14, 2014

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.