tg.sh: setup_hook even more carefully
[topgit/pro.git] / tg-delete.sh
blobfc60390cb3629a5a3a33c0ea6b5670eb7aa323c3
1 #!/bin/sh
2 # TopGit - A different patch queue manager
3 # Copyright (C) 2008 Petr Baudis <pasky@suse.cz>
4 # Copyright (C) 2017 Kyle J. McKay <mackyle@gmail.com>
5 # All rights reserved
6 # License GPLv2
8 force= # Whether to delete non-empty branch, or branch where only the base is left.
9 stash= # tgstash refs before changes
10 name=
12 if [ "$(git config --get --bool topgit.autostash 2>/dev/null)" != "false" ]; then
13 # topgit.autostash is true (or unset)
14 stash=1
17 ## Parse options
19 while [ -n "$1" ]; do
20 arg="$1"; shift
21 case "$arg" in
22 -f|--force)
23 force=$(( $force +1 ));;
24 --stash)
25 stash=1;;
26 --no-stash)
27 stash=;;
28 -*)
29 echo "Usage: ${tgname:-tg} [...] delete [-f] <name>" >&2
30 exit 1;;
32 [ -z "$name" ] || die "name already specified ($name)"
33 name="$arg";;
34 esac
35 done
38 ## Sanity checks
40 [ -n "$name" ] || die "no branch name specified"
41 branchrev="$(git rev-parse --verify "refs/heads/$name^0" -- 2>/dev/null)" ||
42 if [ -n "$force" ]; then
43 info "invalid branch name: $name; assuming it has been deleted already"
44 else
45 die "invalid branch name: $name"
47 baserev="$(git rev-parse --verify "refs/$topbases/$name^0" -- 2>/dev/null)" ||
48 die "not a TopGit topic branch: $name"
49 ! headsym="$(git symbolic-ref -q HEAD)" || [ "$headsym" != "refs/heads/$name" ] || {
50 [ -n "$force" ] && [ "$force" -ge 2 ] || die "cannot delete your current branch"
51 warn "detaching HEAD to delete current branch"
52 git update-ref -m "tgdelete: detach HEAD to delete $name" --no-deref HEAD "$branchrev"
53 git --no-pager log -n 1 --format=format:'HEAD is now at %h... %s' HEAD
56 [ -z "$force" ] && { branch_empty "$name" || die "branch is non-empty: $name"; }
58 # Quick'n'dirty check whether branch is required
59 [ -z "$force" ] && { tg summary --tgish-only --deps | cut -d ' ' -f2- | tr ' ' '\n' | grep -Fxq -- "$name" &&
60 die "some branch depends on $name"; }
62 ensure_ident_available
64 # always auto stash even if it's just to the anonymous stash TG_STASH
66 stashmsg="tgdelete: autostash before delete branch $name"
67 if [ -n "$stash" ]; then
68 tg tag -q -q -m "$stashmsg" --stash $name &&
69 stashhash="$(git rev-parse --quiet --verify refs/tgstash --)" &&
70 [ -n "$stashhash" ] &&
71 [ "$(git cat-file -t "$stashhash" -- 2>/dev/null)" = "tag" ] ||
72 die "requested --stash failed"
73 else
74 tg tag --anonymous $name &&
75 stashhash="$(git rev-parse --quiet --verify TG_STASH --)" &&
76 [ -n "$stashhash" ] &&
77 [ "$(git cat-file -t "$stashhash" -- 2>/dev/null)" = "tag" ] ||
78 die "anonymous --stash failed"
81 ## Wipe out
83 git update-ref -d "refs/$topbases/$name" "$baserev"
84 [ -z "$branchrev" ] || git update-ref -d "refs/heads/$name" "$branchrev"