Reputation: 349
I'm working on a locale repository $HOME/some_git_repo
Now, i must do git checkout
on the server side, everytime i need to push anything updated. (i can handle that).
The problem is that isn't synchronizing anything in the /var/www/some_git_repo
, on the server side (remote).
That means the hooks/post_receive
script isn't doing their work
scope:
# post-receive -- script
git --work-tree='/var/www/some_git_repo' --git-dir='/var/repo/some_git_repo.git'
Upvotes: 0
Views: 76
Reputation: 349
Well, this response is not the preferible solution, but it resolve the problem, by updating the working-tree with a simple executable script:
rsync -arv --exclude=something_tobe_excluded \
--progress repo_source-dir working_tree
Every file/directory_path, must be specified as a single argument. (on the exclude
variable).
Upvotes: 0
Reputation: 489628
#!
line at the topI assume your post-receive script is in fact just the single line:
git --work-tree=/var/www/some_git_repo --git-dir=/var/repo/some_git_repo.git checkout -f
(I note that this, from your comment, is slightly different from what was in your original posting, having checkout -f
at the end of the line; I've also removed some unnecessary quote marks, one of which was missing in the comment version).
Your OS also appears to be Linux or Solaris or some Unix-like variant, based on the permissions you describe in another comment:
$ ls -l hooks/post-receive
-rwxr-xr-x 1 root root 93 Oct 31 14:08
The script is set to be executable, which is necessary, but is not sufficient: it needs to be marked executable (and is), but it also needs to be actually executable (and is not). That is, the underlying operating system must recognize this as a program that can be run without assistance.
Command-line interpreters (aka shells) like /bin/sh
and /bin/bash
use different rules than the underlying OS. If a file is marked executable, but the OS is unable to run it on its own, these command-line interpreters apply a fallback. They will treat the script as a shell script, and run it themselves. They will, for instance, tell the OS to run /bin/sh
, with the script as an argument to /bin/sh
. Git does not do this: it relies on the program being directly executable by the OS.
(Which shell is the fall-back interpreter? That's up to the shell you are running, since it's that very shell doing the fall-back.)
Fortunately, all modern Unix-like OSes provide a way to allow the OS to run the script directly. Simply write the script using at least two lines (more are of course permitted) with the first line having the form:
#! /bin/sh
or:
#! /bin/bash
or:
#! /usr/local/bin/bash
or wherever the appropriate command-line-interpreter itself lives. (You can run which sh
or type sh
to find out where the sh
interpreter lives, or which bash
or type bash
to find out where the bash
interpreter lives, and so on. For instance, on one of my machines I get:
$ which sh
/bin/sh
$ type sh
sh is /bin/sh
$ which bash
/usr/local/bin/bash
$ type bash
bash is /usr/local/bin/bash
while another gives me:
sh-3.2$ which sh
/bin/sh
sh-3.2$ type sh
sh is /bin/sh
sh-3.2$ which bash
/bin/bash
sh-3.2$ type bash
bash is /bin/bash
which shows that not every interpreter winds up in the same location on every machine.)
This first line makes the program directly executable by the OS: the OS locates the appropriate interpreter and runs that interpreter, passing the name of the script as an argument (just as the shells do themselves).
Note that this means you can use any program as the interpreter. An awk script can begin with:
#! /usr/bin/awk
A Python script can begin with:
#! /usr/bin/python
You can run Ruby scripts this way as well. You can also solve the problem that the interpreters live in different locations on different machines by using /usr/bin/env
, which tends not to move around (so that it's always in /usr/bin
) but also applies the PATH
environment variable:
#! /usr/bin/env python
This locates the Python interpreter, whether it's /usr/bin/python or /usr/local/bin/python, automatically through $PATH
. (Of course it's critical that $PATH
be set, but it nearly always is.)
If you have ever wondered why scripts have these #!
lines at the top, now you know. But they can do more than just make sh
scripts directly executable.
This is a self-printing script:
#! /bin/cat
I print myself!
The OS runs this by invoking /bin/cat
on the name of the script. The cat
command prints the contents of the script to standard output, and exits. The one minor annoyance is that the #!
line itself gets printed, so we fix this using /bin/sed
:
#! /bin/sed 1d
I print myself too,
and I elide my first line.
The OS passes the 1d
as an argument before the name of the script. Since /bin/sed
treats its first argument as an editing command, and the second argument as the input file, this deletes the first line before copying to the output stream, then prints the remaining lines (sed
's default action is to print a line).
This is a self-removing script:
#! /bin/rm -f
It has no function other than being entertaining. You can run it once, and then it's gone.
Some OSes allow multiple arguments after the interpreter, while others allow only one argument, effectively quoting remaining white space. You can tell which kind of OS you have by using a self-"awk"-ing script that works if and only if the entire command is one argv
element:
#! /bin/awk NR > 1 { print }
only one argument is passed
When the OS invokes /bin/awk
, it either does this as the shell equivalent of:
/bin/awk 'NR > 1 { print }' /path/to/script
which prints all but the first line, or it runs it as the shell equivalent of:
/bin/awk NR '>' 1 { print } /path/to/script
which causes a complaint from awk:
awk: can't open file >
source line number 1
Upvotes: 1