Git: Deploy only a directory from post-receive hook

deployment, git

Solution

I'll abbreviate the values supplied to `--work-tree` and `--git-dir` as `WT` and `REPO` respectively so that everything can fit without a horizontal scrollbar.

The general form should be:

#!/bin/sh
git --work-tree=WT --git-dir=REPO checkout -f -- paths

Suppose at the `WT` directory that's being deployed on the live server, you only want to checkout the `Build` folder in the repository. This becomes

#!/bin/sh
git --work-tree=WT --git-dir=REPO checkout -f -- Build

In general, you can replace the `paths` portion with one or more files in the git repository. These are specified as relative paths according to how they are placed in the repo. So if your git repo looks like this:

FolderOne
|- FolderTwo
|  |- FileOne
|- FolderThree

FolderFour
|- FileFive

And you want to checkout `FileOne` and everything `FolderFour`, you should do:

git --work-tree=WT --git-dir=REPO checkout -f -- FolderOne/FolderTwo/FileOne FolderFour

UPDATE:

It's been some time since I've dealt with Git hooks, but I think other than some details like their stdin and argv, you can put anything inside.

So for checking out everything in the `Build` folder but not the `Build` folder itself, you could do something like this in the post-receive hook:

git --work-tree=WT --git-dir=REPO checkout -f -- Build/
cd WT
cp -r Build/* .
rmdir Build

So we first checkout the `Build` directory into the `WT` directory. Then we `cd` into the `WT` directory, copy everything out from the `Build` directory using `cp -r Build/* .` . The `.` stands for the current directory, which is the `WT` directory we just `cd` into. Once that's done, we remove the now empty `Build` directory.

Hence, everything from the `Build` directory is now checked out into the `WT` directory, without the `Build` directory itself. Of course, you've got to replace `WT` and `REPO` by the actual paths to the work tree and git repository respectively.

Hope that helps

Problem

Having followed the instructions from this article I have a post-receive hook which currently reads: ``` #!/bin/sh git --work-tree=/home/user/example.com --git-dir=/home/user/example.com.git checkout -f ``` This is working well - all the files and directories are getting deployed. However I'd like to only deploy the files from the Build folder within example.com.git (I'm using Hammer by the way.) so not all the development files are available and viewable on the live server. Question: What do I alter/add to the above Git command in order to only checkout/deploy what's within the Build directory? Update: After the discussion in the comments I came to the following, which works in my case. ``` #!/bin/sh git --work-tree=/home/user/example.com --git-dir=/home/user/example.com.git checkout -f master -- Build/ cd /home/user/example.com cp -rRp Build/. . rm -rf Build ```

Original source