Changeset 782 for git/branches/dmik/revision.c
- Timestamp:
- Jun 23, 2014, 9:45:51 PM (11 years ago)
- Location:
- git/branches/dmik
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
git/branches/dmik ¶
- Property svn:mergeinfo changed
/git/vendor/2.0.0 (added) merged: 777 /git/vendor/current merged: 772,774,776
- Property svn:mergeinfo changed
-
TabularUnified git/branches/dmik/revision.c ¶
r626 r782 14 14 #include "log-tree.h" 15 15 #include "string-list.h" 16 #include "line-log.h" 17 #include "mailmap.h" 18 #include "commit-slab.h" 19 #include "dir.h" 16 20 17 21 volatile show_early_output_fn_t show_early_output; … … 70 74 } 71 75 72 void show_object_with_name(FILE *out, struct object *obj, const struct name_path *path, const char *component) 76 void show_object_with_name(FILE *out, struct object *obj, 77 const struct name_path *path, const char *component) 73 78 { 74 79 struct name_path leaf; … … 87 92 const char *name) 88 93 { 89 add_object_array(obj, path_name(path, name), p); 94 char *pn = path_name(path, name); 95 add_object_array(obj, pn, p); 96 free(pn); 90 97 } 91 98 … … 99 106 } 100 107 101 void mark_tree_uninteresting(struct tree *tree)108 static void mark_tree_contents_uninteresting(struct tree *tree) 102 109 { 103 110 struct tree_desc desc; … … 105 112 struct object *obj = &tree->object; 106 113 107 if (!tree)108 return;109 if (obj->flags & UNINTERESTING)110 return;111 obj->flags |= UNINTERESTING;112 114 if (!has_sha1_file(obj->sha1)) 113 115 return; … … 134 136 * after it has been marked uninteresting. 135 137 */ 136 free(tree->buffer); 137 tree->buffer = NULL; 138 free_tree_buffer(tree); 139 } 140 141 void mark_tree_uninteresting(struct tree *tree) 142 { 143 struct object *obj = &tree->object; 144 145 if (!tree) 146 return; 147 if (obj->flags & UNINTERESTING) 148 return; 149 obj->flags |= UNINTERESTING; 150 mark_tree_contents_uninteresting(tree); 138 151 } 139 152 140 153 void mark_parents_uninteresting(struct commit *commit) 141 154 { 142 struct commit_list *parents = commit->parents; 155 struct commit_list *parents = NULL, *l; 156 157 for (l = commit->parents; l; l = l->next) 158 commit_list_insert(l->item, &parents); 143 159 144 160 while (parents) { 145 161 struct commit *commit = parents->item; 146 if (!(commit->object.flags & UNINTERESTING)) { 162 l = parents; 163 parents = parents->next; 164 free(l); 165 166 while (commit) { 167 /* 168 * A missing commit is ok iff its parent is marked 169 * uninteresting. 170 * 171 * We just mark such a thing parsed, so that when 172 * it is popped next time around, we won't be trying 173 * to parse it and get an error. 174 */ 175 if (!has_sha1_file(commit->object.sha1)) 176 commit->object.parsed = 1; 177 178 if (commit->object.flags & UNINTERESTING) 179 break; 180 147 181 commit->object.flags |= UNINTERESTING; 148 182 … … 155 189 * to mark its parents recursively too.. 156 190 */ 157 if (commit->parents) 158 mark_parents_uninteresting(commit); 159 } 160 161 /* 162 * A missing commit is ok iff its parent is marked 163 * uninteresting. 164 * 165 * We just mark such a thing parsed, so that when 166 * it is popped next time around, we won't be trying 167 * to parse it and get an error. 168 */ 169 if (!has_sha1_file(commit->object.sha1)) 170 commit->object.parsed = 1; 171 parents = parents->next; 172 } 173 } 174 175 static void add_pending_object_with_mode(struct rev_info *revs, struct object *obj, const char *name, unsigned mode) 191 if (!commit->parents) 192 break; 193 194 for (l = commit->parents->next; l; l = l->next) 195 commit_list_insert(l->item, &parents); 196 commit = commit->parents->item; 197 } 198 } 199 } 200 201 static void add_pending_object_with_mode(struct rev_info *revs, 202 struct object *obj, 203 const char *name, unsigned mode) 176 204 { 177 205 if (!obj) … … 181 209 if (revs->reflog_info && obj->type == OBJ_COMMIT) { 182 210 struct strbuf buf = STRBUF_INIT; 183 int len = interpret_branch_name(name, &buf);211 int len = interpret_branch_name(name, 0, &buf); 184 212 int st; 185 213 … … 196 224 } 197 225 198 void add_pending_object(struct rev_info *revs, struct object *obj, const char *name) 226 void add_pending_object(struct rev_info *revs, 227 struct object *obj, const char *name) 199 228 { 200 229 add_pending_object_with_mode(revs, obj, name, S_IFINVALID); … … 213 242 } 214 243 215 static struct object *get_reference(struct rev_info *revs, const char *name, const unsigned char *sha1, unsigned int flags) 244 static struct object *get_reference(struct rev_info *revs, const char *name, 245 const unsigned char *sha1, 246 unsigned int flags) 216 247 { 217 248 struct object *object; … … 234 265 } 235 266 236 static struct commit *handle_commit(struct rev_info *revs, struct object *object, const char *name) 267 static struct commit *handle_commit(struct rev_info *revs, 268 struct object *object, const char *name) 237 269 { 238 270 unsigned long flags = object->flags; … … 253 285 die("bad object %s", sha1_to_hex(tag->tagged->sha1)); 254 286 } 287 object->flags |= flags; 255 288 } 256 289 … … 264 297 die("unable to parse commit %s", name); 265 298 if (flags & UNINTERESTING) { 266 commit->object.flags |= UNINTERESTING;267 299 mark_parents_uninteresting(commit); 268 300 revs->limited = 1; … … 282 314 return NULL; 283 315 if (flags & UNINTERESTING) { 284 mark_tree_ uninteresting(tree);316 mark_tree_contents_uninteresting(tree); 285 317 return NULL; 286 318 } … … 293 325 */ 294 326 if (object->type == OBJ_BLOB) { 295 struct blob *blob = (struct blob *)object;296 327 if (!revs->blob_objects) 297 328 return NULL; 298 if (flags & UNINTERESTING) { 299 mark_blob_uninteresting(blob); 329 if (flags & UNINTERESTING) 300 330 return NULL; 301 }302 331 add_pending_object(revs, object, ""); 303 332 return NULL; … … 317 346 } 318 347 return 1; 348 } 349 350 /* 351 * A definition of "relevant" commit that we can use to simplify limited graphs 352 * by eliminating side branches. 353 * 354 * A "relevant" commit is one that is !UNINTERESTING (ie we are including it 355 * in our list), or that is a specified BOTTOM commit. Then after computing 356 * a limited list, during processing we can generally ignore boundary merges 357 * coming from outside the graph, (ie from irrelevant parents), and treat 358 * those merges as if they were single-parent. TREESAME is defined to consider 359 * only relevant parents, if any. If we are TREESAME to our on-graph parents, 360 * we don't care if we were !TREESAME to non-graph parents. 361 * 362 * Treating bottom commits as relevant ensures that a limited graph's 363 * connection to the actual bottom commit is not viewed as a side branch, but 364 * treated as part of the graph. For example: 365 * 366 * ....Z...A---X---o---o---B 367 * . / 368 * W---Y 369 * 370 * When computing "A..B", the A-X connection is at least as important as 371 * Y-X, despite A being flagged UNINTERESTING. 372 * 373 * And when computing --ancestry-path "A..B", the A-X connection is more 374 * important than Y-X, despite both A and Y being flagged UNINTERESTING. 375 */ 376 static inline int relevant_commit(struct commit *commit) 377 { 378 return (commit->object.flags & (UNINTERESTING | BOTTOM)) != UNINTERESTING; 379 } 380 381 /* 382 * Return a single relevant commit from a parent list. If we are a TREESAME 383 * commit, and this selects one of our parents, then we can safely simplify to 384 * that parent. 385 */ 386 static struct commit *one_relevant_parent(const struct rev_info *revs, 387 struct commit_list *orig) 388 { 389 struct commit_list *list = orig; 390 struct commit *relevant = NULL; 391 392 if (!orig) 393 return NULL; 394 395 /* 396 * For 1-parent commits, or if first-parent-only, then return that 397 * first parent (even if not "relevant" by the above definition). 398 * TREESAME will have been set purely on that parent. 399 */ 400 if (revs->first_parent_only || !orig->next) 401 return orig->item; 402 403 /* 404 * For multi-parent commits, identify a sole relevant parent, if any. 405 * If we have only one relevant parent, then TREESAME will be set purely 406 * with regard to that parent, and we can simplify accordingly. 407 * 408 * If we have more than one relevant parent, or no relevant parents 409 * (and multiple irrelevant ones), then we can't select a parent here 410 * and return NULL. 411 */ 412 while (list) { 413 struct commit *commit = list->item; 414 list = list->next; 415 if (relevant_commit(commit)) { 416 if (relevant) 417 return NULL; 418 relevant = commit; 419 } 420 } 421 return relevant; 319 422 } 320 423 … … 333 436 int addremove, unsigned mode, 334 437 const unsigned char *sha1, 438 int sha1_valid, 335 439 const char *fullpath, unsigned dirty_submodule) 336 440 { … … 346 450 const unsigned char *old_sha1, 347 451 const unsigned char *new_sha1, 452 int old_sha1_valid, int new_sha1_valid, 348 453 const char *fullpath, 349 454 unsigned old_dirty_submodule, unsigned new_dirty_submodule) … … 353 458 } 354 459 355 static int rev_compare_tree(struct rev_info *revs, struct commit *parent, struct commit *commit) 460 static int rev_compare_tree(struct rev_info *revs, 461 struct commit *parent, struct commit *commit) 356 462 { 357 463 struct tree *t1 = parent->tree; … … 392 498 { 393 499 int retval; 394 void *tree;395 unsigned long size;396 struct tree_desc empty, real;397 500 struct tree *t1 = commit->tree; 398 501 … … 400 503 return 0; 401 504 402 tree = read_object_with_reference(t1->object.sha1, tree_type, &size, NULL);403 if (!tree)404 return 0;405 init_tree_desc(&real, tree, size);406 init_tree_desc(&empty, "", 0);407 408 505 tree_difference = REV_TREE_SAME; 409 506 DIFF_OPT_CLR(&revs->pruning, HAS_CHANGES); 410 retval = diff_tree(&empty, &real, "", &revs->pruning); 411 free(tree); 507 retval = diff_tree_sha1(NULL, t1->object.sha1, "", &revs->pruning); 412 508 413 509 return retval >= 0 && (tree_difference == REV_TREE_SAME); 414 510 } 415 511 512 struct treesame_state { 513 unsigned int nparents; 514 unsigned char treesame[FLEX_ARRAY]; 515 }; 516 517 static struct treesame_state *initialise_treesame(struct rev_info *revs, struct commit *commit) 518 { 519 unsigned n = commit_list_count(commit->parents); 520 struct treesame_state *st = xcalloc(1, sizeof(*st) + n); 521 st->nparents = n; 522 add_decoration(&revs->treesame, &commit->object, st); 523 return st; 524 } 525 526 /* 527 * Must be called immediately after removing the nth_parent from a commit's 528 * parent list, if we are maintaining the per-parent treesame[] decoration. 529 * This does not recalculate the master TREESAME flag - update_treesame() 530 * should be called to update it after a sequence of treesame[] modifications 531 * that may have affected it. 532 */ 533 static int compact_treesame(struct rev_info *revs, struct commit *commit, unsigned nth_parent) 534 { 535 struct treesame_state *st; 536 int old_same; 537 538 if (!commit->parents) { 539 /* 540 * Have just removed the only parent from a non-merge. 541 * Different handling, as we lack decoration. 542 */ 543 if (nth_parent != 0) 544 die("compact_treesame %u", nth_parent); 545 old_same = !!(commit->object.flags & TREESAME); 546 if (rev_same_tree_as_empty(revs, commit)) 547 commit->object.flags |= TREESAME; 548 else 549 commit->object.flags &= ~TREESAME; 550 return old_same; 551 } 552 553 st = lookup_decoration(&revs->treesame, &commit->object); 554 if (!st || nth_parent >= st->nparents) 555 die("compact_treesame %u", nth_parent); 556 557 old_same = st->treesame[nth_parent]; 558 memmove(st->treesame + nth_parent, 559 st->treesame + nth_parent + 1, 560 st->nparents - nth_parent - 1); 561 562 /* 563 * If we've just become a non-merge commit, update TREESAME 564 * immediately, and remove the no-longer-needed decoration. 565 * If still a merge, defer update until update_treesame(). 566 */ 567 if (--st->nparents == 1) { 568 if (commit->parents->next) 569 die("compact_treesame parents mismatch"); 570 if (st->treesame[0] && revs->dense) 571 commit->object.flags |= TREESAME; 572 else 573 commit->object.flags &= ~TREESAME; 574 free(add_decoration(&revs->treesame, &commit->object, NULL)); 575 } 576 577 return old_same; 578 } 579 580 static unsigned update_treesame(struct rev_info *revs, struct commit *commit) 581 { 582 if (commit->parents && commit->parents->next) { 583 unsigned n; 584 struct treesame_state *st; 585 struct commit_list *p; 586 unsigned relevant_parents; 587 unsigned relevant_change, irrelevant_change; 588 589 st = lookup_decoration(&revs->treesame, &commit->object); 590 if (!st) 591 die("update_treesame %s", sha1_to_hex(commit->object.sha1)); 592 relevant_parents = 0; 593 relevant_change = irrelevant_change = 0; 594 for (p = commit->parents, n = 0; p; n++, p = p->next) { 595 if (relevant_commit(p->item)) { 596 relevant_change |= !st->treesame[n]; 597 relevant_parents++; 598 } else 599 irrelevant_change |= !st->treesame[n]; 600 } 601 if (relevant_parents ? relevant_change : irrelevant_change) 602 commit->object.flags &= ~TREESAME; 603 else 604 commit->object.flags |= TREESAME; 605 } 606 607 return commit->object.flags & TREESAME; 608 } 609 610 static inline int limiting_can_increase_treesame(const struct rev_info *revs) 611 { 612 /* 613 * TREESAME is irrelevant unless prune && dense; 614 * if simplify_history is set, we can't have a mixture of TREESAME and 615 * !TREESAME INTERESTING parents (and we don't have treesame[] 616 * decoration anyway); 617 * if first_parent_only is set, then the TREESAME flag is locked 618 * against the first parent (and again we lack treesame[] decoration). 619 */ 620 return revs->prune && revs->dense && 621 !revs->simplify_history && 622 !revs->first_parent_only; 623 } 624 416 625 static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit) 417 626 { 418 627 struct commit_list **pp, *parent; 419 int tree_changed = 0, tree_same = 0, nth_parent = 0; 628 struct treesame_state *ts = NULL; 629 int relevant_change = 0, irrelevant_change = 0; 630 int relevant_parents, nth_parent; 420 631 421 632 /* … … 441 652 return; 442 653 443 pp = &commit->parents; 444 while ((parent = *pp) != NULL) { 654 for (pp = &commit->parents, nth_parent = 0, relevant_parents = 0; 655 (parent = *pp) != NULL; 656 pp = &parent->next, nth_parent++) { 445 657 struct commit *p = parent->item; 446 447 /* 448 * Do not compare with later parents when we care only about 449 * the first parent chain, in order to avoid derailing the 450 * traversal to follow a side branch that brought everything 451 * in the path we are limited to by the pathspec. 452 */ 453 if (revs->first_parent_only && nth_parent++) 454 break; 658 if (relevant_commit(p)) 659 relevant_parents++; 660 661 if (nth_parent == 1) { 662 /* 663 * This our second loop iteration - so we now know 664 * we're dealing with a merge. 665 * 666 * Do not compare with later parents when we care only about 667 * the first parent chain, in order to avoid derailing the 668 * traversal to follow a side branch that brought everything 669 * in the path we are limited to by the pathspec. 670 */ 671 if (revs->first_parent_only) 672 break; 673 /* 674 * If this will remain a potentially-simplifiable 675 * merge, remember per-parent treesame if needed. 676 * Initialise the array with the comparison from our 677 * first iteration. 678 */ 679 if (revs->treesame.name && 680 !revs->simplify_history && 681 !(commit->object.flags & UNINTERESTING)) { 682 ts = initialise_treesame(revs, commit); 683 if (!(irrelevant_change || relevant_change)) 684 ts->treesame[0] = 1; 685 } 686 } 455 687 if (parse_commit(p) < 0) 456 688 die("cannot simplify commit %s (because of %s)", … … 459 691 switch (rev_compare_tree(revs, p, commit)) { 460 692 case REV_TREE_SAME: 461 tree_same = 1; 462 if (!revs->simplify_history || (p->object.flags & UNINTERESTING)) { 693 if (!revs->simplify_history || !relevant_commit(p)) { 463 694 /* Even if a merge with an uninteresting 464 695 * side branch brought the entire change … … 467 698 * merge, so we just keep going. 468 699 */ 469 pp = &parent->next; 700 if (ts) 701 ts->treesame[nth_parent] = 1; 470 702 continue; 471 703 } … … 495 727 case REV_TREE_OLD: 496 728 case REV_TREE_DIFFERENT: 497 tree_changed = 1; 498 pp = &parent->next; 729 if (relevant_commit(p)) 730 relevant_change = 1; 731 else 732 irrelevant_change = 1; 499 733 continue; 500 734 } 501 735 die("bad tree compare for commit %s", sha1_to_hex(commit->object.sha1)); 502 736 } 503 if (tree_changed && !tree_same) 504 return; 505 commit->object.flags |= TREESAME; 737 738 /* 739 * TREESAME is straightforward for single-parent commits. For merge 740 * commits, it is most useful to define it so that "irrelevant" 741 * parents cannot make us !TREESAME - if we have any relevant 742 * parents, then we only consider TREESAMEness with respect to them, 743 * allowing irrelevant merges from uninteresting branches to be 744 * simplified away. Only if we have only irrelevant parents do we 745 * base TREESAME on them. Note that this logic is replicated in 746 * update_treesame, which should be kept in sync. 747 */ 748 if (relevant_parents ? !relevant_change : !irrelevant_change) 749 commit->object.flags |= TREESAME; 506 750 } 507 751 … … 530 774 return 0; 531 775 commit->object.flags |= ADDED; 776 777 if (revs->include_check && 778 !revs->include_check(commit, revs->include_check_data)) 779 return 0; 532 780 533 781 /* … … 694 942 * before the source list? Definitely _not_ done. 695 943 */ 696 if (date < src->item->date)944 if (date <= src->item->date) 697 945 return SLOP; 698 946 … … 786 1034 * reach A. 787 1035 */ 788 static struct commit_list *collect_bottom_commits(struct rev_info *revs) 789 { 790 struct commit_list *bottom = NULL; 791 int i; 792 for (i = 0; i < revs->cmdline.nr; i++) { 793 struct rev_cmdline_entry *elem = &revs->cmdline.rev[i]; 794 if ((elem->flags & UNINTERESTING) && 795 elem->item->type == OBJ_COMMIT) 796 commit_list_insert((struct commit *)elem->item, &bottom); 797 } 1036 static struct commit_list *collect_bottom_commits(struct commit_list *list) 1037 { 1038 struct commit_list *elem, *bottom = NULL; 1039 for (elem = list; elem; elem = elem->next) 1040 if (elem->item->object.flags & BOTTOM) 1041 commit_list_insert(elem->item, &bottom); 798 1042 return bottom; 799 1043 } … … 826 1070 827 1071 if (revs->ancestry_path) { 828 bottom = collect_bottom_commits( revs);1072 bottom = collect_bottom_commits(list); 829 1073 if (!bottom) 830 1074 die("--ancestry-path given but there are no bottom commits"); … … 879 1123 } 880 1124 1125 /* 1126 * Check if any commits have become TREESAME by some of their parents 1127 * becoming UNINTERESTING. 1128 */ 1129 if (limiting_can_increase_treesame(revs)) 1130 for (list = newlist; list; list = list->next) { 1131 struct commit *c = list->item; 1132 if (c->object.flags & (UNINTERESTING | TREESAME)) 1133 continue; 1134 update_treesame(revs, c); 1135 } 1136 881 1137 revs->commits = newlist; 882 1138 return 0; 883 1139 } 884 1140 1141 /* 1142 * Add an entry to refs->cmdline with the specified information. 1143 * *name is copied. 1144 */ 885 1145 static void add_rev_cmdline(struct rev_info *revs, 886 1146 struct object *item, … … 894 1154 ALLOC_GROW(info->rev, nr + 1, info->alloc); 895 1155 info->rev[nr].item = item; 896 info->rev[nr].name = name;1156 info->rev[nr].name = xstrdup(name); 897 1157 info->rev[nr].whence = whence; 898 1158 info->rev[nr].flags = flags; 899 1159 info->nr++; 1160 } 1161 1162 static void add_rev_cmdline_list(struct rev_info *revs, 1163 struct commit_list *commit_list, 1164 int whence, 1165 unsigned flags) 1166 { 1167 while (commit_list) { 1168 struct object *object = &commit_list->item->object; 1169 add_rev_cmdline(revs, object, sha1_to_hex(object->sha1), 1170 whence, flags); 1171 commit_list = commit_list->next; 1172 } 900 1173 } 901 1174 … … 907 1180 }; 908 1181 1182 int ref_excluded(struct string_list *ref_excludes, const char *path) 1183 { 1184 struct string_list_item *item; 1185 1186 if (!ref_excludes) 1187 return 0; 1188 for_each_string_list_item(item, ref_excludes) { 1189 if (!wildmatch(item->string, path, 0, NULL)) 1190 return 1; 1191 } 1192 return 0; 1193 } 1194 909 1195 static int handle_one_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data) 910 1196 { 911 1197 struct all_refs_cb *cb = cb_data; 912 struct object *object = get_reference(cb->all_revs, path, sha1, 913 cb->all_flags); 1198 struct object *object; 1199 1200 if (ref_excluded(cb->all_revs->ref_excludes, path)) 1201 return 0; 1202 1203 object = get_reference(cb->all_revs, path, sha1, cb->all_flags); 914 1204 add_rev_cmdline(cb->all_revs, object, path, REV_CMD_REF, cb->all_flags); 915 1205 add_pending_sha1(cb->all_revs, path, sha1, cb->all_flags); … … 922 1212 cb->all_revs = revs; 923 1213 cb->all_flags = flags; 1214 } 1215 1216 void clear_ref_exclusion(struct string_list **ref_excludes_p) 1217 { 1218 if (*ref_excludes_p) { 1219 string_list_clear(*ref_excludes_p, 0); 1220 free(*ref_excludes_p); 1221 } 1222 *ref_excludes_p = NULL; 1223 } 1224 1225 void add_ref_exclusion(struct string_list **ref_excludes_p, const char *exclude) 1226 { 1227 if (!*ref_excludes_p) { 1228 *ref_excludes_p = xcalloc(1, sizeof(**ref_excludes_p)); 1229 (*ref_excludes_p)->strdup_strings = 1; 1230 } 1231 string_list_append(*ref_excludes_p, exclude); 924 1232 } 925 1233 … … 985 1293 986 1294 if (*arg == '^') { 987 flags ^= UNINTERESTING ;1295 flags ^= UNINTERESTING | BOTTOM; 988 1296 arg++; 989 1297 } 990 if (get_sha1 (arg, sha1))1298 if (get_sha1_committish(arg, sha1)) 991 1299 return 0; 992 1300 while (1) { … … 1023 1331 revs->pruning.add_remove = file_add_remove; 1024 1332 revs->pruning.change = file_change; 1025 revs-> lifo = 1;1333 revs->sort_order = REV_SORT_IN_GRAPH_ORDER; 1026 1334 revs->dense = 1; 1027 1335 revs->prefix = prefix; … … 1034 1342 revs->commit_format = CMIT_FMT_DEFAULT; 1035 1343 1344 init_grep_defaults(); 1345 grep_init(&revs->grep_filter, prefix); 1036 1346 revs->grep_filter.status_only = 1; 1037 revs->grep_filter.pattern_tail = &(revs->grep_filter.pattern_list);1038 revs->grep_filter.header_tail = &(revs->grep_filter.header_list);1039 1347 revs->grep_filter.regflags = REG_NEWLINE; 1040 1348 … … 1077 1385 add_pending_object(revs, &other->object, "MERGE_HEAD"); 1078 1386 bases = get_merge_bases(head, other, 1); 1079 add_pending_commit_list(revs, bases, UNINTERESTING); 1387 add_rev_cmdline_list(revs, bases, REV_CMD_MERGE_BASE, UNINTERESTING | BOTTOM); 1388 add_pending_commit_list(revs, bases, UNINTERESTING | BOTTOM); 1080 1389 free_commit_list(bases); 1081 1390 head->object.flags |= SYMMETRIC_LEFT; … … 1084 1393 read_cache(); 1085 1394 for (i = 0; i < active_nr; i++) { 1086 struct cache_entry *ce = active_cache[i];1395 const struct cache_entry *ce = active_cache[i]; 1087 1396 if (!ce_stage(ce)) 1088 1397 continue; 1089 if (ce_path_match(ce, &revs->prune_data )) {1398 if (ce_path_match(ce, &revs->prune_data, NULL)) { 1090 1399 prune_num++; 1091 1400 prune = xrealloc(prune, sizeof(*prune) * prune_num); … … 1098 1407 } 1099 1408 free_pathspec(&revs->prune_data); 1100 init_pathspec(&revs->prune_data, prune); 1409 parse_pathspec(&revs->prune_data, PATHSPEC_ALL_MAGIC & ~PATHSPEC_LITERAL, 1410 PATHSPEC_PREFER_FULL | PATHSPEC_LITERAL_PATH, "", prune); 1101 1411 revs->limited = 1; 1102 1412 } 1103 1413 1104 int handle_revision_arg(const char *arg_, struct rev_info *revs, 1105 int flags, 1106 int cant_be_filename) 1107 { 1108 unsigned mode; 1414 int handle_revision_arg(const char *arg_, struct rev_info *revs, int flags, unsigned revarg_opt) 1415 { 1416 struct object_context oc; 1109 1417 char *dotdot; 1110 1418 struct object *object; … … 1112 1420 int local_flags; 1113 1421 const char *arg = arg_; 1422 int cant_be_filename = revarg_opt & REVARG_CANNOT_BE_FILENAME; 1423 unsigned get_sha1_flags = 0; 1424 1425 flags = flags & UNINTERESTING ? flags | BOTTOM : flags & ~BOTTOM; 1114 1426 1115 1427 dotdot = strstr(arg, ".."); … … 1119 1431 const char *this = arg; 1120 1432 int symmetric = *next == '.'; 1121 unsigned int flags_exclude = flags ^ UNINTERESTING; 1433 unsigned int flags_exclude = flags ^ (UNINTERESTING | BOTTOM); 1434 static const char head_by_default[] = "HEAD"; 1122 1435 unsigned int a_flags; 1123 1436 … … 1126 1439 1127 1440 if (!*next) 1128 next = "HEAD";1441 next = head_by_default; 1129 1442 if (dotdot == arg) 1130 this = "HEAD"; 1131 if (!get_sha1(this, from_sha1) && 1132 !get_sha1(next, sha1)) { 1133 struct commit *a, *b; 1134 struct commit_list *exclude; 1135 1136 a = lookup_commit_reference(from_sha1); 1137 b = lookup_commit_reference(sha1); 1138 if (!a || !b) { 1139 if (revs->ignore_missing) 1140 return 0; 1141 die(symmetric ? 1142 "Invalid symmetric difference expression %s...%s" : 1143 "Invalid revision range %s..%s", 1144 arg, next); 1443 this = head_by_default; 1444 if (this == head_by_default && next == head_by_default && 1445 !symmetric) { 1446 /* 1447 * Just ".."? That is not a range but the 1448 * pathspec for the parent directory. 1449 */ 1450 if (!cant_be_filename) { 1451 *dotdot = '.'; 1452 return -1; 1145 1453 } 1454 } 1455 if (!get_sha1_committish(this, from_sha1) && 1456 !get_sha1_committish(next, sha1)) { 1457 struct object *a_obj, *b_obj; 1146 1458 1147 1459 if (!cant_be_filename) { … … 1150 1462 } 1151 1463 1152 if (symmetric) { 1464 a_obj = parse_object(from_sha1); 1465 b_obj = parse_object(sha1); 1466 if (!a_obj || !b_obj) { 1467 missing: 1468 if (revs->ignore_missing) 1469 return 0; 1470 die(symmetric 1471 ? "Invalid symmetric difference expression %s" 1472 : "Invalid revision range %s", arg); 1473 } 1474 1475 if (!symmetric) { 1476 /* just A..B */ 1477 a_flags = flags_exclude; 1478 } else { 1479 /* A...B -- find merge bases between the two */ 1480 struct commit *a, *b; 1481 struct commit_list *exclude; 1482 1483 a = (a_obj->type == OBJ_COMMIT 1484 ? (struct commit *)a_obj 1485 : lookup_commit_reference(a_obj->sha1)); 1486 b = (b_obj->type == OBJ_COMMIT 1487 ? (struct commit *)b_obj 1488 : lookup_commit_reference(b_obj->sha1)); 1489 if (!a || !b) 1490 goto missing; 1153 1491 exclude = get_merge_bases(a, b, 1); 1492 add_rev_cmdline_list(revs, exclude, 1493 REV_CMD_MERGE_BASE, 1494 flags_exclude); 1154 1495 add_pending_commit_list(revs, exclude, 1155 1496 flags_exclude); 1156 1497 free_commit_list(exclude); 1498 1157 1499 a_flags = flags | SYMMETRIC_LEFT; 1158 } else1159 a_flags = flags_exclude; 1160 a ->object.flags |= a_flags;1161 b ->object.flags |= flags;1162 add_rev_cmdline(revs, &a->object, this,1500 } 1501 1502 a_obj->flags |= a_flags; 1503 b_obj->flags |= flags; 1504 add_rev_cmdline(revs, a_obj, this, 1163 1505 REV_CMD_LEFT, a_flags); 1164 add_rev_cmdline(revs, &b->object, next,1506 add_rev_cmdline(revs, b_obj, next, 1165 1507 REV_CMD_RIGHT, flags); 1166 add_pending_object(revs, &a->object, this);1167 add_pending_object(revs, &b->object, next);1508 add_pending_object(revs, a_obj, this); 1509 add_pending_object(revs, b_obj, next); 1168 1510 return 0; 1169 1511 } … … 1180 1522 if (dotdot && !dotdot[2]) { 1181 1523 *dotdot = 0; 1182 if (!add_parents_only(revs, arg, flags ^ UNINTERESTING))1524 if (!add_parents_only(revs, arg, flags ^ (UNINTERESTING | BOTTOM))) 1183 1525 *dotdot = '^'; 1184 1526 } … … 1186 1528 local_flags = 0; 1187 1529 if (*arg == '^') { 1188 local_flags = UNINTERESTING ;1530 local_flags = UNINTERESTING | BOTTOM; 1189 1531 arg++; 1190 1532 } 1191 if (get_sha1_with_mode(arg, sha1, &mode)) 1533 1534 if (revarg_opt & REVARG_COMMITTISH) 1535 get_sha1_flags = GET_SHA1_COMMITTISH; 1536 1537 if (get_sha1_with_context(arg, get_sha1_flags, sha1, &oc)) 1192 1538 return revs->ignore_missing ? 0 : -1; 1193 1539 if (!cant_be_filename) … … 1195 1541 object = get_reference(revs, arg, sha1, flags ^ local_flags); 1196 1542 add_rev_cmdline(revs, object, arg_, REV_CMD_REV, flags ^ local_flags); 1197 add_pending_object_with_mode(revs, object, arg, mode);1543 add_pending_object_with_mode(revs, object, arg, oc.mode); 1198 1544 return 0; 1199 1545 } … … 1208 1554 { 1209 1555 while (*av) { 1210 ALLOC_GROW(prune->path, prune->nr +1, prune->alloc);1556 ALLOC_GROW(prune->path, prune->nr + 1, prune->alloc); 1211 1557 prune->path[prune->nr++] = *(av++); 1212 1558 } … … 1220 1566 if (len && sb->buf[len - 1] == '\n') 1221 1567 sb->buf[--len] = '\0'; 1222 ALLOC_GROW(prune->path, prune->nr +1, prune->alloc);1568 ALLOC_GROW(prune->path, prune->nr + 1, prune->alloc); 1223 1569 prune->path[prune->nr++] = xstrdup(sb->buf); 1224 1570 } … … 1230 1576 struct strbuf sb; 1231 1577 int seen_dashdash = 0; 1578 int save_warning; 1579 1580 save_warning = warn_on_object_refname_ambiguity; 1581 warn_on_object_refname_ambiguity = 0; 1232 1582 1233 1583 strbuf_init(&sb, 1000); … … 1245 1595 die("options not supported in --stdin mode"); 1246 1596 } 1247 if (handle_revision_arg(sb.buf, revs, 0, 1)) 1597 if (handle_revision_arg(sb.buf, revs, 0, 1598 REVARG_CANNOT_BE_FILENAME)) 1248 1599 die("bad revision '%s'", sb.buf); 1249 1600 } 1250 1601 if (seen_dashdash) 1251 1602 read_pathspec_from_stdin(revs, &sb, prune); 1603 1252 1604 strbuf_release(&sb); 1605 warn_on_object_refname_ambiguity = save_warning; 1253 1606 } 1254 1607 … … 1280 1633 !strcmp(arg, "--reflog") || !strcmp(arg, "--not") || 1281 1634 !strcmp(arg, "--no-walk") || !strcmp(arg, "--do-walk") || 1282 !strcmp(arg, "--bisect") || !prefixcmp(arg, "--glob=") ||1283 !prefixcmp(arg, "--branches=") || !prefixcmp(arg, "--tags=") ||1284 !prefixcmp(arg, "--remotes="))1635 !strcmp(arg, "--bisect") || starts_with(arg, "--glob=") || 1636 starts_with(arg, "--branches=") || starts_with(arg, "--tags=") || 1637 starts_with(arg, "--remotes=") || starts_with(arg, "--no-walk=")) 1285 1638 { 1286 1639 unkv[(*unkc)++] = arg; … … 1305 1658 revs->no_walk = 0; 1306 1659 return 2; 1307 } else if ( !prefixcmp(arg, "-n")) {1660 } else if (starts_with(arg, "-n")) { 1308 1661 revs->max_count = atoi(arg + 2); 1309 1662 revs->no_walk = 0; … … 1342 1695 revs->show_merge = 1; 1343 1696 } else if (!strcmp(arg, "--topo-order")) { 1344 revs-> lifo = 1;1697 revs->sort_order = REV_SORT_IN_GRAPH_ORDER; 1345 1698 revs->topo_order = 1; 1346 1699 } else if (!strcmp(arg, "--simplify-merges")) { 1347 1700 revs->simplify_merges = 1; 1701 revs->topo_order = 1; 1348 1702 revs->rewrite_parents = 1; 1349 1703 revs->simplify_history = 0; … … 1351 1705 } else if (!strcmp(arg, "--simplify-by-decoration")) { 1352 1706 revs->simplify_merges = 1; 1707 revs->topo_order = 1; 1353 1708 revs->rewrite_parents = 1; 1354 1709 revs->simplify_history = 0; … … 1358 1713 load_ref_decorations(DECORATE_SHORT_REFS); 1359 1714 } else if (!strcmp(arg, "--date-order")) { 1360 revs-> lifo = 0;1715 revs->sort_order = REV_SORT_BY_COMMIT_DATE; 1361 1716 revs->topo_order = 1; 1362 } else if (!prefixcmp(arg, "--early-output")) { 1717 } else if (!strcmp(arg, "--author-date-order")) { 1718 revs->sort_order = REV_SORT_BY_AUTHOR_DATE; 1719 revs->topo_order = 1; 1720 } else if (starts_with(arg, "--early-output")) { 1363 1721 int count = 100; 1364 1722 switch (arg[14]) { … … 1385 1743 } else if (!strcmp(arg, "--no-merges")) { 1386 1744 revs->max_parents = 1; 1387 } else if ( !prefixcmp(arg, "--min-parents=")) {1745 } else if (starts_with(arg, "--min-parents=")) { 1388 1746 revs->min_parents = atoi(arg+14); 1389 } else if ( !prefixcmp(arg, "--no-min-parents")) {1747 } else if (starts_with(arg, "--no-min-parents")) { 1390 1748 revs->min_parents = 0; 1391 } else if ( !prefixcmp(arg, "--max-parents=")) {1749 } else if (starts_with(arg, "--max-parents=")) { 1392 1750 revs->max_parents = atoi(arg+14); 1393 } else if ( !prefixcmp(arg, "--no-max-parents")) {1751 } else if (starts_with(arg, "--no-max-parents")) { 1394 1752 revs->max_parents = -1; 1395 1753 } else if (!strcmp(arg, "--boundary")) { … … 1441 1799 } else if (!strcmp(arg, "--unpacked")) { 1442 1800 revs->unpacked = 1; 1443 } else if ( !prefixcmp(arg, "--unpacked=")) {1801 } else if (starts_with(arg, "--unpacked=")) { 1444 1802 die("--unpacked=<packfile> no longer supported."); 1445 1803 } else if (!strcmp(arg, "-r")) { … … 1466 1824 revs->pretty_given = 1; 1467 1825 get_commit_format(arg+8, revs); 1468 } else if ( !prefixcmp(arg, "--pretty=") || !prefixcmp(arg, "--format=")) {1826 } else if (starts_with(arg, "--pretty=") || starts_with(arg, "--format=")) { 1469 1827 /* 1470 1828 * Detached form ("--pretty X" as opposed to "--pretty=X") … … 1480 1838 } else if (!strcmp(arg, "--show-signature")) { 1481 1839 revs->show_signature = 1; 1482 } else if (!prefixcmp(arg, "--show-notes=") || 1483 !prefixcmp(arg, "--notes=")) { 1840 } else if (!strcmp(arg, "--show-linear-break") || 1841 starts_with(arg, "--show-linear-break=")) { 1842 if (starts_with(arg, "--show-linear-break=")) 1843 revs->break_bar = xstrdup(arg + 20); 1844 else 1845 revs->break_bar = " .........."; 1846 revs->track_linear = 1; 1847 revs->track_first_time = 1; 1848 } else if (starts_with(arg, "--show-notes=") || 1849 starts_with(arg, "--notes=")) { 1484 1850 struct strbuf buf = STRBUF_INIT; 1485 1851 revs->show_notes = 1; 1486 1852 revs->show_notes_given = 1; 1487 if ( !prefixcmp(arg, "--show-notes")) {1853 if (starts_with(arg, "--show-notes")) { 1488 1854 if (revs->notes_opt.use_default_notes < 0) 1489 1855 revs->notes_opt.use_default_notes = 1; … … 1528 1894 } else if (!strcmp(arg, "--abbrev")) { 1529 1895 revs->abbrev = DEFAULT_ABBREV; 1530 } else if ( !prefixcmp(arg, "--abbrev=")) {1896 } else if (starts_with(arg, "--abbrev=")) { 1531 1897 revs->abbrev = strtoul(arg + 9, NULL, 10); 1532 1898 if (revs->abbrev < MINIMUM_ABBREV) … … 1563 1929 add_header_grep(revs, GREP_HEADER_COMMITTER, optarg); 1564 1930 return argcount; 1931 } else if ((argcount = parse_long_opt("grep-reflog", argv, &optarg))) { 1932 add_header_grep(revs, GREP_HEADER_REFLOG, optarg); 1933 return argcount; 1565 1934 } else if ((argcount = parse_long_opt("grep", argv, &optarg))) { 1566 1935 add_message_grep(revs, optarg); 1567 1936 return argcount; 1937 } else if (!strcmp(arg, "--grep-debug")) { 1938 revs->grep_filter.debug = 1; 1939 } else if (!strcmp(arg, "--basic-regexp")) { 1940 grep_set_pattern_type_option(GREP_PATTERN_TYPE_BRE, &revs->grep_filter); 1568 1941 } else if (!strcmp(arg, "--extended-regexp") || !strcmp(arg, "-E")) { 1569 revs->grep_filter.regflags |= REG_EXTENDED;1942 grep_set_pattern_type_option(GREP_PATTERN_TYPE_ERE, &revs->grep_filter); 1570 1943 } else if (!strcmp(arg, "--regexp-ignore-case") || !strcmp(arg, "-i")) { 1571 1944 revs->grep_filter.regflags |= REG_ICASE; 1945 DIFF_OPT_SET(&revs->diffopt, PICKAXE_IGNORE_CASE); 1572 1946 } else if (!strcmp(arg, "--fixed-strings") || !strcmp(arg, "-F")) { 1573 revs->grep_filter.fixed = 1; 1947 grep_set_pattern_type_option(GREP_PATTERN_TYPE_FIXED, &revs->grep_filter); 1948 } else if (!strcmp(arg, "--perl-regexp")) { 1949 grep_set_pattern_type_option(GREP_PATTERN_TYPE_PCRE, &revs->grep_filter); 1574 1950 } else if (!strcmp(arg, "--all-match")) { 1575 1951 revs->grep_filter.all_match = 1; … … 1593 1969 return opts; 1594 1970 } 1971 if (revs->graph && revs->track_linear) 1972 die("--show-linear-break and --graph are incompatible"); 1595 1973 1596 1974 return 1; … … 1642 2020 handle_refs(submodule, revs, *flags, for_each_ref_submodule); 1643 2021 handle_refs(submodule, revs, *flags, head_ref_submodule); 2022 clear_ref_exclusion(&revs->ref_excludes); 1644 2023 } else if (!strcmp(arg, "--branches")) { 1645 2024 handle_refs(submodule, revs, *flags, for_each_branch_ref_submodule); 2025 clear_ref_exclusion(&revs->ref_excludes); 1646 2026 } else if (!strcmp(arg, "--bisect")) { 1647 2027 handle_refs(submodule, revs, *flags, for_each_bad_bisect_ref); 1648 handle_refs(submodule, revs, *flags ^ UNINTERESTING, for_each_good_bisect_ref);2028 handle_refs(submodule, revs, *flags ^ (UNINTERESTING | BOTTOM), for_each_good_bisect_ref); 1649 2029 revs->bisect = 1; 1650 2030 } else if (!strcmp(arg, "--tags")) { 1651 2031 handle_refs(submodule, revs, *flags, for_each_tag_ref_submodule); 2032 clear_ref_exclusion(&revs->ref_excludes); 1652 2033 } else if (!strcmp(arg, "--remotes")) { 1653 2034 handle_refs(submodule, revs, *flags, for_each_remote_ref_submodule); 2035 clear_ref_exclusion(&revs->ref_excludes); 1654 2036 } else if ((argcount = parse_long_opt("glob", argv, &optarg))) { 1655 2037 struct all_refs_cb cb; 1656 2038 init_all_refs_cb(&cb, revs, *flags); 1657 2039 for_each_glob_ref(handle_one_ref, optarg, &cb); 2040 clear_ref_exclusion(&revs->ref_excludes); 1658 2041 return argcount; 1659 } else if (!prefixcmp(arg, "--branches=")) { 2042 } else if ((argcount = parse_long_opt("exclude", argv, &optarg))) { 2043 add_ref_exclusion(&revs->ref_excludes, optarg); 2044 return argcount; 2045 } else if (starts_with(arg, "--branches=")) { 1660 2046 struct all_refs_cb cb; 1661 2047 init_all_refs_cb(&cb, revs, *flags); 1662 2048 for_each_glob_ref_in(handle_one_ref, arg + 11, "refs/heads/", &cb); 1663 } else if (!prefixcmp(arg, "--tags=")) { 2049 clear_ref_exclusion(&revs->ref_excludes); 2050 } else if (starts_with(arg, "--tags=")) { 1664 2051 struct all_refs_cb cb; 1665 2052 init_all_refs_cb(&cb, revs, *flags); 1666 2053 for_each_glob_ref_in(handle_one_ref, arg + 7, "refs/tags/", &cb); 1667 } else if (!prefixcmp(arg, "--remotes=")) { 2054 clear_ref_exclusion(&revs->ref_excludes); 2055 } else if (starts_with(arg, "--remotes=")) { 1668 2056 struct all_refs_cb cb; 1669 2057 init_all_refs_cb(&cb, revs, *flags); 1670 2058 for_each_glob_ref_in(handle_one_ref, arg + 10, "refs/remotes/", &cb); 2059 clear_ref_exclusion(&revs->ref_excludes); 1671 2060 } else if (!strcmp(arg, "--reflog")) { 1672 2061 handle_reflog(revs, *flags); 1673 2062 } else if (!strcmp(arg, "--not")) { 1674 *flags ^= UNINTERESTING ;2063 *flags ^= UNINTERESTING | BOTTOM; 1675 2064 } else if (!strcmp(arg, "--no-walk")) { 1676 revs->no_walk = 1; 2065 revs->no_walk = REVISION_WALK_NO_WALK_SORTED; 2066 } else if (starts_with(arg, "--no-walk=")) { 2067 /* 2068 * Detached form ("--no-walk X" as opposed to "--no-walk=X") 2069 * not allowed, since the argument is optional. 2070 */ 2071 if (!strcmp(arg + 10, "sorted")) 2072 revs->no_walk = REVISION_WALK_NO_WALK_SORTED; 2073 else if (!strcmp(arg + 10, "unsorted")) 2074 revs->no_walk = REVISION_WALK_NO_WALK_UNSORTED; 2075 else 2076 return error("invalid argument to --no-walk"); 1677 2077 } else if (!strcmp(arg, "--do-walk")) { 1678 2078 revs->no_walk = 0; … … 1693 2093 int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct setup_revision_opt *opt) 1694 2094 { 1695 int i, flags, left, seen_dashdash, read_from_stdin, got_rev_arg = 0 ;2095 int i, flags, left, seen_dashdash, read_from_stdin, got_rev_arg = 0, revarg_opt; 1696 2096 struct cmdline_pathspec prune_data; 1697 2097 const char *submodule = NULL; … … 1702 2102 1703 2103 /* First, search for "--" */ 1704 seen_dashdash = 0; 1705 for (i = 1; i < argc; i++) { 1706 const char *arg = argv[i]; 1707 if (strcmp(arg, "--")) 1708 continue; 1709 argv[i] = NULL; 1710 argc = i; 1711 if (argv[i + 1]) 1712 append_prune_data(&prune_data, argv + i + 1); 2104 if (opt && opt->assume_dashdash) { 1713 2105 seen_dashdash = 1; 1714 break; 2106 } else { 2107 seen_dashdash = 0; 2108 for (i = 1; i < argc; i++) { 2109 const char *arg = argv[i]; 2110 if (strcmp(arg, "--")) 2111 continue; 2112 argv[i] = NULL; 2113 argc = i; 2114 if (argv[i + 1]) 2115 append_prune_data(&prune_data, argv + i + 1); 2116 seen_dashdash = 1; 2117 break; 2118 } 1715 2119 } 1716 2120 1717 2121 /* Second, deal with arguments and options */ 1718 2122 flags = 0; 2123 revarg_opt = opt ? opt->revarg_opt : 0; 2124 if (seen_dashdash) 2125 revarg_opt |= REVARG_CANNOT_BE_FILENAME; 1719 2126 read_from_stdin = 0; 1720 2127 for (left = i = 1; i < argc; i++) { … … 1752 2159 } 1753 2160 1754 if (handle_revision_arg(arg, revs, flags, seen_dashdash)) { 2161 2162 if (handle_revision_arg(arg, revs, flags, revarg_opt)) { 1755 2163 int j; 1756 2164 if (seen_dashdash || *arg == '^') … … 1764 2172 */ 1765 2173 for (j = i; j < argc; j++) 1766 verify_filename(revs->prefix, argv[j] );2174 verify_filename(revs->prefix, argv[j], j == i); 1767 2175 1768 2176 append_prune_data(&prune_data, argv + i); … … 1788 2196 * } 1789 2197 */ 1790 ALLOC_GROW(prune_data.path, prune_data.nr +1, prune_data.alloc);2198 ALLOC_GROW(prune_data.path, prune_data.nr + 1, prune_data.alloc); 1791 2199 prune_data.path[prune_data.nr++] = NULL; 1792 init_pathspec(&revs->prune_data,1793 get_pathspec(revs->prefix, prune_data.path));2200 parse_pathspec(&revs->prune_data, 0, 0, 2201 revs->prefix, prune_data.path); 1794 2202 } 1795 2203 … … 1803 2211 unsigned char sha1[20]; 1804 2212 struct object *object; 1805 unsigned mode;1806 if (get_sha1_with_ mode(revs->def, sha1, &mode))2213 struct object_context oc; 2214 if (get_sha1_with_context(revs->def, 0, sha1, &oc)) 1807 2215 die("bad default revision '%s'", revs->def); 1808 2216 object = get_reference(revs, revs->def, sha1, 0); 1809 add_pending_object_with_mode(revs, object, revs->def, mode);2217 add_pending_object_with_mode(revs, object, revs->def, oc.mode); 1810 2218 } 1811 2219 … … 1824 2232 1825 2233 if (revs->prune_data.nr) { 1826 diff_tree_setup_paths(revs->prune_data.raw, &revs->pruning);2234 copy_pathspec(&revs->pruning.pathspec, &revs->prune_data); 1827 2235 /* Can't prune commits with rename following: the paths change.. */ 1828 2236 if (!DIFF_OPT_TST(&revs->diffopt, FOLLOW_RENAMES)) 1829 2237 revs->prune = 1; 1830 2238 if (!revs->full_diff) 1831 diff_tree_setup_paths(revs->prune_data.raw, &revs->diffopt); 2239 copy_pathspec(&revs->diffopt.pathspec, 2240 &revs->prune_data); 1832 2241 } 1833 2242 if (revs->combine_merges) 1834 2243 revs->ignore_merges = 0; 1835 2244 revs->diffopt.abbrev = revs->abbrev; 1836 if (diff_setup_done(&revs->diffopt) < 0) 1837 die("diff_setup_done failed"); 1838 2245 2246 if (revs->line_level_traverse) { 2247 revs->limited = 1; 2248 revs->topo_order = 1; 2249 } 2250 2251 diff_setup_done(&revs->diffopt); 2252 2253 grep_commit_pattern_type(GREP_PATTERN_TYPE_UNSPECIFIED, 2254 &revs->grep_filter); 1839 2255 compile_grep_patterns(&revs->grep_filter); 1840 2256 … … 1852 2268 if (revs->reflog_info && revs->graph) 1853 2269 die("cannot combine --walk-reflogs with --graph"); 2270 if (!revs->reflog_info && revs->grep_filter.use_reflog_filter) 2271 die("cannot use --grep-reflog without --walk-reflogs"); 1854 2272 1855 2273 return left; … … 1864 2282 } 1865 2283 1866 static int remove_duplicate_parents(struct commit *commit) 1867 { 2284 static int remove_duplicate_parents(struct rev_info *revs, struct commit *commit) 2285 { 2286 struct treesame_state *ts = lookup_decoration(&revs->treesame, &commit->object); 1868 2287 struct commit_list **pp, *p; 1869 2288 int surviving_parents; … … 1871 2290 /* Examine existing parents while marking ones we have seen... */ 1872 2291 pp = &commit->parents; 2292 surviving_parents = 0; 1873 2293 while ((p = *pp) != NULL) { 1874 2294 struct commit *parent = p->item; 1875 2295 if (parent->object.flags & TMP_MARK) { 1876 2296 *pp = p->next; 2297 if (ts) 2298 compact_treesame(revs, commit, surviving_parents); 1877 2299 continue; 1878 2300 } 1879 2301 parent->object.flags |= TMP_MARK; 2302 surviving_parents++; 1880 2303 pp = &p->next; 1881 2304 } 1882 /* count them while clearing the temporary mark */ 1883 surviving_parents = 0; 2305 /* clear the temporary mark */ 1884 2306 for (p = commit->parents; p; p = p->next) { 1885 2307 p->item->object.flags &= ~TMP_MARK; 1886 surviving_parents++;1887 }2308 } 2309 /* no update_treesame() - removing duplicates can't affect TREESAME */ 1888 2310 return surviving_parents; 1889 2311 } … … 1905 2327 } 1906 2328 2329 static int mark_redundant_parents(struct rev_info *revs, struct commit *commit) 2330 { 2331 struct commit_list *h = reduce_heads(commit->parents); 2332 int i = 0, marked = 0; 2333 struct commit_list *po, *pn; 2334 2335 /* Want these for sanity-checking only */ 2336 int orig_cnt = commit_list_count(commit->parents); 2337 int cnt = commit_list_count(h); 2338 2339 /* 2340 * Not ready to remove items yet, just mark them for now, based 2341 * on the output of reduce_heads(). reduce_heads outputs the reduced 2342 * set in its original order, so this isn't too hard. 2343 */ 2344 po = commit->parents; 2345 pn = h; 2346 while (po) { 2347 if (pn && po->item == pn->item) { 2348 pn = pn->next; 2349 i++; 2350 } else { 2351 po->item->object.flags |= TMP_MARK; 2352 marked++; 2353 } 2354 po=po->next; 2355 } 2356 2357 if (i != cnt || cnt+marked != orig_cnt) 2358 die("mark_redundant_parents %d %d %d %d", orig_cnt, cnt, i, marked); 2359 2360 free_commit_list(h); 2361 2362 return marked; 2363 } 2364 2365 static int mark_treesame_root_parents(struct rev_info *revs, struct commit *commit) 2366 { 2367 struct commit_list *p; 2368 int marked = 0; 2369 2370 for (p = commit->parents; p; p = p->next) { 2371 struct commit *parent = p->item; 2372 if (!parent->parents && (parent->object.flags & TREESAME)) { 2373 parent->object.flags |= TMP_MARK; 2374 marked++; 2375 } 2376 } 2377 2378 return marked; 2379 } 2380 2381 /* 2382 * Awkward naming - this means one parent we are TREESAME to. 2383 * cf mark_treesame_root_parents: root parents that are TREESAME (to an 2384 * empty tree). Better name suggestions? 2385 */ 2386 static int leave_one_treesame_to_parent(struct rev_info *revs, struct commit *commit) 2387 { 2388 struct treesame_state *ts = lookup_decoration(&revs->treesame, &commit->object); 2389 struct commit *unmarked = NULL, *marked = NULL; 2390 struct commit_list *p; 2391 unsigned n; 2392 2393 for (p = commit->parents, n = 0; p; p = p->next, n++) { 2394 if (ts->treesame[n]) { 2395 if (p->item->object.flags & TMP_MARK) { 2396 if (!marked) 2397 marked = p->item; 2398 } else { 2399 if (!unmarked) { 2400 unmarked = p->item; 2401 break; 2402 } 2403 } 2404 } 2405 } 2406 2407 /* 2408 * If we are TREESAME to a marked-for-deletion parent, but not to any 2409 * unmarked parents, unmark the first TREESAME parent. This is the 2410 * parent that the default simplify_history==1 scan would have followed, 2411 * and it doesn't make sense to omit that path when asking for a 2412 * simplified full history. Retaining it improves the chances of 2413 * understanding odd missed merges that took an old version of a file. 2414 * 2415 * Example: 2416 * 2417 * I--------*X A modified the file, but mainline merge X used 2418 * \ / "-s ours", so took the version from I. X is 2419 * `-*A--' TREESAME to I and !TREESAME to A. 2420 * 2421 * Default log from X would produce "I". Without this check, 2422 * --full-history --simplify-merges would produce "I-A-X", showing 2423 * the merge commit X and that it changed A, but not making clear that 2424 * it had just taken the I version. With this check, the topology above 2425 * is retained. 2426 * 2427 * Note that it is possible that the simplification chooses a different 2428 * TREESAME parent from the default, in which case this test doesn't 2429 * activate, and we _do_ drop the default parent. Example: 2430 * 2431 * I------X A modified the file, but it was reverted in B, 2432 * \ / meaning mainline merge X is TREESAME to both 2433 * *A-*B parents. 2434 * 2435 * Default log would produce "I" by following the first parent; 2436 * --full-history --simplify-merges will produce "I-A-B". But this is a 2437 * reasonable result - it presents a logical full history leading from 2438 * I to X, and X is not an important merge. 2439 */ 2440 if (!unmarked && marked) { 2441 marked->object.flags &= ~TMP_MARK; 2442 return 1; 2443 } 2444 2445 return 0; 2446 } 2447 2448 static int remove_marked_parents(struct rev_info *revs, struct commit *commit) 2449 { 2450 struct commit_list **pp, *p; 2451 int nth_parent, removed = 0; 2452 2453 pp = &commit->parents; 2454 nth_parent = 0; 2455 while ((p = *pp) != NULL) { 2456 struct commit *parent = p->item; 2457 if (parent->object.flags & TMP_MARK) { 2458 parent->object.flags &= ~TMP_MARK; 2459 *pp = p->next; 2460 free(p); 2461 removed++; 2462 compact_treesame(revs, commit, nth_parent); 2463 continue; 2464 } 2465 pp = &p->next; 2466 nth_parent++; 2467 } 2468 2469 /* Removing parents can only increase TREESAMEness */ 2470 if (removed && !(commit->object.flags & TREESAME)) 2471 update_treesame(revs, commit); 2472 2473 return nth_parent; 2474 } 2475 1907 2476 static struct commit_list **simplify_one(struct rev_info *revs, struct commit *commit, struct commit_list **tail) 1908 2477 { 1909 2478 struct commit_list *p; 2479 struct commit *parent; 1910 2480 struct merge_simplify_state *st, *pst; 1911 2481 int cnt; … … 1930 2500 1931 2501 /* 1932 * Do we know what commit all of our parents should be rewritten to? 1933 * Otherwise we are not ready to rewrite this one yet. 2502 * Do we know what commit all of our parents that matter 2503 * should be rewritten to? Otherwise we are not ready to 2504 * rewrite this one yet. 1934 2505 */ 1935 2506 for (cnt = 0, p = commit->parents; p; p = p->next) { … … 1939 2510 cnt++; 1940 2511 } 2512 if (revs->first_parent_only) 2513 break; 1941 2514 } 1942 2515 if (cnt) { … … 1946 2519 1947 2520 /* 1948 * Rewrite our list of parents. 2521 * Rewrite our list of parents. Note that this cannot 2522 * affect our TREESAME flags in any way - a commit is 2523 * always TREESAME to its simplification. 1949 2524 */ 1950 2525 for (p = commit->parents; p; p = p->next) { 1951 2526 pst = locate_simplify_state(revs, p->item); 1952 2527 p->item = pst->simplified; 1953 } 1954 cnt = remove_duplicate_parents(commit); 2528 if (revs->first_parent_only) 2529 break; 2530 } 2531 2532 if (revs->first_parent_only) 2533 cnt = 1; 2534 else 2535 cnt = remove_duplicate_parents(revs, commit); 1955 2536 1956 2537 /* 1957 2538 * It is possible that we are a merge and one side branch 1958 2539 * does not have any commit that touches the given paths; 1959 * in such a case, the immediate parent s will be rewritten1960 * to different commits.2540 * in such a case, the immediate parent from that branch 2541 * will be rewritten to be the merge base. 1961 2542 * 1962 2543 * o----X X: the commit we are looking at; … … 1964 2545 * ---o----' 1965 2546 * 1966 * Further reduce the parents by removing redundant parents. 2547 * Further, a merge of an independent branch that doesn't 2548 * touch the path will reduce to a treesame root parent: 2549 * 2550 * ----o----X X: the commit we are looking at; 2551 * / o: a commit that touches the paths; 2552 * r r: a root commit not touching the paths 2553 * 2554 * Detect and simplify both cases. 1967 2555 */ 1968 2556 if (1 < cnt) { 1969 struct commit_list *h = reduce_heads(commit->parents); 1970 cnt = commit_list_count(h); 1971 free_commit_list(commit->parents); 1972 commit->parents = h; 2557 int marked = mark_redundant_parents(revs, commit); 2558 marked += mark_treesame_root_parents(revs, commit); 2559 if (marked) 2560 marked -= leave_one_treesame_to_parent(revs, commit); 2561 if (marked) 2562 cnt = remove_marked_parents(revs, commit); 1973 2563 } 1974 2564 … … 1976 2566 * A commit simplifies to itself if it is a root, if it is 1977 2567 * UNINTERESTING, if it touches the given paths, or if it is a 1978 * merge and its parents simplifies to more than one commits2568 * merge and its parents don't simplify to one relevant commit 1979 2569 * (the first two cases are already handled at the beginning of 1980 2570 * this function). 1981 2571 * 1982 * Otherwise, it simplifies to what its sole parent simplifies to. 2572 * Otherwise, it simplifies to what its sole relevant parent 2573 * simplifies to. 1983 2574 */ 1984 2575 if (!cnt || 1985 2576 (commit->object.flags & UNINTERESTING) || 1986 2577 !(commit->object.flags & TREESAME) || 1987 ( 1 < cnt))2578 (parent = one_relevant_parent(revs, commit->parents)) == NULL) 1988 2579 st->simplified = commit; 1989 2580 else { 1990 pst = locate_simplify_state(revs, commit->parents->item);2581 pst = locate_simplify_state(revs, parent); 1991 2582 st->simplified = pst->simplified; 1992 2583 } … … 1996 2587 static void simplify_merges(struct rev_info *revs) 1997 2588 { 1998 struct commit_list *list ;2589 struct commit_list *list, *next; 1999 2590 struct commit_list *yet_to_do, **tail; 2000 2001 if (!revs->topo_order) 2002 sort_in_topological_order(&revs->commits, revs->lifo); 2591 struct commit *commit; 2592 2003 2593 if (!revs->prune) 2004 2594 return; … … 2006 2596 /* feed the list reversed */ 2007 2597 yet_to_do = NULL; 2008 for (list = revs->commits; list; list = list->next) 2009 commit_list_insert(list->item, &yet_to_do); 2598 for (list = revs->commits; list; list = next) { 2599 commit = list->item; 2600 next = list->next; 2601 /* 2602 * Do not free(list) here yet; the original list 2603 * is used later in this function. 2604 */ 2605 commit_list_insert(commit, &yet_to_do); 2606 } 2010 2607 while (yet_to_do) { 2011 2608 list = yet_to_do; … … 2013 2610 tail = &yet_to_do; 2014 2611 while (list) { 2015 struct commit *commit = list->item;2016 struct commit_list *next = list->next;2612 commit = list->item; 2613 next = list->next; 2017 2614 free(list); 2018 2615 list = next; … … 2026 2623 tail = &revs->commits; 2027 2624 while (list) { 2028 struct commit *commit = list->item;2029 struct commit_list *next = list->next;2030 2625 struct merge_simplify_state *st; 2626 2627 commit = list->item; 2628 next = list->next; 2031 2629 free(list); 2032 2630 list = next; … … 2049 2647 } 2050 2648 2649 void reset_revision_walk(void) 2650 { 2651 clear_object_flags(SEEN | ADDED | SHOWN); 2652 } 2653 2051 2654 int prepare_revision_walk(struct rev_info *revs) 2052 2655 { 2053 2656 int nr = revs->pending.nr; 2054 2657 struct object_array_entry *e, *list; 2658 struct commit_list **next = &revs->commits; 2055 2659 2056 2660 e = list = revs->pending.objects; … … 2063 2667 if (!(commit->object.flags & SEEN)) { 2064 2668 commit->object.flags |= SEEN; 2065 commit_list_insert_by_date(commit, &revs->commits);2669 next = commit_list_append(commit, next); 2066 2670 } 2067 2671 } … … 2071 2675 free(list); 2072 2676 2677 /* Signal whether we need per-parent treesame decoration */ 2678 if (revs->simplify_merges || 2679 (revs->limited && limiting_can_increase_treesame(revs))) 2680 revs->treesame.name = "treesame"; 2681 2682 if (revs->no_walk != REVISION_WALK_NO_WALK_UNSORTED) 2683 commit_list_sort_by_date(&revs->commits); 2073 2684 if (revs->no_walk) 2074 2685 return 0; … … 2077 2688 return -1; 2078 2689 if (revs->topo_order) 2079 sort_in_topological_order(&revs->commits, revs->lifo); 2690 sort_in_topological_order(&revs->commits, revs->sort_order); 2691 if (revs->line_level_traverse) 2692 line_log_filter(revs); 2080 2693 if (revs->simplify_merges) 2081 2694 simplify_merges(revs); … … 2085 2698 } 2086 2699 2087 enum rewrite_result {2088 rewrite_one_ok,2089 rewrite_one_noparents,2090 rewrite_one_error2091 };2092 2093 2700 static enum rewrite_result rewrite_one(struct rev_info *revs, struct commit **pp) 2094 2701 { … … 2100 2707 if (add_parents_to_list(revs, p, &revs->commits, &cache) < 0) 2101 2708 return rewrite_one_error; 2102 if (p->parents && p->parents->next)2103 return rewrite_one_ok;2104 2709 if (p->object.flags & UNINTERESTING) 2105 2710 return rewrite_one_ok; … … 2108 2713 if (!p->parents) 2109 2714 return rewrite_one_noparents; 2110 *pp = p->parents->item; 2111 } 2112 } 2113 2114 static int rewrite_parents(struct rev_info *revs, struct commit *commit) 2715 if ((p = one_relevant_parent(revs, p->parents)) == NULL) 2716 return rewrite_one_ok; 2717 *pp = p; 2718 } 2719 } 2720 2721 int rewrite_parents(struct rev_info *revs, struct commit *commit, 2722 rewrite_parent_fn_t rewrite_parent) 2115 2723 { 2116 2724 struct commit_list **pp = &commit->parents; 2117 2725 while (*pp) { 2118 2726 struct commit_list *parent = *pp; 2119 switch (rewrite_ one(revs, &parent->item)) {2727 switch (rewrite_parent(revs, &parent->item)) { 2120 2728 case rewrite_one_ok: 2121 2729 break; … … 2128 2736 pp = &parent->next; 2129 2737 } 2130 remove_duplicate_parents( commit);2738 remove_duplicate_parents(revs, commit); 2131 2739 return 0; 2132 2740 } 2133 2741 2742 static int commit_rewrite_person(struct strbuf *buf, const char *what, struct string_list *mailmap) 2743 { 2744 char *person, *endp; 2745 size_t len, namelen, maillen; 2746 const char *name; 2747 const char *mail; 2748 struct ident_split ident; 2749 2750 person = strstr(buf->buf, what); 2751 if (!person) 2752 return 0; 2753 2754 person += strlen(what); 2755 endp = strchr(person, '\n'); 2756 if (!endp) 2757 return 0; 2758 2759 len = endp - person; 2760 2761 if (split_ident_line(&ident, person, len)) 2762 return 0; 2763 2764 mail = ident.mail_begin; 2765 maillen = ident.mail_end - ident.mail_begin; 2766 name = ident.name_begin; 2767 namelen = ident.name_end - ident.name_begin; 2768 2769 if (map_user(mailmap, &mail, &maillen, &name, &namelen)) { 2770 struct strbuf namemail = STRBUF_INIT; 2771 2772 strbuf_addf(&namemail, "%.*s <%.*s>", 2773 (int)namelen, name, (int)maillen, mail); 2774 2775 strbuf_splice(buf, ident.name_begin - buf->buf, 2776 ident.mail_end - ident.name_begin + 1, 2777 namemail.buf, namemail.len); 2778 2779 strbuf_release(&namemail); 2780 2781 return 1; 2782 } 2783 2784 return 0; 2785 } 2786 2134 2787 static int commit_match(struct commit *commit, struct rev_info *opt) 2135 2788 { 2789 int retval; 2790 const char *encoding; 2791 char *message; 2792 struct strbuf buf = STRBUF_INIT; 2793 2136 2794 if (!opt->grep_filter.pattern_list && !opt->grep_filter.header_list) 2137 2795 return 1; 2138 return grep_buffer(&opt->grep_filter, 2139 commit->buffer, strlen(commit->buffer)); 2140 } 2141 2142 static inline int want_ancestry(struct rev_info *revs) 2796 2797 /* Prepend "fake" headers as needed */ 2798 if (opt->grep_filter.use_reflog_filter) { 2799 strbuf_addstr(&buf, "reflog "); 2800 get_reflog_message(&buf, opt->reflog_info); 2801 strbuf_addch(&buf, '\n'); 2802 } 2803 2804 /* 2805 * We grep in the user's output encoding, under the assumption that it 2806 * is the encoding they are most likely to write their grep pattern 2807 * for. In addition, it means we will match the "notes" encoding below, 2808 * so we will not end up with a buffer that has two different encodings 2809 * in it. 2810 */ 2811 encoding = get_log_output_encoding(); 2812 message = logmsg_reencode(commit, NULL, encoding); 2813 2814 /* Copy the commit to temporary if we are using "fake" headers */ 2815 if (buf.len) 2816 strbuf_addstr(&buf, message); 2817 2818 if (opt->grep_filter.header_list && opt->mailmap) { 2819 if (!buf.len) 2820 strbuf_addstr(&buf, message); 2821 2822 commit_rewrite_person(&buf, "\nauthor ", opt->mailmap); 2823 commit_rewrite_person(&buf, "\ncommitter ", opt->mailmap); 2824 } 2825 2826 /* Append "fake" message parts as needed */ 2827 if (opt->show_notes) { 2828 if (!buf.len) 2829 strbuf_addstr(&buf, message); 2830 format_display_notes(commit->object.sha1, &buf, encoding, 1); 2831 } 2832 2833 /* Find either in the original commit message, or in the temporary */ 2834 if (buf.len) 2835 retval = grep_buffer(&opt->grep_filter, buf.buf, buf.len); 2836 else 2837 retval = grep_buffer(&opt->grep_filter, 2838 message, strlen(message)); 2839 strbuf_release(&buf); 2840 logmsg_free(message, commit); 2841 return retval; 2842 } 2843 2844 static inline int want_ancestry(const struct rev_info *revs) 2143 2845 { 2144 2846 return (revs->rewrite_parents || revs->children.name); … … 2158 2860 return commit_ignore; 2159 2861 if (revs->min_parents || (revs->max_parents >= 0)) { 2160 int n = 0; 2161 struct commit_list *p; 2162 for (p = commit->parents; p; p = p->next) 2163 n++; 2862 int n = commit_list_count(commit->parents); 2164 2863 if ((n < revs->min_parents) || 2165 2864 ((revs->max_parents >= 0) && (n > revs->max_parents))) … … 2171 2870 /* Commit without changes? */ 2172 2871 if (commit->object.flags & TREESAME) { 2872 int n; 2873 struct commit_list *p; 2173 2874 /* drop merges unless we want parenthood */ 2174 2875 if (!want_ancestry(revs)) 2175 2876 return commit_ignore; 2176 /* non-merge - always ignore it */ 2177 if (!commit->parents || !commit->parents->next) 2178 return commit_ignore; 2877 /* 2878 * If we want ancestry, then need to keep any merges 2879 * between relevant commits to tie together topology. 2880 * For consistency with TREESAME and simplification 2881 * use "relevant" here rather than just INTERESTING, 2882 * to treat bottom commit(s) as part of the topology. 2883 */ 2884 for (n = 0, p = commit->parents; p; p = p->next) 2885 if (relevant_commit(p->item)) 2886 if (++n >= 2) 2887 return commit_show; 2888 return commit_ignore; 2179 2889 } 2180 2890 } … … 2189 2899 !revs->show_all && 2190 2900 revs->prune && revs->dense && want_ancestry(revs)) { 2191 if (rewrite_parents(revs, commit) < 0) 2901 /* 2902 * --full-diff on simplified parents is no good: it 2903 * will show spurious changes from the commits that 2904 * were elided. So we save the parents on the side 2905 * when --full-diff is in effect. 2906 */ 2907 if (revs->full_diff) 2908 save_parents(revs, commit); 2909 if (rewrite_parents(revs, commit, rewrite_one) < 0) 2192 2910 return commit_error; 2193 2911 } 2194 2912 return action; 2913 } 2914 2915 static void track_linear(struct rev_info *revs, struct commit *commit) 2916 { 2917 if (revs->track_first_time) { 2918 revs->linear = 1; 2919 revs->track_first_time = 0; 2920 } else { 2921 struct commit_list *p; 2922 for (p = revs->previous_parents; p; p = p->next) 2923 if (p->item == NULL || /* first commit */ 2924 !hashcmp(p->item->object.sha1, commit->object.sha1)) 2925 break; 2926 revs->linear = p != NULL; 2927 } 2928 if (revs->reverse) { 2929 if (revs->linear) 2930 commit->object.flags |= TRACK_LINEAR; 2931 } 2932 free_commit_list(revs->previous_parents); 2933 revs->previous_parents = copy_commit_list(commit->parents); 2195 2934 } 2196 2935 … … 2208 2947 2209 2948 if (revs->reflog_info) { 2949 save_parents(revs, commit); 2210 2950 fake_reflog_parent(revs->reflog_info, commit); 2211 2951 commit->object.flags &= ~(ADDED | SEEN | SHOWN); … … 2221 2961 (commit->date < revs->max_age)) 2222 2962 continue; 2223 if (add_parents_to_list(revs, commit, &revs->commits, NULL) < 0) 2224 die("Failed to traverse parents of commit %s", 2225 sha1_to_hex(commit->object.sha1)); 2963 if (add_parents_to_list(revs, commit, &revs->commits, NULL) < 0) { 2964 if (!revs->ignore_missing_links) 2965 die("Failed to traverse parents of commit %s", 2966 sha1_to_hex(commit->object.sha1)); 2967 } 2226 2968 } 2227 2969 … … 2233 2975 sha1_to_hex(commit->object.sha1)); 2234 2976 default: 2977 if (revs->track_linear) 2978 track_linear(revs, commit); 2235 2979 return commit; 2236 2980 } … … 2239 2983 } 2240 2984 2985 /* 2986 * Return true for entries that have not yet been shown. (This is an 2987 * object_array_each_func_t.) 2988 */ 2989 static int entry_unshown(struct object_array_entry *entry, void *cb_data_unused) 2990 { 2991 return !(entry->item->flags & SHOWN); 2992 } 2993 2994 /* 2995 * If array is on the verge of a realloc, garbage-collect any entries 2996 * that have already been shown to try to free up some space. 2997 */ 2241 2998 static void gc_boundary(struct object_array *array) 2242 2999 { 2243 unsigned nr = array->nr; 2244 unsigned alloc = array->alloc; 2245 struct object_array_entry *objects = array->objects; 2246 2247 if (alloc <= nr) { 2248 unsigned i, j; 2249 for (i = j = 0; i < nr; i++) { 2250 if (objects[i].item->flags & SHOWN) 2251 continue; 2252 if (i != j) 2253 objects[j] = objects[i]; 2254 j++; 2255 } 2256 for (i = j; i < nr; i++) 2257 objects[i].item = NULL; 2258 array->nr = j; 2259 } 3000 if (array->nr == array->alloc) 3001 object_array_filter(array, entry_unshown, NULL); 2260 3002 } 2261 3003 … … 2298 3040 * in topological order 2299 3041 */ 2300 sort_in_topological_order(&revs->commits, revs-> lifo);3042 sort_in_topological_order(&revs->commits, revs->sort_order); 2301 3043 } 2302 3044 … … 2320 3062 2321 3063 /* 2322 * Now pick up what they want to give us 2323 */ 2324 c = get_revision_1(revs); 2325 if (c) { 2326 while (0 < revs->skip_count) { 2327 revs->skip_count--; 2328 c = get_revision_1(revs); 2329 if (!c) 2330 break; 2331 } 2332 } 2333 2334 /* 2335 * Check the max_count. 2336 */ 2337 switch (revs->max_count) { 2338 case -1: 2339 break; 2340 case 0: 2341 c = NULL; 2342 break; 2343 default: 2344 revs->max_count--; 3064 * If our max_count counter has reached zero, then we are done. We 3065 * don't simply return NULL because we still might need to show 3066 * boundary commits. But we want to avoid calling get_revision_1, which 3067 * might do a considerable amount of work finding the next commit only 3068 * for us to throw it away. 3069 * 3070 * If it is non-zero, then either we don't have a max_count at all 3071 * (-1), or it is still counting, in which case we decrement. 3072 */ 3073 if (revs->max_count) { 3074 c = get_revision_1(revs); 3075 if (c) { 3076 while (revs->skip_count > 0) { 3077 revs->skip_count--; 3078 c = get_revision_1(revs); 3079 if (!c) 3080 break; 3081 } 3082 } 3083 3084 if (revs->max_count > 0) 3085 revs->max_count--; 2345 3086 } 2346 3087 … … 2348 3089 c->object.flags |= SHOWN; 2349 3090 2350 if (!revs->boundary) {3091 if (!revs->boundary) 2351 3092 return c; 2352 }2353 3093 2354 3094 if (!c) { … … 2396 3136 if (revs->reverse) { 2397 3137 reversed = NULL; 2398 while ((c = get_revision_internal(revs))) {3138 while ((c = get_revision_internal(revs))) 2399 3139 commit_list_insert(c, &reversed); 2400 }2401 3140 revs->commits = reversed; 2402 3141 revs->reverse = 0; … … 2404 3143 } 2405 3144 2406 if (revs->reverse_output_stage) 2407 return pop_commit(&revs->commits); 3145 if (revs->reverse_output_stage) { 3146 c = pop_commit(&revs->commits); 3147 if (revs->track_linear) 3148 revs->linear = !!(c && c->object.flags & TRACK_LINEAR); 3149 return c; 3150 } 2408 3151 2409 3152 c = get_revision_internal(revs); 2410 3153 if (c && revs->graph) 2411 3154 graph_update(revs->graph, c); 3155 if (!c) { 3156 free_saved_parents(revs); 3157 if (revs->previous_parents) { 3158 free_commit_list(revs->previous_parents); 3159 revs->previous_parents = NULL; 3160 } 3161 } 2412 3162 return c; 2413 3163 } … … 2441 3191 putchar(' '); 2442 3192 } 3193 3194 define_commit_slab(saved_parents, struct commit_list *); 3195 3196 #define EMPTY_PARENT_LIST ((struct commit_list *)-1) 3197 3198 void save_parents(struct rev_info *revs, struct commit *commit) 3199 { 3200 struct commit_list **pp; 3201 3202 if (!revs->saved_parents_slab) { 3203 revs->saved_parents_slab = xmalloc(sizeof(struct saved_parents)); 3204 init_saved_parents(revs->saved_parents_slab); 3205 } 3206 3207 pp = saved_parents_at(revs->saved_parents_slab, commit); 3208 3209 /* 3210 * When walking with reflogs, we may visit the same commit 3211 * several times: once for each appearance in the reflog. 3212 * 3213 * In this case, save_parents() will be called multiple times. 3214 * We want to keep only the first set of parents. We need to 3215 * store a sentinel value for an empty (i.e., NULL) parent 3216 * list to distinguish it from a not-yet-saved list, however. 3217 */ 3218 if (*pp) 3219 return; 3220 if (commit->parents) 3221 *pp = copy_commit_list(commit->parents); 3222 else 3223 *pp = EMPTY_PARENT_LIST; 3224 } 3225 3226 struct commit_list *get_saved_parents(struct rev_info *revs, const struct commit *commit) 3227 { 3228 struct commit_list *parents; 3229 3230 if (!revs->saved_parents_slab) 3231 return commit->parents; 3232 3233 parents = *saved_parents_at(revs->saved_parents_slab, commit); 3234 if (parents == EMPTY_PARENT_LIST) 3235 return NULL; 3236 return parents; 3237 } 3238 3239 void free_saved_parents(struct rev_info *revs) 3240 { 3241 if (revs->saved_parents_slab) 3242 clear_saved_parents(revs->saved_parents_slab); 3243 }
Note:
See TracChangeset
for help on using the changeset viewer.