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

Re: [PATCH] t4202 (log): add failing test for log with subtree

From
Ramkumar Ramachandra <artagnon@gmail.com>
Date
Apr 23, 2013, 07:53 UTC
Message-ID
<CALkWK0noVfRoXAH75r4yBijXSHD5yusLcKgGC=8bjOW6=qCMng@mail.gmail.com>
In-Reply-To
<7vehe2m88a.fsf@alter.siamese.dyndns.org>
Junio C Hamano wrote:
Show 6 quoted lines
> It sounds like you are repeating the same old "let's record renames
> in the commit", and in a system (not Git) where recording renames
> may make sense, you may be making sense.
>
> But we will not record renames in the commit.  Time to re-read
> $gmane/217, perhaps?

Yeah, you're right. It makes no sense to record renames, although I have a different argument against it: any implementation that records renames will depend on the path that was taken to get to the final state, and this is completely wrong. Subversion made this mistake, and users pay a very heavy price: if the user didn't explicitly rename a node (~= tree) and just did a delete + add, the repository is more-or-less screwed wrt merging.

Forget everything that I said, and let's start over.

In the common usecase of subtrees, it might make sense to record some additional submodule-like parameters in the subtree's tree object. This additional information is entirely optional, and doesn't change the way merges happen: we can have it as merely a heuristic-helper (for git merge -s subtree). Initially, let's just think of putting a ref field in the tree, so that I can have the following setup:

- remote origin referring to my superproject.
- remote git/origin referring to the fetchdefault of my subproject git.
- remote git/ram referring to the pushdefault of my subproject.
- the tree object corresponding to quux/baz/git is additionally filled
in with the ref refs/remotes/git/origin/master.

Then, I can just say git pull quux/baz/git, and it will automatically fetch changes from the ref and merge it into the subtree. It's not to say that I can't merge any other ref; just that I merge this ref most of the time, and I want a DWIM for this case.

Further, this can speed up tree-rename detection greatly (in fact, I'm thinking the first implementation will depend on this information being present). I inspect M^{tree} and I want to know how it's composed from M^1^{tree} and M^2^{tree}. Simple. In M^{tree}, look for trees that have this additional data filled in: then we can just short-circuit the rename detection to matching the similarity of this tree with M^1^{tree} and M^2^{tree}.

When this aux data is present in the tree, we can do one more thing: have a symref tracking the commit-line corresponding to M^2. This means that we can DWIM for things like 'git commit' inside the subtree very easily. When the aux information is not present, 'git commit' will obviously commit to HEAD, essentially making the superproject own those changes in the subtree (as it does now).

This might be the route to implementing narrow clones sensibly. A narrow clone does not mean that any directory in the entire repository can be cloned separately: it just means that a tree with this aux data need not be fetched in the initial clone. For this to work, instead of refs/remotes/git/origin/master, the aux data will need a combination of upstream URL and ref: we can then automatically figure out the name from the URL and deposit the fetched data in refs/remotes/<name>/origin/<ref>.

Initializing nested submodules without the container is also easy: in the superproject, you need to have aux-trees corresponding to quux/baz/git and quux/baz/git/moo/clayoven. It might additionally be a good idea to track these aux-trees: but even if we don't go down that route, we can always deposit a "template" file from the superproject that won't interfere with the subtree merging process.

Now, I'm not sure what the value of splitting the object stores at this point is. The aux-tree can have a statthrough field to block stat() calls from going through, so there's really no performance issue. If you want to separate one tree out of the superproject and work on it separately, all you have to do is fetch the corresponding ref.

On the issue of floating submodules. It might make sense to zero out the hex of the tree, as seen by the superproject. The limitation is that we can't introduce any changes to the submodule from the superproject: it's basically a dummy entry sitting in the superproject's tree. It's a bit of a hack, but I think it's workable.

So, what do you think?
Previous: Junio C HamanoNext: Junio C Hamano
Message 27 of 34 in “t4202 (log): add failing test for log with subtree”
  1. t4202 (log): add failing test for log with subtreeRamkumar Ramachandra, Apr 22, 2013
  2. Matthieu MoyApr 22, 2013
  3. Thomas RastApr 22, 2013
  4. Ramkumar RamachandraApr 22, 2013
  5. Ramkumar RamachandraApr 22, 2013
  6. Ramkumar RamachandraApr 22, 2013
  7. Matthieu MoyApr 22, 2013
  8. Thomas RastApr 22, 2013
  9. Thomas RastApr 22, 2013
  10. Ramkumar RamachandraApr 22, 2013
  11. Ramkumar RamachandraApr 22, 2013
  12. Thomas RastApr 22, 2013
  13. Ramkumar RamachandraApr 22, 2013
  14. Ramkumar RamachandraApr 22, 2013
  15. Ramkumar RamachandraApr 22, 2013
  16. Ramkumar RamachandraApr 22, 2013
  17. Thomas RastApr 22, 2013
  18. Ramkumar RamachandraApr 22, 2013
  19. Philip OakleyApr 22, 2013
  20. Ramkumar RamachandraApr 22, 2013
  21. Ramkumar RamachandraApr 22, 2013
  22. Matthieu MoyApr 22, 2013
  23. Junio C HamanoApr 22, 2013
  24. Ramkumar RamachandraApr 22, 2013
  25. Ramkumar RamachandraApr 22, 2013
  26. Junio C HamanoApr 22, 2013
  27. Ramkumar RamachandraApr 23, 2013
  28. Junio C HamanoApr 23, 2013
  29. Ramkumar RamachandraApr 23, 2013
  30. Junio C HamanoApr 22, 2013
  31. Ramkumar RamachandraApr 22, 2013
  32. Matthieu MoyApr 22, 2013
  33. Junio C HamanoApr 22, 2013
  34. Ramkumar RamachandraApr 22, 2013

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.