|
15 | 15 | #include "string-list.h" |
16 | 16 | #include "line-log.h" |
17 | 17 | #include "mailmap.h" |
| 18 | +#include "commit-slab.h" |
18 | 19 |
|
19 | 20 | volatile show_early_output_fn_t show_early_output; |
20 | 21 |
|
@@ -2763,7 +2764,7 @@ static int commit_match(struct commit *commit, struct rev_info *opt) |
2763 | 2764 | return retval; |
2764 | 2765 | } |
2765 | 2766 |
|
2766 | | -static inline int want_ancestry(struct rev_info *revs) |
| 2767 | +static inline int want_ancestry(const struct rev_info *revs) |
2767 | 2768 | { |
2768 | 2769 | return (revs->rewrite_parents || revs->children.name); |
2769 | 2770 | } |
@@ -2820,6 +2821,14 @@ enum commit_action simplify_commit(struct rev_info *revs, struct commit *commit) |
2820 | 2821 | if (action == commit_show && |
2821 | 2822 | !revs->show_all && |
2822 | 2823 | revs->prune && revs->dense && want_ancestry(revs)) { |
| 2824 | + /* |
| 2825 | + * --full-diff on simplified parents is no good: it |
| 2826 | + * will show spurious changes from the commits that |
| 2827 | + * were elided. So we save the parents on the side |
| 2828 | + * when --full-diff is in effect. |
| 2829 | + */ |
| 2830 | + if (revs->full_diff) |
| 2831 | + save_parents(revs, commit); |
2823 | 2832 | if (rewrite_parents(revs, commit, rewrite_one) < 0) |
2824 | 2833 | return commit_error; |
2825 | 2834 | } |
@@ -3038,6 +3047,8 @@ struct commit *get_revision(struct rev_info *revs) |
3038 | 3047 | c = get_revision_internal(revs); |
3039 | 3048 | if (c && revs->graph) |
3040 | 3049 | graph_update(revs->graph, c); |
| 3050 | + if (!c) |
| 3051 | + free_saved_parents(revs); |
3041 | 3052 | return c; |
3042 | 3053 | } |
3043 | 3054 |
|
@@ -3069,3 +3080,33 @@ void put_revision_mark(const struct rev_info *revs, const struct commit *commit) |
3069 | 3080 | fputs(mark, stdout); |
3070 | 3081 | putchar(' '); |
3071 | 3082 | } |
| 3083 | + |
| 3084 | +define_commit_slab(saved_parents, struct commit_list *); |
| 3085 | + |
| 3086 | +void save_parents(struct rev_info *revs, struct commit *commit) |
| 3087 | +{ |
| 3088 | + struct commit_list **pp; |
| 3089 | + |
| 3090 | + if (!revs->saved_parents_slab) { |
| 3091 | + revs->saved_parents_slab = xmalloc(sizeof(struct saved_parents)); |
| 3092 | + init_saved_parents(revs->saved_parents_slab); |
| 3093 | + } |
| 3094 | + |
| 3095 | + pp = saved_parents_at(revs->saved_parents_slab, commit); |
| 3096 | + assert(*pp == NULL); |
| 3097 | + *pp = copy_commit_list(commit->parents); |
| 3098 | +} |
| 3099 | + |
| 3100 | +struct commit_list *get_saved_parents(struct rev_info *revs, const struct commit *commit) |
| 3101 | +{ |
| 3102 | + if (!revs->saved_parents_slab) |
| 3103 | + return commit->parents; |
| 3104 | + |
| 3105 | + return *saved_parents_at(revs->saved_parents_slab, commit); |
| 3106 | +} |
| 3107 | + |
| 3108 | +void free_saved_parents(struct rev_info *revs) |
| 3109 | +{ |
| 3110 | + if (revs->saved_parents_slab) |
| 3111 | + clear_saved_parents(revs->saved_parents_slab); |
| 3112 | +} |
0 commit comments