0

I am trying to use git checkout-index to 'export' files from a repository to another directory with source code as described in https://stackoverflow.com/a/160719/1068167

My git repository has the following structure:

./src/subproject/[files]
./src/subproject/subfolder1/[files]
./src/subproject/subfolder2/[files]
./src/subproject2/[files]

My first 'export' where I used the -a flag worked perfectly. All my files and folders were 'exported' to the /tmp/export/src/... as expected. This is the command I used:

git checkout-index -a -f --prefix=/tmp/export/src/

Now I am trying to update the export location with a subset of files that have changed since the last export. I do not want to export all files since I have deleted many files from other subfolders that should not be copied.

I am thinking something like this:

git checkout-index -f --prefix=/tmp/export/src/ -- ./src/subproject/*

This command copies the files in the 'subproject' folder but fails with a message the subfolders.

git checkout-index: src/subproject/subfolder1 is not in the cache

git checkout-index: src/subproject/subfolder2 is not in the cache

I was hoping that the following files and directories would be copied

/tmp/export/src/subproject/[files]
/tmp/export/src/subproject/subfolder1/[files]
/tmp/export/src/subproject/subfolder2/[files]

How can I export/checkout a given specified set of files and folders in my subproject so that all subfolders and their nested folders are copied as well?

span
  • 5,405
  • 9
  • 57
  • 115
  • Submodules are separate (and independent except for being controlled by the superproject) Git repositories. Each one has its own index. You'd have to run the `git checkout-index` in the submodule itself, with the correct paths based on the submodule's location relative to the superproject. – torek Nov 04 '19 at 09:34
  • I am not using "git submodules". I have rephrased the question. Sorry for the confusion. – span Nov 04 '19 at 11:12

1 Answers1

2

For git checkout-index to copy files from the index to some alternate location using --prefix=<string>, the files must be in the index. Yours are not.

To read a specific Git tree object into the index, use git read-tree. Note that by default, this wipes out the current index. You might wish to use a temporary index instead; to do that, export the name of a safe, but currently non-existent, file via the environment variable name GIT_INDEX_FILE. Git will create and use that file as the index while the variable is set. Unset it (or have a script that has set it exit) before, during, or after removing the temporary file to clean up.

I do not want to export all files since I have deleted many files from other subfolders that should not be copied.

I suspect you are going about all of this the wrong way:

  • git checkout-index can only copy out files that are in the index.

  • Normally, you fill the index by reading a whole commit into it. That is, while git read-tree technically reads any tree object, if you point git read-tree to a commit object, it reads the tree for that commit.

  • If you've deleted a bunch of files and committed, the new commit is a commit that does not (and never did) have the deleted files. So reading that commit into the index, then checking out the index, will not write those files to the target directory from --prefix.

  • But using git checkout-index like this will never remove files from the target directory either. If those files already exist in the target, and you don't want them to exist in the target, you will have to remove them yourself.

Hence, in general, to use git checkout-index like this to export a commit requires first filling the index from the commit, then exporting to what will be created as an empty directory (--prefix=/tmp/emptied/ after rm -rf /tmp/emptied). It's far easier to use git archive for this. This also avoids needing fancy footwork with a temporary index to avoid wrecking the index if you're doing something with it, such as doing any actual work with a work-tree.

torek
  • 448,244
  • 59
  • 642
  • 775