2 # TopGit - A different patch queue manager
3 # (C) Petr Baudis <pasky@suse.cz> 2008
4 # (C) Per Cederqvist <ceder@lysator.liu.se> 2010
5 # (C) Kyle J. McKay <mackyle@gmail.com> 2017
9 force
= # Whether to annihilate non-empty branch, or branch where only the base is left.
10 update
=1 # Whether to run tg update on affected branches
11 stash
= # tgstash refs before changes
13 if [ "$(git config --get --bool topgit.autostash 2>/dev/null)" != "false" ]; then
14 # topgit.autostash is true (or unset)
34 echo "Usage: ${tgname:-tg} [...] annihilate [-f] [--no-update]" >&2
42 v_verify_topgit_branch name HEAD
43 ! branch_annihilated
"$name" || die
"TopGit branch $name is already annihilated."
45 [ -z "$force" ] && { branch_empty
"$name" || die
"branch is non-empty: $name"; }
50 ensure_ident_available
51 alldeps
="$(get_temp alldeps)"
52 tg
--no-pager summary
--deps >"$alldeps" || die
"tg summary --deps failed"
54 # always auto stash even if it's just to the anonymous stash TG_STASH
56 stashbr
="$(awk -v annb="$name" '
58 if ($1 == annb && $2 != "" && $2 != annb) print $2
59 if ($2 == annb && $1 != "" && $1 != annb) print $1
61 ' <"$alldeps" | sort -u)"
62 stashmsg
="tgannihilate: autostash before annihilate branch $name"
63 if [ -n "$stash" ]; then
64 tg tag
-q -q -m "$stashmsg" --stash $name $stashbr &&
65 stashhash
="$(git rev-parse --quiet --verify refs/tgstash --)" &&
66 [ -n "$stashhash" ] &&
67 [ "$(git cat-file -t "$stashhash" -- 2>/dev/null)" = "tag" ] ||
68 die
"requested --stash failed"
70 tg tag
--anonymous $name $stashbr &&
71 stashhash
="$(git rev-parse --quiet --verify TG_STASH --)" &&
72 [ -n "$stashhash" ] &&
73 [ "$(git cat-file -t "$stashhash" -- 2>/dev/null)" = "tag" ] ||
74 die
"anonymous --stash failed"
77 mb
="$(git merge-base "refs
/$topbases/$name" "refs
/heads
/$name")"
78 git read-tree
"$mb^{tree}"
79 # Need to pass --no-verify in order to inhibit TopGit's pre-commit hook to run,
80 # which would bark upon missing .top* files.
81 git commit
--no-verify -m"TopGit branch $name annihilated."
83 # Propagate the dependencies through to dependents (if any), if they don't already have them
84 dependencies
="$(awk -v annb="$name" 'NF == 2 && $2 != "" && $1 == annb { print $2 }' <"$alldeps")"
86 while read dependent
&& [ -n "$dependent" ]; do
87 # to avoid ambiguity with checkout -f we must use symbolic-ref + reset
88 git symbolic-ref HEAD
"refs/heads/$dependent"
91 while read dependency
&& [ -n "$dependency" ]; do
92 ! tg depend add
--no-update "$dependency" >/dev
/null
2>&1 || needupdate
=1
96 [ -z "$needupdate" ] || updatelist
="${updatelist:+$updatelist }$dependent"
98 $(awk -v annb="$name" 'NF == 2 && $1 != "" && $2 == annb { print $1 }' <"$alldeps")
101 info
"branch successfully annihilated: $name"
103 if [ -n "$updatelist" ]; then
104 if [ -n "$update" ]; then
105 now
="after the update completes"
107 info
"skipping update because --no-update given"
108 info
"be sure to update affected branches: $updatelist"
112 info
"If you have shared your work, you might want to run ${tgname:-tg} push $name $now."
113 if [ -n "$updatelist" ] && [ -n "$update" ]; then
114 info
"now updating affected branches: $updatelist"
116 .
"$TG_INST_CMDDIR"/tg-update