Skip to content

Commit

Permalink
Install sample hooks
Browse files Browse the repository at this point in the history
A template mechanism to populate newly initialized repository
with default set of files is introduced.  Use it to ship example
hooks that can be used for update and post update checks, as
Josef Weidendorfer suggests.

Signed-off-by: Junio C Hamano <junkio@cox.net>
  • Loading branch information
Junio C Hamano committed Aug 3, 2005
1 parent ee63914 commit 8d5afef
Show file tree
Hide file tree
Showing 6 changed files with 199 additions and 0 deletions.
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ CFLAGS+=$(COPTS) -Wall $(DEFINES)

prefix=$(HOME)
bindir=$(prefix)/bin
etcdir=$(prefix)/etc
etcgitdir=$(etcdir)/git-core
# dest=

CC?=gcc
Expand Down Expand Up @@ -144,6 +146,7 @@ endif
endif

CFLAGS += '-DSHA1_HEADER=$(SHA1_HEADER)'
CFLAGS += '-DDEFAULT_GIT_TEMPLATE_ENVIRONMENT="$(etcgitdir)/templates"'



Expand Down Expand Up @@ -196,6 +199,7 @@ check:
install: $(PROG) $(SCRIPTS)
$(INSTALL) -m755 -d $(dest)$(bindir)
$(INSTALL) $(PROG) $(SCRIPTS) $(dest)$(bindir)
$(MAKE) -C templates install

install-tools:
$(MAKE) -C tools install
Expand Down Expand Up @@ -236,4 +240,5 @@ clean:
rm -f git-core-*.tar.gz git-core.spec
$(MAKE) -C tools/ clean
$(MAKE) -C Documentation/ clean
$(MAKE) -C templates/ clean
$(MAKE) -C t/ clean
4 changes: 4 additions & 0 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ extern unsigned int active_nr, active_alloc, active_cache_changed;
#define DB_ENVIRONMENT "GIT_OBJECT_DIRECTORY"
#define INDEX_ENVIRONMENT "GIT_INDEX_FILE"
#define GRAFT_ENVIRONMENT "GIT_GRAFT_FILE"
#define TEMPLATE_DIR_ENVIRONMENT "GIT_TEMPLATE_DIRECTORY"
#ifndef DEFAULT_GIT_TEMPLATE_ENVIRONMENT
#define DEFAULT_GIT_TEMPLATE_ENVIRONMENT "/etc/git-core/templates"
#endif

extern char *get_object_directory(void);
extern char *get_refs_directory(void);
Expand Down
142 changes: 142 additions & 0 deletions init-db.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,147 @@ static void safe_create_dir(const char *dir)
}
}

static int copy_file(const char *dst, const char *src, int mode)
{
int fdi, fdo;

mode = (mode & 0111) ? 0777 : 0666;
if ((fdi = open(src, O_RDONLY)) < 0)
return fdi;
if ((fdo = open(dst, O_WRONLY | O_CREAT | O_EXCL, mode)) < 0) {
close(fdi);
return fdo;
}
while (1) {
char buf[BUFSIZ];
ssize_t leni, leno, ofs;
leni = read(fdi, buf, sizeof(buf));
if (leni < 0) {
error_return:
close(fdo);
close(fdi);
return -1;
}
if (!leni)
break;
ofs = 0;
do {
leno = write(fdo, buf+ofs, leni);
if (leno < 0)
goto error_return;
leni -= leno;
ofs += leno;
} while (0 < leni);
}
close(fdo);
close(fdi);
return 0;
}

static void copy_templates_1(char *path, int baselen,
char *template, int template_baselen,
DIR *dir)
{
struct dirent *de;

/* Note: if ".git/hooks" file exists in the repository being
* re-initialized, /etc/core-git/templates/hooks/update would
* cause git-init-db to fail here. I think this is sane but
* it means that the set of templates we ship by default, along
* with the way the namespace under .git/ is organized, should
* be really carefully chosen.
*/
safe_create_dir(path);
while ((de = readdir(dir)) != NULL) {
struct stat st_git, st_template;
int namelen;
int exists = 0;

if (de->d_name[0] == '.')
continue;
namelen = strlen(de->d_name);
if ((PATH_MAX <= baselen + namelen) ||
(PATH_MAX <= template_baselen + namelen))
die("insanely long template name %s", de->d_name);
memcpy(path + baselen, de->d_name, namelen+1);
memcpy(template + template_baselen, de->d_name, namelen+1);
if (lstat(path, &st_git)) {
if (errno != ENOENT)
die("cannot stat %s", path);
}
else
exists = 1;

if (lstat(template, &st_template))
die("cannot stat template %s", template);

if (S_ISDIR(st_template.st_mode)) {
DIR *subdir = opendir(template);
int baselen_sub = baselen + namelen;
int template_baselen_sub = template_baselen + namelen;
if (!subdir)
die("cannot opendir %s", template);
path[baselen_sub++] =
template[template_baselen_sub++] = '/';
path[baselen_sub] =
template[template_baselen_sub] = 0;
copy_templates_1(path, baselen_sub,
template, template_baselen_sub,
subdir);
closedir(subdir);
}
else if (exists)
continue;
else if (S_ISLNK(st_template.st_mode)) {
char lnk[256];
int len;
len = readlink(template, lnk, sizeof(lnk));
if (len < 0)
die("cannot readlink %s", template);
if (sizeof(lnk) <= len)
die("insanely long symlink %s", template);
lnk[len] = 0;
if (symlink(lnk, path))
die("cannot symlink %s %s", lnk, path);
}
else if (S_ISREG(st_template.st_mode)) {
if (copy_file(path, template, st_template.st_mode))
die("cannot copy %s to %s", template, path);
}
else
error("ignoring template %s", template);
}
}

static void copy_templates(const char *git_dir)
{
char path[PATH_MAX];
char template_path[PATH_MAX];
char *template_dir;
int len, template_len;
DIR *dir;

strcpy(path, git_dir);
len = strlen(path);
template_dir = gitenv(TEMPLATE_DIR_ENVIRONMENT);
if (!template_dir)
template_dir = DEFAULT_GIT_TEMPLATE_ENVIRONMENT;
strcpy(template_path, template_dir);
template_len = strlen(template_path);
if (template_path[template_len-1] != '/') {
template_path[template_len++] = '/';
template_path[template_len] = 0;
}

dir = opendir(template_path);
if (!dir)
return;
copy_templates_1(path, len,
template_path, template_len,
dir);
closedir(dir);
}

static void create_default_files(const char *git_dir)
{
unsigned len = strlen(git_dir);
Expand Down Expand Up @@ -48,6 +189,7 @@ static void create_default_files(const char *git_dir)
exit(1);
}
}
copy_templates(path);
}

/*
Expand Down
19 changes: 19 additions & 0 deletions templates/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# make

INSTALL=install
prefix=$(HOME)
etcdir=$(prefix)/etc
etcgitdir=$(etcdir)/git-core
templatedir=$(etcgitdir)/templates
# dest=

all:
clean:

install:
$(INSTALL) -d -m755 $(dest)$(templatedir)/hooks/
$(foreach s,$(wildcard hooks--*),\
$(INSTALL) -m644 $s \
$(dest)$(templatedir)/hooks/$(patsubst hooks--%,%,$s);)
$(INSTALL) -d -m755 $(dest)$(templatedir)/info
$(INSTALL) -d -m755 $(dest)$(templatedir)/branches
8 changes: 8 additions & 0 deletions templates/hooks--post-update
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh
#
# An example hook script to prepare a packed repository for use over
# dumb transports.
#
# To enable this hook, make this file executable by "chmod +x post-update".

exec git-update-server-info
21 changes: 21 additions & 0 deletions templates/hooks--update
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/sh
#
# An example hook script to mail out commit update information.
#
# To enable this hook:
# (1) change the recipient e-mail address
# (2) make this file executable by "chmod +x update".
#

recipient="commit-list@mydomain.xz"

if expr "$2" : '0*$' >/dev/null
then
echo "Created a new ref, with the following commits:"
git-rev-list --pretty "$2"
else
echo "New commits:"
git-rev-list --pretty "$3" "^$2"
fi |
mail -s "Changes to ref $1" "$recipient"
exit 0

0 comments on commit 8d5afef

Please sign in to comment.