summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore6
-rw-r--r--Makefile67
-rwxr-xr-xgitolite-sync70
-rw-r--r--gitolite-sync.conf13
-rw-r--r--gitolite-sync.in97
-rw-r--r--gitolite-sync.service.in (renamed from gitolite-sync.service)4
-rw-r--r--gitolite-sync.timer.in (renamed from gitolite-sync.timer)0
-rw-r--r--man.commons.in14
8 files changed, 199 insertions, 72 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e68e611
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+gitolite-sync
+gitolite-sync.service
+gitolite-sync.timer
+man.commons
+*.common
+*.1
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..513dcbc
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,67 @@
+#
+# gitolite-sync - synchronize git repositories (designed for gitolite
+# managed ones)
+#
+# Copyright (c) 2013-2016 Erich Eckner <opensource at eckner dot net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+# USA.
+#
+
+DESTDIR =
+ETCDIR = /etc
+BINDIR = /usr/bin
+GITUSER = gitolite
+MANDIR = /usr/share/man
+
+VERSION = 0.0
+
+all: man.commons \
+ gitolite-sync gitolite-sync.1 \
+ gitolite-sync.service gitolite-sync.timer
+
+%: %.in
+ sed " \
+ s/#VERSION#/$(VERSION)/; \
+ s@#BINDIR#@$(BINDIR)@; \
+ s@#ETCDIR#@$(ETCDIR)@; \
+ s@#GITUSER#@$(GITUSER)@; \
+ s@#HELPTEXT#\(\s\+\)#@ --help \1display this help and exit\n --version\1display version and exit@; \
+ " $< > $@ && \
+ ( [[ "$@" = *.* ]] || chmod +x "$@" )
+
+%.1: % man.commons
+ grep -v "^$<(" man.commons | sed '/^\[SEE ALSO]$$/{n;:a;N;/\[/b;s/\n/, /;ta;}' > "$<.common" && \
+ help2man -o "$@" -N --include $<.common --no-discard-stderr "./$<"
+
+.PHONY: install dist clean
+
+install: all
+ install -D -m0755 -t $(DESTDIR)$(BINDIR) gitolite-sync
+ install -D -m0644 -t $(DESTDIR)$(LIBDIR)/systemd/system gitolite-sync.service gitolite-sync.timer
+ install -D -m0644 -t $(DESTDIR)$(MANDIR)/man1 gitolite-sync.1
+ install -D -m0644 -t $(DESTDIR)$(ETCDIR) gitolite-sync.conf
+
+clean:
+ git clean -x -d -f
+
+dist: clean
+ git status --porcelain 2> /dev/null | grep -q "\S" && (git add .; git commit -m"neue Version: $(VERSION)") || true
+ ! git tag -d v$(VERSION) 2> /dev/null
+ git tag v$(VERSION)
+ git push
+ git push --tags
+
+# End of file
diff --git a/gitolite-sync b/gitolite-sync
deleted file mode 100755
index f25ba4e..0000000
--- a/gitolite-sync
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/bin/bash
-
-home=$(
- getent passwd gitolite \
- | cut -d: -f6
-)
-
-if [ -z "${home}" ] || [ ! -d "${home}" ]; then
- >&2 echo 'cannot find user gitolite'
- exit 1
-fi
-
-find "${home}/repositories" \
- -type d \
- -name '*.git' \
- -printf '%p\n' \
- -prune \
-| while read -r path; do
- >&2 printf 'synchronizing "%s" ...\n' \
- "${path}"
- remotes=$(
- git -C "${path}" remote -v \
- | grep '[@.]eckner\.net:' \
- | awk '{print $1}' \
- | sort -u
- )
- if [ -z "${remotes}" ]; then
- >&2 printf 'Repository "%s" has no backup remotes.\n' \
- "${path}"
- continue
- fi
- for remote in ${remotes}; do
- git -C "${path}" fetch "${remote}" -p
- done
- branches=$(
- git -C "${path}" branch --all \
- | sed '
- s,^.\sremotes/[^/[:space:]]\+/,,
- t
- d
- '
- )
- if [ -n "$(git -C "${path}" tag -l)" ]; then
- has_tags=true
- else
- has_tags=false
- fi
- if [ -z "${branches}" ] && ! ${has_tags}; then
- >&2 printf 'Repository "%s" has no branches and no tags.\n' \
- "${path}"
- continue
- fi
- for remote in ${remotes}; do
- if ${has_tags}; then
- git -C "${path}" push "${remote}" --tags
- fi
- if [ -z "${branches}" ]; then
- continue
- fi
- for branch in ${branches}; do
- if ! git -C "${path}" branch \
- | sed 's/^.\s//' \
- | grep -qxF "${branch}"; then
- git -C "${path}" branch "${branch}" --track "${remote}/${branch}"
- fi
- git -C "${path}" pull --ff-only "${remote}" "${branch}" 2>/dev/null
- git -C "${path}" push "${remote}" "${branch}"
- done
- done
-done
diff --git a/gitolite-sync.conf b/gitolite-sync.conf
new file mode 100644
index 0000000..240ec0c
--- /dev/null
+++ b/gitolite-sync.conf
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+# this regex must match the to-be-synchronized remotes (or their url)
+remote_regex='[@.]eckner\.net:'
+
+# these directories contain the to-be-synchronized repositories
+repository_dirs=(
+ $(
+ getent passwd #GITUSER# \
+ | cut -d: -f6 \
+ | sed 's,$,/repositories,'
+ )
+)
diff --git a/gitolite-sync.in b/gitolite-sync.in
new file mode 100644
index 0000000..adc67bd
--- /dev/null
+++ b/gitolite-sync.in
@@ -0,0 +1,97 @@
+#!/bin/bash
+
+if [ $# -eq 1 ]; then
+ if [ "$1" == "--help" ]; then
+ >&2 echo \
+'Usage: gitolite-sync [options]
+Synchronize the configured git repositories.
+
+Options:
+#HELPTEXT# #'
+ exit
+ elif [ "$1" == "--version" ]; then
+ echo '#VERSION#'
+ exit
+ fi
+fi
+
+if [ $# -ne 0 ]; then
+ >&2 echo 'too many arguments'
+ exit 1
+fi
+
+. "#ETCDIR#/gitolite-sync.conf"
+
+if [ ${#repository_dirs[@]} -eq 0 ]; then
+ >&2 echo 'no repository_dirs defined'
+ exit 1
+fi
+
+for repository_dir in "${repository_dir[@]}"; do
+ if [ -z "${repository_dir}" ] || [ ! -d "${repository_dir}" ]; then
+ >&2 printf 'cannot find "%s"\n' \
+ "${repository_dir}"
+ exit 1
+ fi
+done
+
+for repository_dir in "${repository_dir[@]}"; do
+ find "${repository_dir}" \
+ -type d \
+ -name '*.git' \
+ -printf '%p\n' \
+ -prune \
+ | while read -r path; do
+ >&2 printf 'synchronizing "%s" ...\n' \
+ "${path}"
+ remotes=$(
+ git -C "${path}" remote -v \
+ | grep "${remote_regex}" \
+ | awk '{print $1}' \
+ | sort -u
+ )
+ if [ -z "${remotes}" ]; then
+ >&2 printf 'Repository "%s" has no backup remotes.\n' \
+ "${path}"
+ continue
+ fi
+ for remote in ${remotes}; do
+ git -C "${path}" fetch "${remote}" -p
+ done
+ branches=$(
+ git -C "${path}" branch --all \
+ | sed '
+ s,^.\sremotes/[^/[:space:]]\+/,,
+ t
+ d
+ '
+ )
+ if [ -n "$(git -C "${path}" tag -l)" ]; then
+ has_tags=true
+ else
+ has_tags=false
+ fi
+ if [ -z "${branches}" ] && ! ${has_tags}; then
+ >&2 printf 'Repository "%s" has no branches and no tags.\n' \
+ "${path}"
+ continue
+ fi
+ for remote in ${remotes}; do
+ if ${has_tags}; then
+ git -C "${path}" push "${remote}" --tags
+ fi
+ if [ -z "${branches}" ]; then
+ continue
+ fi
+ for branch in ${branches}; do
+ if ! git -C "${path}" branch \
+ | sed 's/^.\s//' \
+ | grep -qxF "${branch}"; then
+ git -C "${path}" branch "${branch}" --track "${remote}/${branch}"
+ fi
+ git -C "${path}" pull --ff-only "${remote}" "${branch}" 2>/dev/null
+ git -C "${path}" push "${remote}" "${branch}"
+ done
+ done
+ done
+done
diff --git a/gitolite-sync.service b/gitolite-sync.service.in
index f85eb43..32ca6cb 100644
--- a/gitolite-sync.service
+++ b/gitolite-sync.service.in
@@ -2,5 +2,5 @@
Description=synchronize gitolite repositories to and from backup location(s)
[Service]
-User=gitolite
-ExecStart=/usr/bin/gitolite-sync
+User=#GITUSER#
+ExecStart=#BINDIR#/gitolite-sync
diff --git a/gitolite-sync.timer b/gitolite-sync.timer.in
index 4a4e9bc..4a4e9bc 100644
--- a/gitolite-sync.timer
+++ b/gitolite-sync.timer.in
diff --git a/man.commons.in b/man.commons.in
new file mode 100644
index 0000000..c56a2f8
--- /dev/null
+++ b/man.commons.in
@@ -0,0 +1,14 @@
+[FILES]
+#ETCDIR#/gitolite-sync.conf
+[AUTHOR]
+Erich Eckner <opensource at eckner dot net>.
+[SEE ALSO]
+gitolite-conf(1)
+[CONFIG]
+The configfile \fB#ETCDIR#/gitolite.conf\fP is a bash script, which defines the following variables:
+.TP
+.B "remote_regex"
+regular expression for remotes that should be synchronized
+.TP
+.B "home_dirs"
+array of directories to be synchronized by \fBgitolite-sync\fP