mirror of
https://github.com/git-for-windows/git.git
synced 2026-06-16 04:07:36 -05:00
Have a repo with a subtree merge, do a 'git log --follow prefix/test.c', the output only contains history in the outer repo, not commits that were merged via a subtree merge. What happens is that 'git log --follow' stores the followed path only in opt->diffopt.pathspec, so in case the commit history is non-linear, and multiple parents have renames to the followed path, then the end result isn't really defined: the first commit that happens to be visited in one of the parents update opt->diffopt.pathspec, and from that point, only that updated path is visited. Fix the problem by introducing a commit -> path map (follow_pathspec_slab) that stores what will be a path to follow when visiting that parent. At the top of log_tree_commit(), if the slab has an entry for this commit, we replace opt->diffopt.pathspec with a path from this entry, so the correct path is followed, even if an unrelated sub-tree changed the path to be followed to something else. After log_tree_diff() runs, we record each parent's path in the slab. As a result, the walk order doesn't matter, which was exactly the source of problems previously. This helps with subtree merges (rename happens inside the merge commit), but also fixes the general case when the rename happens in the history of parents, not in the merge commit itself. Signed-off-by: Miklos Vajna <vmiklos@collabora.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
46 lines
1.4 KiB
C
46 lines
1.4 KiB
C
#ifndef LOG_TREE_H
|
|
#define LOG_TREE_H
|
|
|
|
#include "color.h"
|
|
|
|
struct rev_info;
|
|
|
|
struct log_info {
|
|
struct commit *commit, *parent;
|
|
};
|
|
|
|
struct decoration_filter {
|
|
struct string_list *include_ref_pattern;
|
|
struct string_list *exclude_ref_pattern;
|
|
struct string_list *exclude_ref_config_pattern;
|
|
};
|
|
|
|
struct decoration_options {
|
|
char *prefix;
|
|
char *suffix;
|
|
char *separator;
|
|
char *pointer;
|
|
char *tag;
|
|
};
|
|
|
|
int parse_decorate_color_config(const char *var, const char *slot_name, const char *value);
|
|
int log_tree_diff_flush(struct rev_info *);
|
|
int log_tree_commit(struct rev_info *, struct commit *);
|
|
void release_follow_pathspec_slab(struct rev_info *);
|
|
void show_log(struct rev_info *opt);
|
|
void format_decorations(struct strbuf *sb, const struct commit *commit,
|
|
enum git_colorbool use_color, const struct decoration_options *opts);
|
|
void show_decorations(struct rev_info *opt, struct commit *commit);
|
|
void log_write_email_headers(struct rev_info *opt, struct commit *commit,
|
|
char **extra_headers_p,
|
|
int *need_8bit_cte_p,
|
|
int maybe_multipart);
|
|
void load_ref_decorations(struct decoration_filter *filter, int flags);
|
|
void load_branch_decorations(void);
|
|
|
|
void fmt_output_commit(struct strbuf *, struct commit *, struct rev_info *);
|
|
void fmt_output_subject(struct strbuf *, const char *subject, struct rev_info *);
|
|
void fmt_output_email_subject(struct strbuf *, struct rev_info *);
|
|
|
|
#endif
|