Buju Buju - 1 month ago 8
Git Question

Is it possible to use git-clean in post-receive hook for bare repo?

I have a bare git repository set up on a wordpress hosting service and have followed some instructions to set up a post-receive hook (pagely git setup) As I understand it the work-tree is placed in a different directory referred to as the DEPLOYDIR.

Now, what I am trying to achieve is when a push request is received it will perform a git -clean on a few directories. If anyone is familiar with wordpress, our git has


  • file1

  • file2

  • wp-content


    • mu-plugins

    • plugins

    • themes




I would like to be able to clean mu-plugins, plugins, and themes and remove any thing that was added manually except for what is in our .gitignore.

I tried this variation of the post-receive linked above:

#!/bin/bash
#
## store the arguments given to the script
read oldrev newrev refname

## Where to store the log information about the updates
LOGFILE=./post-receive.log
# The deployed directory (the running site)
DEPLOYDIR=/data/s12345/q1234/r4564

## Record the fact that the push has been received
echo -e "Received Push Request at $( date +%F )" >> $LOGFILE
echo " - Old SHA: $oldrev New SHA: $newrev Branch Name: $refname" >> $LOGFILE

## Update the deployed copy
echo "Starting Deploy" >> $LOGFILE

echo " - Starting code update"
GIT_WORK_TREE="$DEPLOYDIR" git checkout wpqa -f
GIT_WORK_TREE="$DEPLOYDIR/wp-content/plugins" git clean -fd
GIT_WORK_TREE="$DEPLOYDIR/wp-content/themes" git clean -fd
GIT_WORK_TREE="$DEPLOYDIR/wp-content/mu-plugins" git clean -fd
echo " - Finished code update"
echo "Finished Deploy" >> $LOGFILE


After I made a push, everything was removed!

Pushing to ssh://username@helloworld.vendor.com:/data/git/mydirectory.git

remote: - Starting code update

remote: Switched to branch 'qa'

remote: Removing stuff_that_is_in_the_repo/

remote: Removing stuff_in_your_gitignore/

...etc.

Any suggestions for how to refer to the specific paths of the work tree?

Answer

As described in the git clean documentation, you can simply add the set of <path>s to the end of the command (prefixed with -- if any of the paths resemble options; in your case they do not so you will be OK without the -- but it's a good habit to get into). Hence:

GIT_WORK_TREE="$DEPLOYDIR" git checkout wpqa -f
GIT_WORK_TREE="$DEPLOYDIR" git clean -fd -- \
    wp-content/plugins wp-content/themes wp-content/mu-plugins

(I broke up the last line for display purposes; you can do the same, or just do it as one big line without the backslash.)

Note that git clean normally has no function on a bare repository, since a bare repository has no work-tree and git clean removes files from the work-tree. When you use the git --work-tree=... command [ options ] code path or the $GIT_WORK_TREE environment variable, however, you are supplying a work-tree, which overrides the "bare-ness". The problem with the method you tried is that you are supplying three different work-trees, none of which is the same as the work-tree you supplied for the checkout step.