I'm using git to manage a grails project I have. I set up a git repository on a remote server and what I want to do is when I have code working locally, I want to commit it开发者_如何学Go and push to the remote server. I want the updated groovy file and gsp's to be put into the right spot on the remote server so that grails will pick up the changes for remote testing. Is this possible?
If you are pushing to a remote repo, where "it only seems to contain a large pack file, no actual source code" (as you detail in the comments), that should mean "bare repo", which is good for it allows you to push without any risk of differences between a working tree and the git data.
Then, as described in "Can I use git to keep a remote server up to date?", another (non-bare) repo and a post-update hook
on the bare repo side will get you where you want.
The OP TripWired adds:
Okay so what I did is:
- create the bare repo for checking in then
- I created another repo that was standard, basically i have
~/project.git
and~/project
. I cloned
project.git
intoproject
and inproject.git/hooks/post-update
I put:cd ../../project env -i git checkout . env -i git pull
I also made sure that post-update was executable.
When I run the hook from the command line it works fine, but it doesn't seem to work when I do a check in to the repo.
I agree with steps 1 and 2, but would then use this script, as in this question.
Check if it works with a git push
from your local repo to your bare repo.
#!/bin/sh
#
# This hook does two things:
#
# 1. update the "info" files that allow the list of references to be
# queries over dumb transports such as http
#
# 2. if this repository looks like it is a non-bare repository, and
# the checked-out branch is pushed to, then update the working copy.
# This makes "push" function somewhat similarly to darcs and bzr.
#
# To enable this hook, make this file executable by "chmod +x post-update".
git-update-server-info
is_bare=$(git-config --get --bool core.bare)
if [ -z "$is_bare" ]
then
# for compatibility's sake, guess
git_dir_full=$(cd $GIT_DIR; pwd)
case $git_dir_full in */.git) is_bare=false;; *) is_bare=true;; esac
fi
update_wc() {
ref=$1
echo "Push to checked out branch $ref" >&2
if [ ! -f $GIT_DIR/logs/HEAD ]
then
echo "E:push to non-bare repository requires a HEAD reflog" >&2
exit 1
fi
if (cd $GIT_WORK_TREE; git-diff-files -q --exit-code >/dev/null)
then
wc_dirty=0
else
echo "W:unstaged changes found in working copy" >&2
wc_dirty=1
desc="working copy"
fi
if git diff-index --cached HEAD@{1} >/dev/null
then
index_dirty=0
else
echo "W:uncommitted, staged changes found" >&2
index_dirty=1
if [ -n "$desc" ]
then
desc="$desc and index"
else
desc="index"
fi
fi
if [ "$wc_dirty" -ne 0 -o "$index_dirty" -ne 0 ]
then
new=$(git rev-parse HEAD)
echo "W:stashing dirty $desc - see git-stash(1)" >&2
( trap 'echo trapped $$; git symbolic-ref HEAD "'"$ref"'"' 2 3 13 15 ERR EXIT
git-update-ref --no-deref HEAD HEAD@{1}
cd $GIT_WORK_TREE
git stash save "dirty $desc before update to $new";
git-symbolic-ref HEAD "$ref"
)
fi
# eye candy - show the WC updates :)
echo "Updating working copy" >&2
(cd $GIT_WORK_TREE
git-diff-index -R --name-status HEAD >&2
git-reset --hard HEAD)
}
if [ "$is_bare" = "false" ]
then
active_branch=`git-symbolic-ref HEAD`
export GIT_DIR=$(cd $GIT_DIR; pwd)
GIT_WORK_TREE=${GIT_WORK_TREE-..}
for ref
do
if [ "$ref" = "$active_branch" ]
then
update_wc $ref
fi
done
fi
With respect to your comment on Alos' post: the remote is what's called a bare repository - it contains the entire repository except for a checked-out copy of the contents. The idea is that for central repositories that you just push and pull from, there's no need to have the files.
That said, there are a lot of approaches to do what you're trying to do.
You could create another remote non-bare clone, and use it to pull from the bare one and do the testing. This is probably easiest.
You could directly check out files (using
git read-tree
andgit checkout-index
) from the bare repo (an example comes to mind, git.git's install-doc-quick.sh).You could even use a non-bare remote, but keep in mind that pushing into a non-bare repo is dangerous since the working tree doesn't get updated. Depending on your version of git, there are various safeguards you'll have to override, and you'll have fix the work tree after pushing (
git reset --hard
probably).
No matter which approach you take, assuming you want to trigger your tests after every push, you can use the post-receive or post-update hook to do so. (You could have it check the length of time since the last test if you want to avoid repeated tests from a burst of pushes)
If you are on linux you could set up a cron job to copy the files for you, or if you are on windows you could create a scheduled task with a small bat or vbs script to copy the file to the remote server. If you need help on using Git here is the users manual. If that is not what your looking for we can work on something that might work better or if you need help with the scripts let me know.
精彩评论