Web lists-archives.com

Re: Modifying a bare repo directly

On Mon, Apr 10, 2017 at 12:33:18PM +0200, Ævar Arnfjörð Bjarmason wrote:

> On Mon, Apr 10, 2017 at 12:09 PM, Julian Goacher
> <julian.goacher@xxxxxxxxx> wrote:
> > Hi -
> >
> > Is it possible to modify a bare repo directly? e.g. is it possible to
> > insert a file into a bare repo without first cloning a non-bare copy?
> > I'm thinking along the lines of a command or sequence of commands that
> > modifies the file index and then copies the file blob into /objects,
> > but in a situation where the new file exists separately from the
> > target repo.
> Yes you use the plumbing commands (see "man git", search for plumbing), e.g.:
> git init --bare mybare.git
> cd mybare.git
> echo hello | git hash-object --stdin -w >obj
> $ printf "100644 blob $(cat obj)\thello.txt\n" | git mktree
> aaa96ced2d9a1c8e72c56b253a0e2fe78393feb7
> $ git commit-tree -m "1st commit" aaa96ced2d9a1c8e72c56b253a0e2fe78393feb7
> 318448647ab7a2b1f78c87cb8a05ac0cf172fbb8

This is definitely the right track, but if you're going to be modifying
an existing tree (and not just creating a new one), I'd suggest using
using a temporary index:

  export GIT_INDEX_FILE=my-index
  parent=$(git rev-parse HEAD)
  git read-tree $parent
  obj=$(echo hello | git hash-object --stdin -w)
  git update-index --add --cacheinfo 100644,$obj,hello.txt
  [...and other index changes if you want...]
  tree=$(git write-tree)
  commit=$(git commit-tree -p $parent $tree)
  git update-ref HEAD $commit $parent

That's a bit simpler because it handles modifications to existing trees
(rather than overwriting), and it handles changes to nested subtrees (to
edit "deep/subdir/hello.txt" using mktree, you have to issue three
separate mktree commands).