git-repo

Tools for sharing git bare repositories
git clone git://git.meso-star.fr/git-repo.git
Log | Files | Refs | README | LICENSE

commit 42c7d9f51d552a6b9c25d22940de0fb16def587a
parent 2af6fff5d5b5fc48f62848a7d99d9561632e73a7
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Tue, 10 Jun 2025 21:49:34 +0200

git-publish: unpublish repositories

Add the -d option to unpublish repositories, i.e. to delete the data
that makes them public.

Diffstat:
Mgit-publish | 129+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
Mgit-publish.1 | 12+++++++++---
2 files changed, 112 insertions(+), 29 deletions(-)

diff --git a/git-publish b/git-publish @@ -41,7 +41,7 @@ die() synopsis() { >&2 printf \ -'usage: %s [-f] [-g dir_git] [-u base_url] [-w dir_www] repository ...\n' \ +'usage: %s [-df] [-g dir_git] [-u base_url] [-w dir_www] repository ...\n' \ "${0##*/}" } @@ -122,12 +122,11 @@ publish_repo() cd "${OLDPWD}" } +# Returns 0 if the repository has no receive hook or if it is the one +# configured by git-publish, and >0 otherwise. # Inputs: -# - base_url: base URL under which the git HTML repository is exposed -# - dir_git: directory where to publish the git repository -# - dir_www: directory where to publish the git repository's HTML pages -# - repo: git bare repository -setup_post_receive_hook() +# - 1: repository +check_post_receive_hook() { hook="${GIT_PUBLISH_RESOURCES_PATH}/post-receive.in" @@ -135,15 +134,28 @@ setup_post_receive_hook() digest="$(cksum "${hook}" | cut -d' ' -f1)" header='# git-publish '"${digest}" - if [ -e "${repo}/hooks/post-receive" ]; then - # Don't overwrite the repository's already configured post-receive - # hook if it hasn't been configured by git-publish. - header2="$(sed -n '2p' "${repo}/hooks/post-receive")" + if [ -e "$1/hooks/post-receive" ]; then + header2="$(sed -n '2p' "$1/hooks/post-receive")" if [ ! "${header}" = "${header2}" ]; then - >&2 printf 'another post-receive hook already exist\n' return 1 fi fi +} + +# Inputs: +# - base_url: base URL under which the git HTML repository is exposed +# - dir_git: directory where to publish the git repository +# - dir_www: directory where to publish the git repository's HTML pages +# - repo: git bare repository +setup_post_receive_hook() +{ + # shellcheck disable=SC2310 + if ! check_post_receive_hook "${repo}"; then + # Don't overwrite the repository's already configured post-receive + # hook if it hasn't been configured by git-publish. + >&2 printf 'another post-receive hook already exist\n' + return 1 + fi sed "2i ${header}" "${hook}" \ | sed -e "s#@DIR_GIT@#${dir_git}#g" \ @@ -188,13 +200,65 @@ make_index() repo_list=$(find "${dir_git}" -path "${dir_git}/*.git" -prune | sort \ | join - "${tmpfile}" | tr '\n' ' ') - # Generate the index - # shellcheck disable=SC2086 - stagit-index ${repo_list} > "${dir_www}/index.html" + if [ -z "${repo_list}" ]; then + # No repo to index. Delete index file if any + rm -f "${dir_www}/index.html" + else + # Generate the index + # shellcheck disable=SC2086 + stagit-index ${repo_list} > "${dir_www}/index.html" + fi rm -f "${tmpfile}" } + +# Inputs: +# - @: repository list +# - base_url: base URL under which the git HTML repository is exposed +# - dir_git: directory where to publish the git repository +# - dir_www: directory where to publish the git repository's HTML pages +# - force: force generation of HTML pages from scratch +publish() # list of repositories +{ + printf '%s\n' "$@" | while read -r repo; do + printf '%s: ' "${repo}" + check_repo + publish_repo + setup_post_receive_hook + printf 'done\n' + done +} + +# Inputs: +# - @ : repository list +# - base_url: base URL under which the git HTML repositories are exposed +# - dir_git: directory where to publish the git repositories +# - dir_www: directory where to publish the git repositories' HTML pages +# - force: force generation of HTML pages from scratch +unpublish() +{ + printf '%s\n' "$@" | while read -r repo; do + printf '%s: ' "${repo}" + + check_repo + + repo_name=$(basename "${repo}" ".git") + repo_www="${dir_www}/${repo_name}" + repo_git="${dir_git}/${repo_name}.git" + + rm -rf "${repo_www}" # Remove HTML pages + rm -f "${repo_git}" # Remove link in the publicly exposed directory + + # shellcheck disable=SC2310 + if check_post_receive_hook "${repo}"; then + rm -f "${repo}/hooks/post-receive" + fi + + printf 'done\n' + done +} + ######################################################################## # The script ######################################################################## @@ -202,11 +266,13 @@ base_url="${GIT_PUBLISH_BASE_URL:-}" dir_git="${GIT_PUBLISH_DIR_GIT:-/srv/git}" dir_www="${GIT_PUBLISH_DIR_WWW:-/srv/www/git}" force=0 # Force HTML generation +delete=0 # Delete publication # Parse input arguments OPTIND=1 -while getopts ":fg:u:w:" opt; do +while getopts ":dfg:u:w:" opt; do case "${opt}" in + d) delete=1 ;; f) force=1 ;; u) base_url="${OPTARG}" ;; g) dir_git="${OPTARG}" ;; # git directory @@ -217,24 +283,35 @@ done # Check mandatory options [ "${OPTIND}" -le $# ] || { synopsis; die; } -[ -n "${base_url}" ] || { >&2 printf 'Base url is missing\n'; die; } -[ -n "${dir_git}" ] || { >&2 printf 'git directory is missing\n'; die; } -[ -n "${dir_www}" ] || { >&2 printf 'WWW directory is missing\n'; die; } + +if [ -z "${dir_git}" ]; then + >&2 printf 'git directory is missing\n' + die +fi +if [ -z "${dir_www}" ]; then + >&2 printf 'WWW directory is missing\n' + die +fi +if [ -z "${base_url}" ] && [ "${delete}" -eq 0 ]; then + >&2 printf 'Base url is missing\n' + die +fi check_directory "${dir_git}" check_directory "${dir_www}" -check_resources "${dir_www}" + +if [ ! "${delete}" -eq 0 ]; then + check_resources "${dir_www}" +fi # Skip parsed arguments shift $((OPTIND - 1)) -printf '%s\n' "$@" | while read -r repo; do - printf '%s: ' "${repo}" - check_repo - publish_repo - setup_post_receive_hook - printf 'done\n' -done +if [ "${delete}" -eq 0 ]; then + publish "$@" +else + unpublish "$@" +fi # [Re]generate index of publicly exposed repositories make_index diff --git a/git-publish.1 b/git-publish.1 @@ -12,7 +12,7 @@ .\" .\" You should have received a copy of the GNU General Public License .\" along with this program. If not, see <http://www.gnu.org/licenses/>. -.Dd May 30, 2025 +.Dd June 10, 2025 .Dt GIT-PUBLISH 1 .Os .\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" @@ -22,7 +22,7 @@ .\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .Sh SYNOPSIS .Nm -.Op Fl f +.Op Fl df .Op Fl g Ar dir_git .Op Fl u Ar base_url .Op Fl w Ar dir_www @@ -46,6 +46,11 @@ published repositories to update HTML pages on new commits .Pp The options are as follows: .Bl -tag -width Ds +.It Fl c +Unpublish repositories: their link in the publicly exposed directory is +removed, as are their HTML pages and the post-receive hook that updates +them. +In other words, the publication process is cancelled. .It Fl f Force HTML generation from scratch. Enabling this option ensures that HTML pages take into account any @@ -95,7 +100,8 @@ The default is Base URL to make links in the ATOM feed absolute. It has no default value and must be explicitly defined if the .Fl u -option is not used. +option is not used, unless publications are to be deleted +.Pq option Fl c . .It Ev GIT_PUBLISH_DIR_WWW Directory where public repository HTML pages are stored. The default is