tg.sh: awksome accelerate non_annihilated_branches
[topgit/pro.git] / tg-depend.sh
blob67aa7dc53b44733c3769c5ef745afb9c1654eede
1 #!/bin/sh
2 # TopGit - A different patch queue manager
3 # Copyright (C) Petr Baudis <pasky@suse.cz> 2008
4 # Copyright (C) Kyle J. McKay <mackyle@gmail.com> 2015
5 # All rights reserved.
6 # GPLv2
8 USAGE="Usage: ${tgname:-tg} [...] depend add [--no-update | --no-commit] <name>..."
10 names=
12 usage()
14 printf '%s\n' "$USAGE" >&2
15 exit 1
18 ## Parse options
20 subcmd="$1"
21 case "$subcmd" in
22 -h|--help|"")
23 usage;;
24 add)
27 die "unknown subcommand ($subcmd)";;
28 esac
29 shift
31 noupdate=
32 nocommit=
33 while [ -n "$1" ]; do
34 arg="$1"; shift
35 case "$arg" in
36 --no-update)
37 noupdate=1;;
38 --no-commit)
39 nocommit=1;;
40 -*)
41 usage;;
43 names="${names:+$names }$arg";;
44 esac
45 done
48 ## Sanity checks
50 [ -n "$names" ] || die "no branch name specified"
51 oldnames="$names "
52 names=
53 while
54 name="${oldnames%% *}"
55 oldnames="${oldnames#* }"
56 [ -n "$name" ]
58 case " $names " in *" $name "*) continue; esac
59 git rev-parse --quiet --verify "refs/heads/$name" -- >/dev/null ||
60 die "invalid branch name: $name"
61 names="${names:+$names }$name"
62 done
63 unset oldnames
65 # Check that we are on a TopGit branch.
66 current_name="$(verify_topgit_branch HEAD)"
68 check_cycle_name()
70 [ "$current_name" != "$_dep" ] ||
71 die "$tgname: that dependency ($newly_added) would introduce a dependency loop"
74 check_new_dep()
76 [ "$1" != "$current_name" ] ||
77 die "$current_name cannot depend on itself."
78 ! grep -F -q -x -e "$1" "$root_dir/.topdeps" ||
79 die "$tgname: $current_name already depends on $1"
80 # deps can be non-tgish but we can't run recurse_deps() on them
81 ref_exists "refs/$topbases/$1" || return 0
82 no_remotes=1
83 newly_added="$1"
84 recurse_deps check_cycle_name "$newly_added"
87 ## Record new dependency
88 depend_add()
90 [ -z "$(git status --porcelain -- :/.topdeps)" ] ||
91 die ".topdeps has uncommitted changes"
92 # We are "read-only" and cacheable until the first change
93 tg_read_only=1
94 v_create_ref_cache
95 for name in $names; do
96 check_new_dep "$name"
97 done
98 [ -n "$nocommit" ] || ensure_ident_available
99 for name in $names; do
100 echol "$name" >>"$root_dir/.topdeps"
101 done
102 git add -f "$root_dir/.topdeps"
103 case "$names" in
104 *" "*)
105 msg=".topdeps: add dependencies: $names";;
107 msg=".topdeps: add new dependency $name";;
108 esac
109 [ -z "$nocommit" ] || {
110 [ -s "$git_dir/MERGE_MSG" ] || printf '%s\n' "$msg" >"$git_dir/MERGE_MSG"
111 info "updated .topdeps and staged the change"
112 info "run \`git commit\` then \`tg update\` to complete addition"
113 exit 0
115 become_non_cacheable
116 git commit -m "$msg" "$root_dir/.topdeps"
117 [ -z "$noupdate" ] || {
118 info "be sure to run \`tg update\` at some point"
119 exit 0
121 (ensure_clean_tree) || {
122 warn "skipping needed \`tg update\` since worktree is dirty"
123 warn "be sure to run \`tg update\` when worktree is clean"
124 exit 1
126 set -- "$current_name"
127 . "$TG_INST_CMDDIR"/tg-update
130 depend_$subcmd