问题
I am writing a git hook which checks if a new branch is created, and if so then add some predefined files to the repo for that new branch(Some config files). However because the branch is actually in the process of being created, my logic fails.
Currently I am doing this in a post-receive
hook, which looks something like this:
#!/bin/sh
read oldrev newrev refname
branch=$(git rev-parse --symbolic --abbrev-ref $refname)
echo "branch is $branch"
echo "oldrev is $oldrev and newrev is $newrev"
# if $oldrev is 0000...0000, it's a new branch
# also check if the branch is of the format "feature_<name>"
zero="0000000000000000000000000000000000000000"
if [ "$oldrev" = "$zero" ] && [[ $branch =~ feature_.+ ]]; then
#create a temp repo
temp_repo=`mktemp -d /tmp/repo.XXXXX`
cd $temp_repo
git clone $git_url
#here i create the config file needed, called file_name
git checkout "$branch"
git add "$file_name"
git commit -m "Added config file"
git push origin $branch
fi
This works for an existing branch, however for a newly created branch it gives an error fatal: Not a git repository: '.'
.
I am not sure in which hook I should use this logic, as I don't really know much about git
. Any idea how I can go about this?
Thanks
回答1:
If you're in a hook and want to run "normal" git commands, you will need to unset the GIT_DIR
environment variable (inside a hook it's set to .
).
That said, this does not seem to me to be the right approach. It should work but it seems a little surprising: if I git push origin abc:feature_def
I'll have to re-fetch and merge from origin to pick up this newly-committed $file_name
file. Would it not make more sense to require that I include that file myself, so that it's already there in the commit on branch feature_def
?
If so, a pre-receive or update hook would be the place to do the checking. A simplified example (untested):
#! /bin/sh
# update hook - check if new branch is named
# feature_*, and if so, require config file
refname=$1
oldrev=$2
newrev=$3
# BEGIN BOILERPLATE
NULL_SHA1=0000000000000000000000000000000000000000
# what kind of ref is it? also, get short name for branch-or-tag
case $refname in
refs/heads/*) reftype=branch; shortname=${refname#refs/heads/};;
refs/tags/*) reftype=tag; shortname=${refname#refs/tags/};;
*) reftype=other;;
esac
# what's happening to the ref?
# note: if update, there are potentially two different objtypes,
# but we only get the new one here
case $oldrev,$newrev in
$NULL_SHA1,*) action=create; objtype=$(git cat-file -t $newrev);;
*,$NULL_SHA1) action=delete; objtype=$(git cat-file -t $oldrev);;
*,*) action=update; objtype=$(git cat-file -t $newrev);;
esac
# END BOILERPLATE
# code to check a feature branch. Top level file named xyzzy.conf must exist.
check_feature_branch()
{
if ! git show $refname:xyzzy.conf >/dev/null 2>&1; then
echo "new branch $branch does not contain xyzzy.conf at top level" >&2
exit 1
fi
}
# check whether we're creating a branch named feature_*
case $action,$reftype,$shortname in
create,branch,feature_*) check_feature_branch;;
*) ;;
esac
# if we got here it must be OK
exit 0
来源:https://stackoverflow.com/questions/18323175/git-hook-add-a-new-file-to-repo-if-a-new-branch-is-created