Git fork
at reftables-rust 558 lines 16 kB view raw
1#ifndef REVISION_H 2#define REVISION_H 3 4#include "commit.h" 5#include "grep.h" 6#include "notes.h" 7#include "oidset.h" 8#include "pretty.h" 9#include "diff.h" 10#include "commit-slab-decl.h" 11#include "decorate.h" 12#include "ident.h" 13#include "list-objects-filter-options.h" 14#include "strvec.h" 15 16/** 17 * The revision walking API offers functions to build a list of revisions 18 * and then iterate over that list. 19 * 20 * Calling sequence 21 * ---------------- 22 * 23 * The walking API has a given calling sequence: first you need to initialize 24 * a rev_info structure, then add revisions to control what kind of revision 25 * list do you want to get, finally you can iterate over the revision list. 26 * 27 */ 28 29/* Remember to update object flag allocation in object.h */ 30#define SEEN (1u<<0) 31#define UNINTERESTING (1u<<1) 32#define TREESAME (1u<<2) 33#define SHOWN (1u<<3) 34#define TMP_MARK (1u<<4) /* for isolated cases; clean after use */ 35#define BOUNDARY (1u<<5) 36#define CHILD_SHOWN (1u<<6) 37#define ADDED (1u<<7) /* Parents already parsed and added? */ 38#define SYMMETRIC_LEFT (1u<<8) 39#define PATCHSAME (1u<<9) 40#define BOTTOM (1u<<10) 41 42/* WARNING: This is also used as REACHABLE in commit-graph.c. */ 43#define PULL_MERGE (1u<<15) 44 45#define TOPO_WALK_EXPLORED (1u<<23) 46#define TOPO_WALK_INDEGREE (1u<<24) 47 48/* 49 * Indicates object was reached by traversal. i.e. not given by user on 50 * command-line or stdin. 51 */ 52#define NOT_USER_GIVEN (1u<<25) 53#define TRACK_LINEAR (1u<<26) 54#define ANCESTRY_PATH (1u<<27) 55#define ALL_REV_FLAGS (((1u<<11)-1) | NOT_USER_GIVEN | TRACK_LINEAR | PULL_MERGE) 56 57#define DECORATE_SHORT_REFS 1 58#define DECORATE_FULL_REFS 2 59 60struct log_info; 61struct repository; 62struct rev_info; 63struct string_list; 64struct saved_parents; 65struct bloom_keyvec; 66struct bloom_filter_settings; 67struct option; 68struct parse_opt_ctx_t; 69define_shared_commit_slab(revision_sources, char *); 70 71struct rev_cmdline_info { 72 unsigned int nr; 73 unsigned int alloc; 74 struct rev_cmdline_entry { 75 struct object *item; 76 const char *name; 77 enum { 78 REV_CMD_REF, 79 REV_CMD_PARENTS_ONLY, 80 REV_CMD_LEFT, 81 REV_CMD_RIGHT, 82 REV_CMD_MERGE_BASE, 83 REV_CMD_REV 84 } whence; 85 unsigned flags; 86 } *rev; 87}; 88 89struct ref_exclusions { 90 /* 91 * Excluded refs is a list of wildmatch patterns. If any of the 92 * patterns match, the reference will be excluded. 93 */ 94 struct string_list excluded_refs; 95 96 /* 97 * Hidden refs is a list of patterns that is to be hidden via 98 * `ref_is_hidden()`. 99 */ 100 struct strvec hidden_refs; 101 102 /* 103 * Indicates whether hidden refs have been configured. This is to 104 * distinguish between no hidden refs existing and hidden refs not 105 * being parsed. 106 */ 107 char hidden_refs_configured; 108}; 109 110/** 111 * Initialize a `struct ref_exclusions` with a macro. 112 */ 113#define REF_EXCLUSIONS_INIT { \ 114 .excluded_refs = STRING_LIST_INIT_DUP, \ 115 .hidden_refs = STRVEC_INIT, \ 116} 117 118struct oidset; 119struct topo_walk_info; 120 121struct rev_info { 122 /* Starting list */ 123 struct commit_list *commits; 124 struct object_array pending; 125 struct repository *repo; 126 127 /* Parents of shown commits */ 128 struct object_array boundary_commits; 129 130 /* The end-points specified by the end user */ 131 struct rev_cmdline_info cmdline; 132 133 /* 134 * Object filter options. No filtering is specified 135 * if and only if filter.choice is zero. 136 */ 137 struct list_objects_filter_options filter; 138 139 /* excluding from --branches, --refs, etc. expansion */ 140 struct ref_exclusions ref_excludes; 141 142 /* Basic information */ 143 const char *prefix; 144 const char *def; 145 char *ps_matched; /* optionally record matches of prune_data */ 146 struct pathspec prune_data; 147 148 /* 149 * Whether the arguments parsed by setup_revisions() included any 150 * "input" revisions that might still have yielded an empty pending 151 * list (e.g., patterns like "--all" or "--glob"). 152 */ 153 int rev_input_given; 154 155 /* 156 * Whether we read from stdin due to the --stdin option. 157 */ 158 int read_from_stdin; 159 160 /* topo-sort */ 161 enum rev_sort_order sort_order; 162 163 unsigned int ignore_missing:1, 164 ignore_missing_links:1; 165 166 /* Traversal flags */ 167 unsigned int dense:1, 168 prune:1, 169 no_walk:1, 170 unsorted_input:1, 171 remove_empty_trees:1, 172 simplify_history:1, 173 show_pulls:1, 174 topo_order:1, 175 simplify_merges:1, 176 simplify_by_decoration:1, 177 single_worktree:1, 178 tag_objects:1, 179 tree_objects:1, 180 blob_objects:1, 181 verify_objects:1, 182 edge_hint:1, 183 edge_hint_aggressive:1, 184 limited:1, 185 unpacked:1, 186 no_kept_objects:1, 187 boundary:2, 188 count:1, 189 left_right:1, 190 left_only:1, 191 right_only:1, 192 rewrite_parents:1, 193 print_parents:1, 194 show_decorations:1, 195 reverse:1, 196 reverse_output_stage:1, 197 cherry_pick:1, 198 cherry_mark:1, 199 bisect:1, 200 ancestry_path:1, 201 202 /* True if --ancestry-path was specified without an 203 * argument. The bottom revisions are implicitly 204 * the arguments in this case. 205 */ 206 ancestry_path_implicit_bottoms:1, 207 208 first_parent_only:1, 209 exclude_first_parent_only:1, 210 line_level_traverse:1, 211 tree_blobs_in_commit_order:1, 212 213 /* 214 * Blobs are shown without regard for their existence. 215 * But not so for trees/commits: unless exclude_promisor_objects 216 * is set and the tree in question is a promisor object; 217 * OR ignore_missing_links is set, the revision walker 218 * dies with a "bad <type> object HASH" message when 219 * encountering a missing object. For callers that can 220 * handle missing trees/commits and want them to be filterable 221 * and showable, set this to true. The revision walker 222 * will filter and show such a missing object as usual, 223 * but will not attempt to recurse into this tree/commit 224 * object. The revision walker will also set the MISSING 225 * flag for such objects. 226 */ 227 do_not_die_on_missing_objects:1, 228 229 /* for internal use only */ 230 exclude_promisor_objects:1; 231 232 /* Diff flags */ 233 unsigned int diff:1, 234 full_diff:1, 235 show_root_diff:1, 236 match_missing:1, 237 no_commit_id:1, 238 verbose_header:1, 239 always_show_header:1, 240 /* Diff-merge flags */ 241 explicit_diff_merges: 1, 242 merges_need_diff: 1, 243 merges_imply_patch:1, 244 separate_merges: 1, 245 combine_merges:1, 246 combined_all_paths:1, 247 dense_combined_merges:1, 248 first_parent_merges:1, 249 remerge_diff:1; 250 251 /* Format info */ 252 int show_notes; 253 unsigned int shown_one:1, 254 shown_dashes:1, 255 show_merge:1, 256 show_notes_given:1, 257 show_notes_by_default:1, 258 show_signature:1, 259 pretty_given:1, 260 abbrev_commit:1, 261 abbrev_commit_given:1, 262 zero_commit:1, 263 use_terminator:1, 264 missing_newline:1, 265 date_mode_explicit:1, 266 preserve_subject:1, 267 force_in_body_from:1, 268 encode_email_headers:1, 269 include_header:1; 270 unsigned int disable_stdin:1; 271 /* --show-linear-break */ 272 unsigned int track_linear:1, 273 track_first_time:1, 274 linear:1; 275 276 struct date_mode date_mode; 277 int expand_tabs_in_log; /* unset if negative */ 278 int expand_tabs_in_log_default; 279 280 unsigned int abbrev; 281 enum cmit_fmt commit_format; 282 struct log_info *loginfo; 283 int nr, total; 284 const char *mime_boundary; 285 const char *patch_suffix; 286 int numbered_files; 287 const char *reroll_count; 288 char *message_id; 289 struct ident_split from_ident; 290 struct string_list *ref_message_ids; 291 int add_signoff; 292 const char *extra_headers; 293 const char *subject_prefix; 294 int patch_name_max; 295 int no_inline; 296 int show_log_size; 297 struct string_list *mailmap; 298 299 /* Filter by commit log message */ 300 struct grep_opt grep_filter; 301 302 /* Display history graph */ 303 struct git_graph *graph; 304 305 /* special limits */ 306 int skip_count; 307 int max_count; 308 timestamp_t max_age; 309 timestamp_t max_age_as_filter; 310 timestamp_t min_age; 311 int min_parents; 312 int max_parents; 313 int (*include_check)(struct commit *, void *); 314 int (*include_check_obj)(struct object *obj, void *); 315 void *include_check_data; 316 317 /* diff info for patches and for paths limiting */ 318 struct diff_options diffopt; 319 struct diff_options pruning; 320 321 struct reflog_walk_info *reflog_info; 322 struct decoration children; 323 struct decoration merge_simplification; 324 struct decoration treesame; 325 326 /* notes-specific options: which refs to show */ 327 struct display_notes_opt notes_opt; 328 329 /* interdiff */ 330 const struct object_id *idiff_oid1; 331 const struct object_id *idiff_oid2; 332 const char *idiff_title; 333 334 /* range-diff */ 335 const char *rdiff1; 336 const char *rdiff2; 337 struct strvec rdiff_log_arg; 338 int creation_factor; 339 const char *rdiff_title; 340 341 /* commit counts */ 342 int count_left; 343 int count_right; 344 int count_same; 345 346 /* line level range that we are chasing */ 347 struct decoration line_log_data; 348 349 /* copies of the parent lists, for --full-diff display */ 350 struct saved_parents *saved_parents_slab; 351 352 struct commit_list *previous_parents; 353 struct commit_list *ancestry_path_bottoms; 354 const char *break_bar; 355 356 struct revision_sources *sources; 357 358 struct topo_walk_info *topo_walk_info; 359 360 /* Commit graph bloom filter fields */ 361 /* The bloom filter key(s) for the pathspec */ 362 struct bloom_keyvec **bloom_keyvecs; 363 int bloom_keyvecs_nr; 364 365 /* 366 * The bloom filter settings used to generate the key. 367 * This is loaded from the commit-graph being used. 368 */ 369 struct bloom_filter_settings *bloom_filter_settings; 370 371 /* misc. flags related to '--no-kept-objects' */ 372 unsigned keep_pack_cache_flags; 373 374 /* Location where temporary objects for remerge-diff are written. */ 375 struct tmp_objdir *remerge_objdir; 376 377 /* Missing commits to be tracked without failing traversal. */ 378 struct oidset missing_commits; 379}; 380 381/** 382 * Initialize the "struct rev_info" structure with a macro. 383 * 384 * This will not fully initialize a "struct rev_info", the 385 * repo_init_revisions() function needs to be called before 386 * setup_revisions() and any revision walking takes place. 387 * 388 * Use REV_INFO_INIT to make the "struct rev_info" safe for passing to 389 * release_revisions() when it's inconvenient (e.g. due to a "goto 390 * cleanup" pattern) to arrange for repo_init_revisions() to be called 391 * before release_revisions() is called. 392 * 393 * Initializing with this REV_INFO_INIT is redundant to invoking 394 * repo_init_revisions(). If repo_init_revisions() is guaranteed to be 395 * called before release_revisions() the "struct rev_info" can be left 396 * uninitialized. 397 */ 398#define REV_INFO_INIT { \ 399 .abbrev = DEFAULT_ABBREV, \ 400 .simplify_history = 1, \ 401 .pruning.flags.recursive = 1, \ 402 .pruning.flags.quick = 1, \ 403 .sort_order = REV_SORT_IN_GRAPH_ORDER, \ 404 .dense = 1, \ 405 .max_age = -1, \ 406 .max_age_as_filter = -1, \ 407 .min_age = -1, \ 408 .skip_count = -1, \ 409 .max_count = -1, \ 410 .max_parents = -1, \ 411 .expand_tabs_in_log = -1, \ 412 .commit_format = CMIT_FMT_DEFAULT, \ 413 .expand_tabs_in_log_default = 8, \ 414 .rdiff_log_arg = STRVEC_INIT, \ 415} 416 417/** 418 * Initialize a rev_info structure with default values. The third parameter may 419 * be NULL or can be prefix path, and then the `.prefix` variable will be set 420 * to it. This is typically the first function you want to call when you want 421 * to deal with a revision list. After calling this function, you are free to 422 * customize options, like set `.ignore_merges` to 0 if you don't want to 423 * ignore merges, and so on. 424 */ 425void repo_init_revisions(struct repository *r, 426 struct rev_info *revs, 427 const char *prefix); 428 429/** 430 * Parse revision information, filling in the `rev_info` structure, and 431 * removing the used arguments from the argument list. Returns the number 432 * of arguments left that weren't recognized, which are also moved to the 433 * head of the argument list. The last parameter is used in case no 434 * parameter given by the first two arguments. 435 */ 436struct setup_revision_opt { 437 const char *def; 438 void (*tweak)(struct rev_info *); 439 unsigned int assume_dashdash:1, 440 allow_exclude_promisor_objects:1, 441 free_removed_argv_elements:1; 442 unsigned revarg_opt; 443}; 444int setup_revisions(int argc, const char **argv, struct rev_info *revs, 445 struct setup_revision_opt *); 446void setup_revisions_from_strvec(struct strvec *argv, struct rev_info *revs, 447 struct setup_revision_opt *); 448 449/** 450 * Free data allocated in a "struct rev_info" after it's been 451 * initialized with repo_init_revisions() or REV_INFO_INIT. 452 */ 453void release_revisions(struct rev_info *revs); 454 455void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ctx, 456 const struct option *options, 457 const char * const usagestr[]); 458#define REVARG_CANNOT_BE_FILENAME 01 459#define REVARG_COMMITTISH 02 460int handle_revision_arg(const char *arg, struct rev_info *revs, 461 int flags, unsigned revarg_opt); 462void revision_opts_finish(struct rev_info *revs); 463 464/** 465 * Reset the flags used by the revision walking api. You can use this to do 466 * multiple sequential revision walks. 467 */ 468void reset_revision_walk(void); 469 470/** 471 * Prepares the rev_info structure for a walk. You should check if it returns 472 * any error (non-zero return code) and if it does not, you can start using 473 * get_revision() to do the iteration. 474 */ 475int prepare_revision_walk(struct rev_info *revs); 476 477/** 478 * Takes a pointer to a `rev_info` structure and iterates over it, returning a 479 * `struct commit *` each time you call it. The end of the revision list is 480 * indicated by returning a NULL pointer. 481 */ 482struct commit *get_revision(struct rev_info *revs); 483 484const char *get_revision_mark(const struct rev_info *revs, 485 const struct commit *commit); 486void put_revision_mark(const struct rev_info *revs, 487 const struct commit *commit); 488 489void mark_parents_uninteresting(struct rev_info *revs, struct commit *commit); 490void mark_tree_uninteresting(struct repository *r, struct tree *tree); 491void mark_trees_uninteresting_sparse(struct repository *r, struct oidset *trees); 492 493/** 494 * Helpers to check if a reference should be excluded. 495 */ 496 497int ref_excluded(const struct ref_exclusions *exclusions, const char *path); 498void init_ref_exclusions(struct ref_exclusions *); 499void clear_ref_exclusions(struct ref_exclusions *); 500void add_ref_exclusion(struct ref_exclusions *, const char *exclude); 501void exclude_hidden_refs(struct ref_exclusions *, const char *section); 502 503/** 504 * This function can be used if you want to add commit objects as revision 505 * information. You can use the `UNINTERESTING` object flag to indicate if 506 * you want to include or exclude the given commit (and commits reachable 507 * from the given commit) from the revision list. 508 * 509 * NOTE: If you have the commits as a string list then you probably want to 510 * use setup_revisions(), instead of parsing each string and using this 511 * function. 512 */ 513void add_pending_object(struct rev_info *revs, 514 struct object *obj, const char *name); 515 516void add_pending_oid(struct rev_info *revs, 517 const char *name, const struct object_id *oid, 518 unsigned int flags); 519 520void add_head_to_pending(struct rev_info *); 521void add_reflogs_to_pending(struct rev_info *, unsigned int flags); 522void add_index_objects_to_pending(struct rev_info *, unsigned int flags); 523 524enum commit_action { 525 commit_ignore, 526 commit_show, 527 commit_error 528}; 529 530enum commit_action get_commit_action(struct rev_info *revs, 531 struct commit *commit); 532enum commit_action simplify_commit(struct rev_info *revs, 533 struct commit *commit); 534 535enum rewrite_result { 536 rewrite_one_ok, 537 rewrite_one_noparents, 538 rewrite_one_error 539}; 540 541typedef enum rewrite_result (*rewrite_parent_fn_t)(struct rev_info *revs, struct commit **pp); 542 543int rewrite_parents(struct rev_info *revs, 544 struct commit *commit, 545 rewrite_parent_fn_t rewrite_parent); 546 547/* 548 * The log machinery saves the original parent list so that 549 * get_saved_parents() can later tell what the real parents of the 550 * commits are, when commit->parents has been modified by history 551 * simplification. 552 * 553 * get_saved_parents() will transparently return commit->parents if 554 * history simplification is off. 555 */ 556struct commit_list *get_saved_parents(struct rev_info *revs, const struct commit *commit); 557 558#endif