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

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

From
Jeff King <peff@peff.net>
Date
Nov 13, 2014, 20:03 UTC
Message-ID
<20141113200315.GA3869@peff.net>
In-Reply-To
<20141113192655.GA3413@peff.net>
On Thu, Nov 13, 2014 at 02:26:55PM -0500, Jeff King wrote:
Show 9 quoted lines
> > 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).
> 
> Exactly. Constructing it in ce->name does save you an allocation/memcpy
> in the case that we actually use the new entry, but I thought it would
> look weirder. It probably doesn't matter much either way, so I tried to
> write the most obvious thing.
Actually, it is not that bad:
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 5410dac..5a78758 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -67,6 +67,7 @@ static int update_some(const unsigned char *sha1, const char *base, int baselen,
 {
 	int len;
 	struct cache_entry *ce;
+	int pos;
 
 	if (S_ISDIR(mode))
 		return READ_TREE_RECURSIVE;
@@ -79,6 +80,23 @@ static int update_some(const unsigned char *sha1, const char *base, int baselen,
 	ce->ce_flags = create_ce_flags(0) | CE_UPDATE;
 	ce->ce_namelen = len;
 	ce->ce_mode = create_ce_mode(mode);
+
+	/*
+	 * If the entry is the same as the current index, we can leave the old
+	 * entry in place. Whether it is UPTODATE or not, checkout_entry will
+	 * do the right thing.
+	 */
+	pos = cache_name_pos(ce->name, ce->ce_namelen);
+	if (pos >= 0) {
+		struct cache_entry *old = active_cache[pos];
+		if (ce->ce_mode == old->ce_mode &&
+		    !hashcmp(ce->sha1, old->sha1)) {
+			old->ce_flags |= CE_UPDATE;
+			free(ce);
+			return 0;
+		}
+	}
+
 	add_cache_entry(ce, ADD_CACHE_OK_TO_ADD | ADD_CACHE_OK_TO_REPLACE);
 	return 0;
 }

and in some ways more readable, as you form the whole thing, and then as
the final step either add it, or realize that what is there is fine (I'd
almost wonder if it could be a flag to add_cache_entry).

-Peff
Previous: Jeff KingNext: Junio C Hamano
Message 19 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.