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

Using git-update-index to add existing tree objects at other paths

From
Sean Allred <allred.sean@gmail.com>
Date
Oct 4, 2022, 13:44 UTC
Message-ID
<87o7ur1wi9.fsf@gmail.com>
Hi all,

We're looking to create a tool that can duplicate a specific subtree elsewhere in the repository. (This is part of a rag-tag replacement for svn:external that will continue to work with our existing build infrastructure while we adjust everything to be organized better in the actual repository.) The basic idea is as follows:

1. At the repository root, there is a manifest that defines groups of
   paths that should be copies of one another.
2. Server hook logic will enforce that for each new commit, the paths in
   the manifest at that commit are TREESAME to each other. This
   guarantee is important for our build processes.
3. Client-side tooling will help produce this TREESAME-ness in the
   context of sparse-checkouts. Support for sparse-index may not be so
   large a concern as this entire approach is more of a stopgap measure.
It's this last step, the client-side tooling, that is proving tricky.
### Solution based on git-fast-import

A working solution using git-fast-import was recently submitted for review:

    $ cat | git fast-import
    feature done
    commit refs/heads/<current-branch>
    committer (...)
    data <<ENDDATA
    (...commit message...)
    ENDDATA
    from refs/heads/<current-branch>
    M 040000 TREEID1 PATH1
    M 040000 TREEID1 PATH2
    M 040000 TREEID1 PATH3
    M 040000 TREEID2 PATH1
    M 040000 TREEID2 PATH2
    M 040000 TREEID2 PATH3
    (...)
    done

but using fast-import for this purpose seems like an abuse. It's especially suboptimal because it creates a *new* commit that brings everything into sync, so the two commits (the one the developer makes and the one created by this tooling) must be squashed together.

### Something better?
This feels like a job for git-update-index. From the docs,
Show 10 quoted lines
> USING --INDEX-INFO
> ------------------
>
> `--index-info` is a more powerful mechanism that lets you feed
> multiple entry definitions from the standard input, and designed
> specifically for scripts.  It can take inputs of three formats:
>
>     . mode SP type SP sha1          TAB path
> +
> This format is to stuff `git ls-tree` output into the index.
but the following does not work:
    $ cat | git update-index --index-info
    040000 tree TREEID1	PATH1

(using the appropriate delimiters, of course). This command succeeds, but checking git-status (and confirming with other tools like `git ls-files -s`) reveal that this invocation did not have the desired effect:

Show 5 quoted lines
> (mode) (oid) (stage)	(path)
> (...)
> 100755 (oid1) 0       PATH1FILENAME
> 100755 (oid2) 0       PATH1FILENAME
> 100755 (oid3) 0       PATH1FILENAME

with `PATH1` simply prepended to each file in TREEID1. In contrast, the desired state is

> 100755 (oid1) 0       PATH1/FILENAME
> 100755 (oid2) 0       PATH1/FILENAME
> 100755 (oid3) 0       PATH1/FILENAME

I also tried appending a / at the end of PATH1 (this isn't ls-tree output, but it's 'reasonable'), but git-update-index simply ignores the line with the message

> Ignoring path PATH1/

Is there a better, recommended way to do this? Given the language in git-update-index.txt, is this a bug / functionality gap in update-index? The documentation reads as if I could

    $ git ls-tree <args> | git update-index --index-info
but it seems that is not the case.

Thanks, -Sean

-- Sean Allred

Next: Chris Torek
Message 1 of 4 in “Using git-update-index to add existing tree objects at other paths”
  1. Sean AllredOct 4, 2022
  2. Chris TorekOct 4, 2022
  3. Junio C HamanoOct 5, 2022
  4. Phillip WoodOct 4, 2022

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.