#!/bin/sh -efu # # Copyright (C) 20011 Aleksey Avdeev # # Manage restored tags in the package repository. # # This file 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. # . gear-sh-functions PROG_VERSION="@VERSION@" tmpdir= cleanup_handler() { [ -z "$tmpdir" ] || rm -rf -- "$tmpdir" } print_version() { cat < Copyright (C) 20011 Aleksey Avdeev This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. EOF exit } show_help() { cat <\\t\\t) and exit; --no-type do not print types; --no-sha1 do not print sha1; --no-name do not print names; -f, --force modify existing tags and branches; -v, --verbose print a message for each action; -q, --quiet do not print a message for each action; -V, --version print program version and exit; -h, --help show this text and exit. Report bugs to http://bugzilla.altlinux.org/ EOF exit } get_tag_object() { sed -r -n ' /^[[:space:]]*$/q /^object[[:space:]]+[[:xdigit:]]+[[:space:]]*$/s/^object[[:space:]]+([[:xdigit:]]+)[[:space:]]*$/\1/p ' "$tag_dir/$1" } get_tag_type() { sed -r -n ' /^[[:space:]]*$/q /^type[[:space:]]+[a-z]+[[:space:]]*$/s/^type[[:space:]]+([a-z]+)[[:space:]]*$/\1/p ' "$tag_dir/$1" } get_tag_tag() { sed -r -n ' /^[[:space:]]*$/q /^tag[[:space:]]+[^[:space:]]+(.*[^[:space:]])?[[:space:]]*$/s/^tag[[:space:]]+([^[:space:]]+(.*[^[:space:]])?)[[:space:]]*$/\1/p ' "$tag_dir/$1" } check_tagname() { git tag | grep -q -m1 "^$1\$" || return 1 } check_tagtype() { [ "`get_tag_type "$1"`" = "tag" ] || return 1 } list_print() { local type= local sha1= local name= local format="%s" if [ -n "$type_print" ]; then type="$1" fi if [ -n "$sha1_print" ]; then sha1="$2" if [ -n "$type_print" ]; then format="$format\t%s" else format="$format%s" fi else format="$format%s" fi if [ -n "$name_print" ]; then name="$3" if [ -n "$type_print$sha1_print" ]; then format="$format\t%s\n" else format="$format%s\n" fi else format="$format%s\n" fi printf "$format" "$type" "$sha1" "$name" } list_print_tag() { list_print "tag" "$1" "$2" } list_print_branch() { list_print "branch" "$1" "$2" } list_print_tags() { if [ -r "$tag_dir/$1" ]; then local object="`get_tag_object "$1"`" if check_tagtype "$1"; then list_print_tags "$object" fi local tagname= if [ "$#" -gt "1" ] && [ -n "$2" ]; then tagname="$2" else tagname="`get_tag_tag "$1"`" fi list_print_tag "$1" "$tagname" else fatal "File $tag_dir/$1 is not readable!" fi } list_all() { # Check $tag_dir/list if [ ! -r "$tag_dir/list" ]; then fatal "File $tag_dir/list is not readable!" fi local sha1= local name= verbose "Read $tag_dir/list" while read -r sha1 name; do verbose "Processing of the tag or branch \"$name\" ($sha1)" if [ -r "$tag_dir/$sha1" ]; then verbose " \"$name\" this tag" if [ -n "$tags_processing" ]; then list_print_tags "$sha1" "$name" else verbose "Do not handle tags!" fi else verbose " \"$name\" this branch" if [ -n "$branches_processing" ]; then list_print_branch "$sha1" "$name" else verbose "Do not handle branches!" fi fi done <"$tag_dir/list" } restore_tag() { if [ -r "$tag_dir/$1" ]; then if ! git cat-file -e "$1"; then verbose " create tag $1" local object="`get_tag_object "$1"`" if ! git cat-file -e "$object"; then fatal "Object $object right for the tag $1 was not found!" fi git mktag < "$tag_dir/$1" fi local tagname= if [ "$#" -gt "1" ] && [ -n "$2" ]; then tagname="$2" else tagname="`get_tag_tag "$1"`" fi if check_tagname "$tagname"; then verbose " tag \"$tagname\" already exists!" if [ -z "$force" ]; then return fi fi verbose " create tag \"$tagname\"" git update-ref "refs/tags/$tagname" "$1" else fatal "File $tag_dir/$1 is not readable!" fi } TEMP=`getopt -n "$PROG" -o l,f,$getopt_common_opts -l no-branches,no-tags,list,no-type,no-sha1,no-name,force,$getopt_common_longopts -- "$@"` || show_usage eval set -- "$TEMP" tags_processing="yes" branches_processing="yes" list= type_print="yes" sha1_print="yes" name_print="yes" force= verify= verbose= while :; do case "$1" in --) shift; break ;; --no-tags) tags_processing= ;; --no-branches) branches_processing= ;; -l|--list) list="yes" ;; --no-type) list="yes" type_print= ;; --no-sha1) list="yes" sha1_print= ;; --no-name) list="yes" name_print= ;; -f|--force) force="-f" ;; -q|--quiet) verbose= ;; -v|--verbose) verbose=1 ;; -h|--help) show_help ;; -V|--version) print_version ;; *) fatal "Unrecognized option: $1" ;; esac shift done # Save git directory for future use. git_dir="$(git rev-parse --git-dir)" git_dir="$(readlink -ev -- "$git_dir")" # Change to toplevel directory. chdir_to_toplevel tmpdir="$(mktemp -dt "$PROG.XXXXXXXX")" workdir="$tmpdir/work" mkdir "$workdir" tmp_tag_dir="$tmpdir/tags" mkdir "$tmp_tag_dir" if [ -z "$tags_processing$branches_processing" ]; then verbose "Needless to handle!" exit 0 fi find_rules_in_cwd find_tags_in_cwd head_branch="`cat "$git_dir/HEAD" | sed -r 's@[[:space:]]*ref:[[:space:]]+(refs/heads/|)@@'`" head_commit="`git rev-parse "$head_branch"`" if [ -n "$list" ]; then if [ -n "$type_print$sha1_print$name_print" ]; then list_all else verbose "Nothing to print!" fi else type= sha1= name= head_newcommit= list_all | while read -r type sha1 name; do case "$type" in tag) verbose " \"$name\" this tag" restore_tag "$sha1" "$name" ;; branch) verbose " \"$name\" this branch" git cat-file -e "$sha1" || fatal "Commit $sha1 is not in the repositories!" if [ "$name" = "$head_branch" ]; then verbose " \"$name\" the same name as the current branch!" if [ -n "$force" ]; then head_newcommit="$sha1" fi continue fi if git branch | egrep -q -m1 "^\\*?[[:space:]]+$name\$"; then verbose " branch \"$name\" already exists!" if [ -z "$force" ]; then continue fi fi verbose " create branch \"$name\"" git branch $force "$name" "$sha1" || fatal "Can not create a branch \"$name\"!" ;; *) fatal "Unrecognized type: $type" ;; esac done if [ -n "$head_newcommit" ]; then verbose "Set current branch \"$head_branch\" to $head_newcommit" git reset --hard "$head_newcommit" fi fi