17

Unlike Subversion, git has no cp command. For files, this is not a problem: if I want to copy a file a to b, I can just do:

cp -a a b
git add b

However, say I want to copy a directory d to give it another name e. I can still do the same thing. However, d may contain files that are not tracked by git, e.g., compiled binaries, etc. In this context, I do not want to do the above, because I do not want git to track these additional files.

With Subversion, I can do svn cp, and it will only copy and add the files that are tracked by Subversion. How can I do this with git?

a3nm
  • 1,335

5 Answers5

5

You can use git clone:

$ git clone /path/to/project /target/path

Then remove the .git file

$ rm -R /target/path/.git
3
  1. Find the tree hash of "d" (git ls-tree HEAD d)
  2. git read-tree -u --prefix=e tree-hash

Done!

git read-tree lets you replace your index, or (as in this case) a subtree of it, with any tree object that you know the hash of. The -u checks out the subtree from the index afterwards (as if you had done git checkout -- e). For more information about tree objects and the index, please see the Pro Git book.

user981942
  • 41
  • 3
1

The right solution is simply to make sure that all untracked files are ignored in .gitignore.

In this case, when you copy the directory with cp -Ra d e and run git add e on the copy, git will be smart enough to avoid adding the files that it ignores.

a3nm
  • 1,335
1

An example command flow for what the OP wants to do in windows 10 is as follows

git archive -o d.zip HEAD:d
move d d_original
tar -x -f d.zip
move d e
move d_original d

In the commands above

  1. we use git archive (docs) to create a zip of the folder d as it is committed in the git tree
  2. rename d to d_original as we will extract the previously zipped d folder and we do not want it to overwrite our current d folder
  3. extract the zipped archive
  4. rename the extracted d folder to e
  5. rename our d_original back to d

The usage of git above above creates a zip of the current committed state of subfolder of the active branch, because we use HEAD. A specific subfolder from a specific branch can be zipped using the following command

git archive -o subfolder.zip BRANCH_NAME path/to/subfolder
0

cd into the directory d and do

$ git checkout-index --prefix=e/ -- *

to find everything tracked by git in d copied to e (e is relative to the repo root).

Ramen
  • 101