Vallieres
Vallieres

Reputation: 879

Git clone only a subdirectory, at the root of the current directory

I have a few folders on my Git repo:

folder1/suba
folder2/subb
folder3/subc

And locally I have the public folder on my web server.

http://domain.com/ 

points to that folder

~/apps/appname/public

I would like to effectively do a git clone of the folder3/subc to the public folder on the server. Now I know about the sparse checkout, but that retains the folder hierarchy (like so ~/apps/appname/public/folder3/subc).

I do not want that hierarchy and would like to checkout the content of folder3/subc directly into the public folder.

Is that possible?

Upvotes: 5

Views: 2020

Answers (3)

VonC
VonC

Reputation: 1328562

If you use git write-tree from jthill's answer, make sure to use Git 2.41+.

With Git 2.41 (Q2 2023), "git write-tree"(man) learns to work better with sparse-index.

See commit 1a65b41 (03 Apr 2023) by Shuqi Liang (none).
(Merged by Junio C Hamano -- gitster -- in commit d47ee0a, 17 Apr 2023)

write-tree: integrate with sparse index

Signed-off-by: Shuqi Liang

Update 'git write-tree'(man) to allow using the sparse-index in memory without expanding to a full one.

The recursive algorithm for update_one() was already updated in 2de37c5 ("cache-tree: integrate with sparse directory entries", 2021-03-03, Git v2.32.0-rc0 -- merge listed in batch #13) to handle sparse directory entries in the index.
Hence we can just set the requires-full-index to false for "write-tree".

The p2000 tests demonstrate a ~96% execution time reduction for 'git write-tree' using a sparse index:

Test                                           before  after 
-----------------------------------------------------------------
2000.78: git write-tree (full-v3)              0.34    0.33 -2.9% 
2000.79: git write-tree (full-v4)              0.32    0.30 -6.3% 
2000.80: git write-tree (sparse-v3)            0.47    0.02 -95.8% 
2000.81: git write-tree (sparse-v4)            0.45    0.02 -95.6%

Upvotes: 0

jthill
jthill

Reputation: 60537

If ~/apps/appname/public is on a shared filesystem, and your webserver doesn't alter the checked-out files, you can maintain a dedicated index of its contents and just use git read-tree -um to update the filesystem from any commit you like:

( 
  export GIT_INDEX_FILE=/path/to/repo/.git/appname-public-manifest
  export GIT_WORK_TREE=~/apps/appname/public
  git read-tree -um `git write-tree` master:folder3/subc
)

The git write-tree writes a tree for git read-tree to inspect, and the read-tree applies the differences between what's there now and what's in the specified tree to the index and worktree.

If there's nothing in that directory already there's no need to initialize, otherwise

( 
  export GIT_INDEX_FILE=/path/to/repo/.git/appname-public-manifest
  export GIT_WORK_TREE=~/apps/appname/public
  git read-tree --empty   # start from nothing
  git add .               # index what's there now
)

will set up the manifest to match what's already there.

Upvotes: 3

forvaidya
forvaidya

Reputation: 3315

You can't clone a sub-directory. However you can create shallow clones. Such shallow clones are suitable only for deployment.

Meaning you can't Commit, Pull, Push and rebase using those clones. Shallow clones help you to reduce clone size foot print

Upvotes: -1

Related Questions