80
81
For example, with this topology:
82
83
- o---o---o---B
84
- /
85
- ---o---1---o---o---o---A
83
+....
84
+ o---o---o---B
85
+ /
86
+---o---1---o---o---o---A
87
+....
88
89
the merge base between 'A' and 'B' is '1'.
90
92
merge base between 'A' and a hypothetical commit 'M', which is a merge
93
between 'B' and 'C'. For example, with this topology:
94
93
- o---o---o---o---C
94
- /
95
- / o---o---o---B
96
- / /
97
- ---2---1---o---o---o---A
95
+....
96
+ o---o---o---o---C
97
+ /
98
+ / o---o---o---B
99
+ / /
100
+---2---1---o---o---o---A
101
+....
102
103
the result of `git merge-base A B C` is '1'. This is because the
104
equivalent topology with a merge commit 'M' between 'B' and 'C' is:
105
106
103
- o---o---o---o---o
104
- / \
105
- / o---o---o---o---M
106
- / /
107
- ---2---1---o---o---o---A
107
+....
108
+ o---o---o---o---o
109
+ / \
110
+ / o---o---o---o---M
111
+ / /
112
+---2---1---o---o---o---A
113
+....
114
115
and the result of `git merge-base A M` is '1'. Commit '2' is also a
116
common ancestor between 'A' and 'M', but '1' is a better common ancestor,
122
When the history involves criss-cross merges, there can be more than one
123
'best' common ancestor for two commits. For example, with this topology:
124
119
- ---1---o---A
120
- \ /
121
- X
122
- / \
123
- ---2---o---o---B
125
+....
126
+---1---o---A
127
+ \ /
128
+ X
129
+ / \
130
+---2---o---o---B
131
+....
132
133
both '1' and '2' are merge-bases of A and B. Neither one is better than
134
the other (both are 'best' merge bases). When the `--all` option is not given,
139
A and B, and check if it is the same as A, in which case, A is an
140
ancestor of B. You will see this idiom used often in older scripts.
141
134
- A=$(git rev-parse --verify A)
135
- if test "$A" = "$(git merge-base A B)"
136
- then
137
- ... A is an ancestor of B ...
138
- fi
142
+....
143
+A=$(git rev-parse --verify A)
144
+if test "$A" = "$(git merge-base A B)"
145
+then
146
+ ... A is an ancestor of B ...
147
+fi
148
+....
149
150
In modern git, you can say this in a more direct way:
151
142
- if git merge-base --is-ancestor A B
143
- then
144
- ... A is an ancestor of B ...
145
- fi
152
+....
153
+if git merge-base --is-ancestor A B
154
+then
155
+ ... A is an ancestor of B ...
156
+fi
157
+....
158
159
instead.
160
166
`origin/master` may have been rewound and rebuilt, leading to a
167
history of this shape:
168
157
- o---B2
158
- /
159
- ---o---o---B1--o---o---o---B (origin/master)
160
- \
161
- B0
162
- \
163
- D0---D1---D (topic)
169
+....
170
+ o---B2
171
+ /
172
+---o---o---B1--o---o---o---B (origin/master)
173
+ \
174
+ B0
175
+ \
176
+ D0---D1---D (topic)
177
+....
178
179
where `origin/master` used to point at commits B0, B1, B2 and now it
180
points at B, and your `topic` branch was started on top of it back
207
will replay D0, D1 and D on top of B to create a new history of this
208
shape:
209
196
- o---B2
197
- /
198
- ---o---o---B1--o---o---o---B (origin/master)
199
- \ \
200
- B0 D0'--D1'--D' (topic - updated)
201
- \
202
- D0---D1---D (topic - old)
210
+....
211
+ o---B2
212
+ /
213
+---o---o---B1--o---o---o---B (origin/master)
214
+ \ \
215
+ B0 D0'--D1'--D' (topic - updated)
216
+ \
217
+ D0---D1---D (topic - old)
218
+....
219
220
A caveat is that older reflog entries in your repository may be
221
expired by `git gc`. If B0 no longer appears in the reflog of the