2 # TopGit - A different patch queue manager
3 # (c) Petr Baudis <pasky@suse.cz> 2008
6 deps
= # List of dependent branches
7 restarted
= # Set to 1 if we are picking up in the middle of base setup
8 merge
= # List of branches to be merged; subset of $deps
10 rname
= # Remote branch to base this one on
21 echo "Usage: ${tgname:-tg} [...] create [<name> [<dep>...|-r <rname>] ]" >&2
24 if [ -z "$name" ]; then
33 ## Fast-track creating branches based on remote ones
35 if [ -n "$rname" ]; then
36 [ -n "$name" ] || die
"no branch name given"
37 ! ref_exists
"$name" || die
"branch '$name' already exists"
38 has_remote
"$rname" || die
"no branch $rname in remote $base_remote"
40 if [ -n "$logrefupdates" ]; then
41 mkdir
-p "$git_dir/logs/refs/top-bases/$(dirname "$name")" 2>/dev
/null ||
:
42 { >>"$git_dir/logs/refs/top-bases/$name" ||
:; } 2>/dev
/null
44 git update-ref
"refs/top-bases/$name" "refs/remotes/$base_remote/top-bases/$rname"
45 git update-ref
"refs/heads/$name" "refs/remotes/$base_remote/$rname"
46 info
"Topic branch $name based on $base_remote : $rname set up."
51 ## Auto-guess dependencies
54 if [ -z "$deps" ]; then
55 if [ -z "$name" -a -s "$git_dir/top-name" -a -s "$git_dir/top-deps" -a -s "$git_dir/top-merge" ]; then
56 # We are setting up the base branch now; resume merge!
57 name
="$(cat "$git_dir/top-name
")"
58 deps
="$(cat "$git_dir/top-deps
")"
59 merge
="$(cat "$git_dir/top-merge
")"
61 info
"Resuming $name setup..."
64 [ -z "$name" ] && die
"no branch name given"
65 head="$(git symbolic-ref HEAD)"
66 deps
="${head#refs/heads/}"
67 [ "$deps" != "$head" ] || die
"refusing to auto-depend on non-head ref ($head)"
68 info
"Automatically marking dependency on $deps"
72 [ -n "$merge" -o -n "$restarted" ] || merge
="$deps "
76 die
"unknown branch dependency '$d'"
78 ! ref_exists
"$name" ||
79 die
"branch '$name' already exists"
81 # Clean up any stale stuff
82 rm -f "$git_dir/top-name" "$git_dir/top-deps" "$git_dir/top-merge"
85 ## Find starting commit to create the base
87 if [ -n "$merge" -a -z "$restarted" ]; then
88 # Unshift the first item from the to-merge list
91 info
"Creating $name base from $branch..."
92 # We create a detached head so that we can abort this operation
93 git checkout
-q "$(git rev-parse "$branch")"
97 ## Merge other dependencies into the base
99 while [ -n "$merge" ]; do
100 # Unshift the first item from the to-merge list
101 branch
="${merge%% *}"
103 info
"Merging $name base with $branch..."
105 if ! git merge
"$branch"; then
106 info
"Please commit merge resolution and call: $tgdisplay create"
107 info
"It is also safe to abort this operation using:"
108 info
"git$gitcdopt reset --hard some_branch"
109 info
"(You are on a detached HEAD now.)"
110 echo "$name" >"$git_dir/top-name"
111 echo "$deps" >"$git_dir/top-deps"
112 echo "$merge" >"$git_dir/top-merge"
118 ## Set up the topic branch
120 if [ -n "$logrefupdates" ]; then
121 mkdir
-p "$git_dir/logs/refs/top-bases/$(dirname "$name")" 2>/dev
/null ||
:
122 { >>"$git_dir/logs/refs/top-bases/$name" ||
:; } 2>/dev
/null
124 git update-ref
"refs/top-bases/$name" "HEAD" ""
125 git checkout
-b "$name"
127 echo "$deps" |
sed 'y/ /\n/' >"$root_dir/.topdeps"
128 git add
-f "$root_dir/.topdeps"
130 author
="$(git var GIT_AUTHOR_IDENT)"
131 author_addr
="${author%> *}>"
133 echo "From: $author_addr"
134 ! header
="$(git config topgit.to)" ||
echo "To: $header"
135 ! header
="$(git config topgit.cc)" ||
echo "Cc: $header"
136 ! header
="$(git config topgit.bcc)" ||
echo "Bcc: $header"
137 ! subject_prefix
="$(git config topgit.subjectprefix)" || subject_prefix
="$subject_prefix "
138 echo "Subject: [${subject_prefix}PATCH] $name"
140 echo '<patch description>'
142 [ "$(git config --bool format.signoff)" = true
] && echo "Signed-off-by: $author_addr"
143 } >"$root_dir/.topmsg"
144 git add
-f "$root_dir/.topmsg"
148 info
"Topic branch $name set up. Please fill .topmsg now and make initial commit."
149 info
"To abort: git$gitcdopt rm -f .top* && git$gitcdopt checkout ${deps%% *} && $tgdisplay delete $name"