TODO: add unified "fetch"
[git] / TO
1 #!/bin/sh
2
3 clean= next=next
4 branch=`git symbolic-ref HEAD`
5 while case $# in 0) break ;; esac
6 do
7         case "$1" in
8         --clean)
9                 test refs/heads/master = "$branch" || {
10                         echo >&2 Not on master 
11                         exit 1
12                 }
13                 clean=t
14                 ;;
15         --next)
16                 test 2 -le $# || {
17                         echo >&2 "Need argument"
18                         exit 1
19                 }
20                 next="$2"
21                 git rev-parse --verify "$next" >/dev/null || exit
22                 shift
23                 ;;
24         *)
25                 echo >&2 "$0 [--clean | --next test-next ]"
26                 exit 1
27                 ;;
28         esac
29         shift
30 done
31
32 master_sha1=`git rev-parse --verify refs/heads/master`
33 LF='
34 '
35 (cd .git/refs/heads && find -type f) |
36 sed -n \
37     -e 's/^\.\///' \
38     -e '/^[^\/][^\/]\//p' |
39 sort |
40 while read topic
41 do
42         rebase= done= not_done= trouble= date=
43         topic_sha1=`git rev-parse --verify "refs/heads/$topic"`
44         is_current=
45         if test "refs/heads/$topic" = "$branch"
46         then
47                 is_current=" *"
48         fi
49
50         date=`
51                 git-rev-list -1 --pretty "$topic" |
52                 sed -ne 's/^Date: *\(.*\)/ (\1)/p'
53         `
54         # (1)
55         only_next_1=`git-rev-list ^master "^$topic" ${next} | sort`
56         only_next_2=`git-rev-list ^master           ${next} | sort`
57         if test "$only_next_1" = "$only_next_2"
58         then
59                 not_in_topic=`git-rev-list "^$topic" master`
60                 if test -z "$not_in_topic"
61                 then
62                         rebase=" (vanilla)"
63                 else
64                         rebase=" (can be rebased)"
65                 fi
66         fi
67
68         # (2)
69         not_in_master=`
70                 git-rev-list ^master "$topic"
71         `
72         test -z "$not_in_master" &&
73         done="${LF}Fully merged -- delete."
74
75         # (3)
76         not_in_next=`
77                 git-rev-list --pretty=oneline ^${next} "$topic" |
78                 sed -e 's/^[0-9a-f]* / - /'
79         `
80         if test -n "$not_in_next"
81         then
82                 if test -n "$done"
83                 then
84                         # If $topic and master are the same,
85                         # it is fine.
86                         test "$master_sha1" = "$topic_sha1" ||
87                         trouble="${LF}### MODIFIED AFTER COOKED ###"
88                 fi
89                 not_done="${LF}Still not merged in ${next}$rebase.$LF$not_in_next"
90         elif test -n "$done"
91         then
92                 not_done=
93         else
94                 not_done="${LF}Up to date."
95         fi
96
97         echo "*** $topic ***$date$is_current$trouble$done$not_done"
98
99         if test -z "$trouble$not_done" &&
100             test -n "$done" &&
101             test t = "$clean"
102         then
103                 git branch -d "$topic"
104         fi
105 done
106
107 exit
108
109 ################################################################
110 Using Topic Branches
111
112 Some important disciplines first.
113
114  * Once a topic branch forks from "master", avoid merging "master"
115    updates into the topic branch unless necessary to resolve conflicts
116    early.
117
118  * Once a topic branch is fully cooked and merged into "master",
119    delete it.  If you need to build on top of it to correct
120    earlier mistakes, create a new topic branch by forking at the
121    tip of the "master".  This is not strictly necessary, but it
122    makes it easier to keep your history simple.
123
124  * Whenever you need to test or publish your changes to topic
125    branches, merge them into "next" branch.
126
127 So, you would want to know:
128
129 (1) ... if a topic branch has ever been merged to "next".  Young
130     topic branches can have stupid mistakes you would rather
131     clean up, and things that have not been merged into other
132     branches can be easily rebased without affecting others.
133
134 (2) ... if a topic branch has been fully merged to "master".
135     Then you can delete it.  More importantly, you can tell you
136     should not build on top of it.
137
138 (3) ... if a topic branch has commits unmerged to "next".  You
139     need to merge them to test and/or publish.
140
141 Let's look at this example:
142
143                    o---o---o---o---o---o---o---o---o---o "next"
144                   /       /           /           /
145                  /   a---a---b A     /           /
146                 /   /               /           /
147                /   /   c---c---c---c B         /
148               /   /   /             \         /
149              /   /   /   b---b C     \       /
150             /   /   /   /             \     /
151     ---o---o---o---o---o---o---o---o---o---o---o "master"
152
153
154 A, B and C are topic branches.
155
156  * A has one fix since it was merged up to "next".
157
158  * B has finished.  It has been fully merged up to "master" and "next",
159    and is ready to be deleted.
160
161  * C has not merged to "next" at all.
162
163 To compute (1):
164
165         git-rev-list ^master ^topic next
166         git-rev-list ^master        next
167
168         if these match, topic has not merged in next at all.
169
170 To compute (2):
171
172         git-rev-list master..topic
173
174         if this is empty, it is fully merged to "master".
175
176 To compute (3):
177
178         git-rev-list next..topic
179
180         if this is empty, there is nothing to merge to "next".
181