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