summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: ee63914)
raw | patch | inline | side by side (parent: ee63914)
author | Junio C Hamano <junkio@cox.net> | |
Tue, 2 Aug 2005 23:45:21 +0000 (16:45 -0700) | ||
committer | Junio C Hamano <junkio@cox.net> | |
Wed, 3 Aug 2005 23:27:38 +0000 (16:27 -0700) |
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>
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>
Makefile | patch | blob | history | |
cache.h | patch | blob | history | |
init-db.c | patch | blob | history | |
templates/Makefile | [new file with mode: 0644] | patch | blob |
templates/hooks--post-update | [new file with mode: 0644] | patch | blob |
templates/hooks--update | [new file with mode: 0644] | patch | blob |
diff --git a/Makefile b/Makefile
index 4622e039c0e87f0cf3957209ea0c7d7d6b9be2a1..c0aaa62b6ab510b677e0b719d9d553b9bf10b7b3 100644 (file)
--- a/Makefile
+++ b/Makefile
prefix=$(HOME)
bindir=$(prefix)/bin
+etcdir=$(prefix)/etc
+etcgitdir=$(etcdir)/git-core
# dest=
CC?=gcc
endif
CFLAGS += '-DSHA1_HEADER=$(SHA1_HEADER)'
+CFLAGS += '-DDEFAULT_GIT_TEMPLATE_ENVIRONMENT="$(etcgitdir)/templates"'
install: $(PROG) $(SCRIPTS)
$(INSTALL) -m755 -d $(dest)$(bindir)
$(INSTALL) $(PROG) $(SCRIPTS) $(dest)$(bindir)
+ $(MAKE) -C templates install
install-tools:
$(MAKE) -C tools install
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
index 1b49f0f4c3c5bef6e9fe6dcf68b117880c1a956a..10243f0b8ce5ff658e129bbec8085b5f0fae1125 100644 (file)
--- a/cache.h
+++ b/cache.h
#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);
diff --git a/init-db.c b/init-db.c
index c78c4951144e04d97773a872b0663a405097874c..fcb55f6e77f81f03c09f956ea2a63323a19c6217 100644 (file)
--- a/init-db.c
+++ b/init-db.c
}
}
+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);
exit(1);
}
}
+ copy_templates(path);
}
/*
diff --git a/templates/Makefile b/templates/Makefile
--- /dev/null
+++ b/templates/Makefile
@@ -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
diff --git a/templates/hooks--post-update b/templates/hooks--post-update
--- /dev/null
@@ -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
diff --git a/templates/hooks--update b/templates/hooks--update
--- /dev/null
+++ b/templates/hooks--update
@@ -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