topgit_msg: expose bare branches
[topgit/pro.git] / tg-depend.sh
blob73790777e8ceb8b180126fec7082f8ac1779511e
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
30 ensure_work_tree
32 noupdate=
33 nocommit=
34 while [ -n "$1" ]; do
35 arg="$1"; shift
36 case "$arg" in
37 --no-update)
38 noupdate=1;;
39 --no-commit)
40 nocommit=1;;
41 -*)
42 usage;;
44 names="${names:+$names }$arg";;
45 esac
46 done
49 ## Sanity checks
51 [ -n "$names" ] || die "no branch name specified"
52 oldnames="$names "
53 names=
54 while
55 name="${oldnames%% *}"
56 oldnames="${oldnames#* }"
57 [ -n "$name" ]
59 case " $names " in *" $name "*) continue; esac
60 git rev-parse --quiet --verify "refs/heads/$name" -- >/dev/null ||
61 die "invalid branch name: $name"
62 names="${names:+$names }$name"
63 done
64 unset oldnames
66 # Check that we are on a TopGit branch.
67 current_name="$(verify_topgit_branch HEAD)"
69 check_cycle_name()
71 [ "$current_name" != "$_dep" ] ||
72 die "$tgname: that dependency ($newly_added) would introduce a dependency loop"
75 check_new_dep()
77 [ "$1" != "$current_name" ] ||
78 die "$current_name cannot depend on itself."
79 ! grep -F -q -x -e "$1" "$root_dir/.topdeps" ||
80 die "$tgname: $current_name already depends on $1"
81 # deps can be non-tgish but we can't run recurse_deps() on them
82 ref_exists "refs/$topbases/$1" || return 0
83 no_remotes=1
84 newly_added="$1"
85 recurse_deps check_cycle_name "$newly_added"
88 ## Record new dependency
89 depend_add()
91 [ -z "$(git status --porcelain -- :/.topdeps)" ] ||
92 die ".topdeps has uncommitted changes"
93 # We are "read-only" and cacheable until the first change
94 tg_read_only=1
95 v_create_ref_cache
96 for name in $names; do
97 check_new_dep "$name"
98 done
99 [ -n "$nocommit" ] || ensure_ident_available
100 newdepsfile="$(get_temp newdeps)"
101 ! [ -e "$root_dir/.topdeps" ] || awk '{print}' <"$root_dir/.topdeps" >"$newdepsfile"
102 for name in $names; do
103 echol "$name" >>"$newdepsfile"
104 done
105 cat "$newdepsfile" >"$root_dir/.topdeps"
106 git add -f "$root_dir/.topdeps"
107 case "$names" in
108 *" "*)
109 msg=".topdeps: add dependencies: $names";;
111 msg=".topdeps: add new dependency $name";;
112 esac
113 [ -z "$nocommit" ] || {
114 [ -s "$git_dir/MERGE_MSG" ] || printf '%s\n' "$msg" >"$git_dir/MERGE_MSG"
115 info "updated .topdeps and staged the change"
116 info "run \`git commit\` then \`tg update\` to complete addition"
117 exit 0
119 become_non_cacheable
120 git commit -m "$msg" "$root_dir/.topdeps"
121 [ -z "$noupdate" ] || {
122 info "be sure to run \`tg update\` at some point"
123 exit 0
125 (ensure_clean_tree) || {
126 warn "skipping needed \`tg update\` since worktree is dirty"
127 warn "be sure to run \`tg update\` when worktree is clean"
128 exit 1
130 set -- "$current_name"
131 . "$TG_INST_CMDDIR"/tg-update
134 depend_$subcmd