13
#include "remote.h"
14
#include "parse-options.h"
15
#include "branch.h"
16
+#include "diff.h"
17
+#include "revision.h"
18
19
static const char * const builtin_branch_usage[] = {
20
"git branch [options] [-r | -a] [--merged | --no-merged]",
181
struct ref_item {
182
char *name;
183
unsigned int kind;
182
- unsigned char sha1[20];
184
+ struct commit *commit;
185
};
186
187
struct ref_list {
188
+ struct rev_info revs;
189
int index, alloc, maxwidth;
190
struct ref_item *list;
191
struct commit_list *with_commit;
192
int kinds;
193
};
194
192
-static int has_commit(const unsigned char *sha1, struct commit_list *with_commit)
195
+static int has_commit(struct commit *commit, struct commit_list *with_commit)
196
{
194
- struct commit *commit;
195
-
197
if (!with_commit)
198
return 1;
198
- commit = lookup_commit_reference_gently(sha1, 1);
199
- if (!commit)
200
- return 0;
199
while (with_commit) {
200
struct commit *other;
201
211
{
212
struct ref_list *ref_list = (struct ref_list*)(cb_data);
213
struct ref_item *newitem;
214
+ struct commit *commit;
215
int kind;
216
int len;
217
static struct commit_list branch;
226
} else
227
return 0;
228
229
+ commit = lookup_commit_reference_gently(sha1, 1);
230
+ if (!commit)
231
+ return error("branch '%s' does not point at a commit", refname);
232
+
233
/* Filter with with_commit if specified */
231
- if (!has_commit(sha1, ref_list->with_commit))
234
+ if (!has_commit(commit, ref_list->with_commit))
235
return 0;
236
237
/* Don't add types the caller doesn't want */
242
branch.item = lookup_commit_reference_gently(sha1, 1);
243
if (!branch.item)
244
die("Unable to lookup tip of branch %s", refname);
242
- if (merge_filter == SHOW_NOT_MERGED &&
243
- has_commit(merge_filter_ref, &branch))
244
- return 0;
245
- if (merge_filter == SHOW_MERGED &&
246
- !has_commit(merge_filter_ref, &branch))
247
- return 0;
245
+ add_pending_object(&ref_list->revs,
246
+ (struct object *)branch.item, refname);
247
}
248
249
/* Resize buffer */
257
newitem = &(ref_list->list[ref_list->index++]);
258
newitem->name = xstrdup(refname);
259
newitem->kind = kind;
261
- hashcpy(newitem->sha1, sha1);
260
+ newitem->commit = commit;
261
len = strlen(newitem->name);
262
if (len > ref_list->maxwidth)
263
ref_list->maxwidth = len;
304
{
305
char c;
306
int color;
308
- struct commit *commit;
307
+ struct commit *commit = item->commit;
308
+
309
+ if (merge_filter != NO_FILTER) {
310
+ int is_merged = !!(item->commit->object.flags & UNINTERESTING);
311
+ if (is_merged != (merge_filter == SHOW_MERGED))
312
+ return;
313
+ }
314
315
switch (item->kind) {
316
case REF_LOCAL_BRANCH:
338
strbuf_init(&subject, 0);
339
stat[0] = '\0';
340
336
- commit = lookup_commit(item->sha1);
341
+ commit = item->commit;
342
if (commit && !parse_commit(commit)) {
343
pretty_print_commit(CMIT_FMT_ONELINE, commit,
344
&subject, 0, NULL, NULL, 0, 0);
351
printf("%c %s%-*s%s %s %s%s\n", c, branch_get_color(color),
352
maxwidth, item->name,
353
branch_get_color(COLOR_BRANCH_RESET),
349
- find_unique_abbrev(item->sha1, abbrev),
354
+ find_unique_abbrev(item->commit->object.sha1, abbrev),
355
stat, sub);
356
strbuf_release(&subject);
357
} else {
364
{
365
int i;
366
struct ref_list ref_list;
367
+ struct commit *head_commit = lookup_commit_reference_gently(head_sha1, 1);
368
369
memset(&ref_list, 0, sizeof(ref_list));
370
ref_list.kinds = kinds;
371
ref_list.with_commit = with_commit;
372
+ if (merge_filter != NO_FILTER)
373
+ init_revisions(&ref_list.revs, NULL);
374
for_each_ref(append_ref, &ref_list);
375
+ if (merge_filter != NO_FILTER) {
376
+ struct commit *filter;
377
+ filter = lookup_commit_reference_gently(merge_filter_ref, 0);
378
+ filter->object.flags |= UNINTERESTING;
379
+ add_pending_object(&ref_list.revs,
380
+ (struct object *) filter, "");
381
+ ref_list.revs.limited = 1;
382
+ prepare_revision_walk(&ref_list.revs);
383
+ }
384
385
qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp);
386
387
detached = (detached && (kinds & REF_LOCAL_BRANCH));
371
- if (detached && has_commit(head_sha1, with_commit)) {
388
+ if (detached && head_commit && has_commit(head_commit, with_commit)) {
389
struct ref_item item;
390
item.name = xstrdup("(no branch)");
391
item.kind = REF_LOCAL_BRANCH;
375
- hashcpy(item.sha1, head_sha1);
392
+ item.commit = head_commit;
393
if (strlen(item.name) > ref_list.maxwidth)
377
- ref_list.maxwidth = strlen(item.name);
394
+ ref_list.maxwidth = strlen(item.name);
395
print_ref_item(&item, ref_list.maxwidth, verbose, abbrev, 1);
396
free(item.name);
397
}