Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:59:38

0001 /*
0002  * Copyright (C) the libgit2 contributors. All rights reserved.
0003  *
0004  * This file is part of libgit2, distributed under the GNU GPL v2 with
0005  * a Linking Exception. For full terms see the included COPYING file.
0006  */
0007 #ifndef INCLUDE_git_merge_h__
0008 #define INCLUDE_git_merge_h__
0009 
0010 #include "common.h"
0011 #include "types.h"
0012 #include "oid.h"
0013 #include "oidarray.h"
0014 #include "checkout.h"
0015 #include "index.h"
0016 #include "annotated_commit.h"
0017 
0018 /**
0019  * @file git2/merge.h
0020  * @brief Git merge routines
0021  * @defgroup git_merge Git merge routines
0022  * @ingroup Git
0023  * @{
0024  */
0025 GIT_BEGIN_DECL
0026 
0027 /**
0028  * The file inputs to `git_merge_file`.  Callers should populate the
0029  * `git_merge_file_input` structure with descriptions of the files in
0030  * each side of the conflict for use in producing the merge file.
0031  */
0032 typedef struct {
0033     unsigned int version;
0034 
0035     /** Pointer to the contents of the file. */
0036     const char *ptr;
0037 
0038     /** Size of the contents pointed to in `ptr`. */
0039     size_t size;
0040 
0041     /** File name of the conflicted file, or `NULL` to not merge the path. */
0042     const char *path;
0043 
0044     /** File mode of the conflicted file, or `0` to not merge the mode. */
0045     unsigned int mode;
0046 } git_merge_file_input;
0047 
0048 #define GIT_MERGE_FILE_INPUT_VERSION 1
0049 #define GIT_MERGE_FILE_INPUT_INIT {GIT_MERGE_FILE_INPUT_VERSION}
0050 
0051 /**
0052  * Initializes a `git_merge_file_input` with default values. Equivalent to
0053  * creating an instance with GIT_MERGE_FILE_INPUT_INIT.
0054  *
0055  * @param opts the `git_merge_file_input` instance to initialize.
0056  * @param version the version of the struct; you should pass
0057  *        `GIT_MERGE_FILE_INPUT_VERSION` here.
0058  * @return Zero on success; -1 on failure.
0059  */
0060 GIT_EXTERN(int) git_merge_file_input_init(
0061     git_merge_file_input *opts,
0062     unsigned int version);
0063 
0064 /**
0065  * Flags for `git_merge` options.  A combination of these flags can be
0066  * passed in via the `flags` value in the `git_merge_options`.
0067  */
0068 typedef enum {
0069     /**
0070      * Detect renames that occur between the common ancestor and the "ours"
0071      * side or the common ancestor and the "theirs" side.  This will enable
0072      * the ability to merge between a modified and renamed file.
0073      */
0074     GIT_MERGE_FIND_RENAMES = (1 << 0),
0075 
0076     /**
0077      * If a conflict occurs, exit immediately instead of attempting to
0078      * continue resolving conflicts.  The merge operation will fail with
0079      * GIT_EMERGECONFLICT and no index will be returned.
0080      */
0081     GIT_MERGE_FAIL_ON_CONFLICT = (1 << 1),
0082 
0083     /**
0084      * Do not write the REUC extension on the generated index
0085      */
0086     GIT_MERGE_SKIP_REUC = (1 << 2),
0087 
0088     /**
0089      * If the commits being merged have multiple merge bases, do not build
0090      * a recursive merge base (by merging the multiple merge bases),
0091      * instead simply use the first base.  This flag provides a similar
0092      * merge base to `git-merge-resolve`.
0093      */
0094     GIT_MERGE_NO_RECURSIVE = (1 << 3),
0095 
0096     /**
0097      * Treat this merge as if it is to produce the virtual base
0098      * of a recursive merge.  This will ensure that there are
0099      * no conflicts, any conflicting regions will keep conflict
0100      * markers in the merge result.
0101      */
0102     GIT_MERGE_VIRTUAL_BASE = (1 << 4)
0103 } git_merge_flag_t;
0104 
0105 /**
0106  * Merge file favor options for `git_merge_options` instruct the file-level
0107  * merging functionality how to deal with conflicting regions of the files.
0108  */
0109 typedef enum {
0110     /**
0111      * When a region of a file is changed in both branches, a conflict
0112      * will be recorded in the index so that `git_checkout` can produce
0113      * a merge file with conflict markers in the working directory.
0114      * This is the default.
0115      */
0116     GIT_MERGE_FILE_FAVOR_NORMAL = 0,
0117 
0118     /**
0119      * When a region of a file is changed in both branches, the file
0120      * created in the index will contain the "ours" side of any conflicting
0121      * region.  The index will not record a conflict.
0122      */
0123     GIT_MERGE_FILE_FAVOR_OURS = 1,
0124 
0125     /**
0126      * When a region of a file is changed in both branches, the file
0127      * created in the index will contain the "theirs" side of any conflicting
0128      * region.  The index will not record a conflict.
0129      */
0130     GIT_MERGE_FILE_FAVOR_THEIRS = 2,
0131 
0132     /**
0133      * When a region of a file is changed in both branches, the file
0134      * created in the index will contain each unique line from each side,
0135      * which has the result of combining both files.  The index will not
0136      * record a conflict.
0137      */
0138     GIT_MERGE_FILE_FAVOR_UNION = 3
0139 } git_merge_file_favor_t;
0140 
0141 /**
0142  * File merging flags
0143  */
0144 typedef enum {
0145     /** Defaults */
0146     GIT_MERGE_FILE_DEFAULT = 0,
0147 
0148     /** Create standard conflicted merge files */
0149     GIT_MERGE_FILE_STYLE_MERGE = (1 << 0),
0150 
0151     /** Create diff3-style files */
0152     GIT_MERGE_FILE_STYLE_DIFF3 = (1 << 1),
0153 
0154     /** Condense non-alphanumeric regions for simplified diff file */
0155     GIT_MERGE_FILE_SIMPLIFY_ALNUM = (1 << 2),
0156 
0157     /** Ignore all whitespace */
0158     GIT_MERGE_FILE_IGNORE_WHITESPACE = (1 << 3),
0159 
0160     /** Ignore changes in amount of whitespace */
0161     GIT_MERGE_FILE_IGNORE_WHITESPACE_CHANGE = (1 << 4),
0162 
0163     /** Ignore whitespace at end of line */
0164     GIT_MERGE_FILE_IGNORE_WHITESPACE_EOL = (1 << 5),
0165 
0166     /** Use the "patience diff" algorithm */
0167     GIT_MERGE_FILE_DIFF_PATIENCE = (1 << 6),
0168 
0169     /** Take extra time to find minimal diff */
0170     GIT_MERGE_FILE_DIFF_MINIMAL = (1 << 7),
0171 
0172     /** Create zdiff3 ("zealous diff3")-style files */
0173     GIT_MERGE_FILE_STYLE_ZDIFF3 = (1 << 8),
0174 
0175     /**
0176      * Do not produce file conflicts when common regions have
0177      * changed; keep the conflict markers in the file and accept
0178      * that as the merge result.
0179      */
0180     GIT_MERGE_FILE_ACCEPT_CONFLICTS = (1 << 9)
0181 } git_merge_file_flag_t;
0182 
0183 #define GIT_MERGE_CONFLICT_MARKER_SIZE  7
0184 
0185 /**
0186  * Options for merging a file
0187  */
0188 typedef struct {
0189     unsigned int version;
0190 
0191     /**
0192      * Label for the ancestor file side of the conflict which will be prepended
0193      * to labels in diff3-format merge files.
0194      */
0195     const char *ancestor_label;
0196 
0197     /**
0198      * Label for our file side of the conflict which will be prepended
0199      * to labels in merge files.
0200      */
0201     const char *our_label;
0202 
0203     /**
0204      * Label for their file side of the conflict which will be prepended
0205      * to labels in merge files.
0206      */
0207     const char *their_label;
0208 
0209     /** The file to favor in region conflicts. */
0210     git_merge_file_favor_t favor;
0211 
0212     /** see `git_merge_file_flag_t` above */
0213     uint32_t flags;
0214 
0215     /** The size of conflict markers (eg, "<<<<<<<").  Default is
0216      * GIT_MERGE_CONFLICT_MARKER_SIZE. */
0217     unsigned short marker_size;
0218 } git_merge_file_options;
0219 
0220 #define GIT_MERGE_FILE_OPTIONS_VERSION 1
0221 #define GIT_MERGE_FILE_OPTIONS_INIT {GIT_MERGE_FILE_OPTIONS_VERSION}
0222 
0223 /**
0224  * Initialize git_merge_file_options structure
0225  *
0226  * Initializes a `git_merge_file_options` with default values. Equivalent to
0227  * creating an instance with `GIT_MERGE_FILE_OPTIONS_INIT`.
0228  *
0229  * @param opts The `git_merge_file_options` struct to initialize.
0230  * @param version The struct version; pass `GIT_MERGE_FILE_OPTIONS_VERSION`.
0231  * @return Zero on success; -1 on failure.
0232  */
0233 GIT_EXTERN(int) git_merge_file_options_init(git_merge_file_options *opts, unsigned int version);
0234 
0235 /**
0236  * Information about file-level merging
0237  */
0238 typedef struct {
0239     /**
0240      * True if the output was automerged, false if the output contains
0241      * conflict markers.
0242      */
0243     unsigned int automergeable;
0244 
0245     /**
0246      * The path that the resultant merge file should use, or NULL if a
0247      * filename conflict would occur.
0248      */
0249     const char *path;
0250 
0251     /** The mode that the resultant merge file should use.  */
0252     unsigned int mode;
0253 
0254     /** The contents of the merge. */
0255     const char *ptr;
0256 
0257     /** The length of the merge contents. */
0258     size_t len;
0259 } git_merge_file_result;
0260 
0261 /**
0262  * Merging options
0263  */
0264 typedef struct {
0265     unsigned int version;
0266 
0267     /** See `git_merge_flag_t` above */
0268     uint32_t flags;
0269 
0270     /**
0271      * Similarity to consider a file renamed (default 50).  If
0272      * `GIT_MERGE_FIND_RENAMES` is enabled, added files will be compared
0273      * with deleted files to determine their similarity.  Files that are
0274      * more similar than the rename threshold (percentage-wise) will be
0275      * treated as a rename.
0276      */
0277     unsigned int rename_threshold;
0278 
0279     /**
0280      * Maximum similarity sources to examine for renames (default 200).
0281      * If the number of rename candidates (add / delete pairs) is greater
0282      * than this value, inexact rename detection is aborted.
0283      *
0284      * This setting overrides the `merge.renameLimit` configuration value.
0285      */
0286     unsigned int target_limit;
0287 
0288     /** Pluggable similarity metric; pass NULL to use internal metric */
0289     git_diff_similarity_metric *metric;
0290 
0291     /**
0292      * Maximum number of times to merge common ancestors to build a
0293      * virtual merge base when faced with criss-cross merges.  When this
0294      * limit is reached, the next ancestor will simply be used instead of
0295      * attempting to merge it.  The default is unlimited.
0296      */
0297     unsigned int recursion_limit;
0298 
0299     /**
0300      * Default merge driver to be used when both sides of a merge have
0301      * changed.  The default is the `text` driver.
0302      */
0303     const char *default_driver;
0304 
0305     /**
0306      * Flags for handling conflicting content, to be used with the standard
0307      * (`text`) merge driver.
0308      */
0309     git_merge_file_favor_t file_favor;
0310 
0311     /** see `git_merge_file_flag_t` above */
0312     uint32_t file_flags;
0313 } git_merge_options;
0314 
0315 #define GIT_MERGE_OPTIONS_VERSION 1
0316 #define GIT_MERGE_OPTIONS_INIT { \
0317     GIT_MERGE_OPTIONS_VERSION, GIT_MERGE_FIND_RENAMES }
0318 
0319 /**
0320  * Initialize git_merge_options structure
0321  *
0322  * Initializes a `git_merge_options` with default values. Equivalent to
0323  * creating an instance with `GIT_MERGE_OPTIONS_INIT`.
0324  *
0325  * @param opts The `git_merge_options` struct to initialize.
0326  * @param version The struct version; pass `GIT_MERGE_OPTIONS_VERSION`.
0327  * @return Zero on success; -1 on failure.
0328  */
0329 GIT_EXTERN(int) git_merge_options_init(git_merge_options *opts, unsigned int version);
0330 
0331 /**
0332  * The results of `git_merge_analysis` indicate the merge opportunities.
0333  */
0334 typedef enum {
0335     /** No merge is possible.  (Unused.) */
0336     GIT_MERGE_ANALYSIS_NONE = 0,
0337 
0338     /**
0339      * A "normal" merge; both HEAD and the given merge input have diverged
0340      * from their common ancestor.  The divergent commits must be merged.
0341      */
0342     GIT_MERGE_ANALYSIS_NORMAL = (1 << 0),
0343 
0344     /**
0345      * All given merge inputs are reachable from HEAD, meaning the
0346      * repository is up-to-date and no merge needs to be performed.
0347      */
0348     GIT_MERGE_ANALYSIS_UP_TO_DATE = (1 << 1),
0349 
0350     /**
0351      * The given merge input is a fast-forward from HEAD and no merge
0352      * needs to be performed.  Instead, the client can check out the
0353      * given merge input.
0354      */
0355     GIT_MERGE_ANALYSIS_FASTFORWARD = (1 << 2),
0356 
0357     /**
0358      * The HEAD of the current repository is "unborn" and does not point to
0359      * a valid commit.  No merge can be performed, but the caller may wish
0360      * to simply set HEAD to the target commit(s).
0361      */
0362     GIT_MERGE_ANALYSIS_UNBORN = (1 << 3)
0363 } git_merge_analysis_t;
0364 
0365 /**
0366  * The user's stated preference for merges.
0367  */
0368 typedef enum {
0369     /**
0370      * No configuration was found that suggests a preferred behavior for
0371      * merge.
0372      */
0373     GIT_MERGE_PREFERENCE_NONE = 0,
0374 
0375     /**
0376      * There is a `merge.ff=false` configuration setting, suggesting that
0377      * the user does not want to allow a fast-forward merge.
0378      */
0379     GIT_MERGE_PREFERENCE_NO_FASTFORWARD = (1 << 0),
0380 
0381     /**
0382      * There is a `merge.ff=only` configuration setting, suggesting that
0383      * the user only wants fast-forward merges.
0384      */
0385     GIT_MERGE_PREFERENCE_FASTFORWARD_ONLY = (1 << 1)
0386 } git_merge_preference_t;
0387 
0388 /**
0389  * Analyzes the given branch(es) and determines the opportunities for
0390  * merging them into the HEAD of the repository.
0391  *
0392  * @param analysis_out analysis enumeration that the result is written into
0393  * @param preference_out One of the `git_merge_preference_t` flag.
0394  * @param repo the repository to merge
0395  * @param their_heads the heads to merge into
0396  * @param their_heads_len the number of heads to merge
0397  * @return 0 on success or error code
0398  */
0399 GIT_EXTERN(int) git_merge_analysis(
0400     git_merge_analysis_t *analysis_out,
0401     git_merge_preference_t *preference_out,
0402     git_repository *repo,
0403     const git_annotated_commit **their_heads,
0404     size_t their_heads_len);
0405 
0406 /**
0407  * Analyzes the given branch(es) and determines the opportunities for
0408  * merging them into a reference.
0409  *
0410  * @param analysis_out analysis enumeration that the result is written into
0411  * @param preference_out One of the `git_merge_preference_t` flag.
0412  * @param repo the repository to merge
0413  * @param our_ref the reference to perform the analysis from
0414  * @param their_heads the heads to merge into
0415  * @param their_heads_len the number of heads to merge
0416  * @return 0 on success or error code
0417  */
0418 GIT_EXTERN(int) git_merge_analysis_for_ref(
0419     git_merge_analysis_t *analysis_out,
0420     git_merge_preference_t *preference_out,
0421     git_repository *repo,
0422     git_reference *our_ref,
0423     const git_annotated_commit **their_heads,
0424     size_t their_heads_len);
0425 
0426 /**
0427  * Find a merge base between two commits
0428  *
0429  * @param out the OID of a merge base between 'one' and 'two'
0430  * @param repo the repository where the commits exist
0431  * @param one one of the commits
0432  * @param two the other commit
0433  * @return 0 on success, GIT_ENOTFOUND if not found or error code
0434  */
0435 GIT_EXTERN(int) git_merge_base(
0436     git_oid *out,
0437     git_repository *repo,
0438     const git_oid *one,
0439     const git_oid *two);
0440 
0441 /**
0442  * Find merge bases between two commits
0443  *
0444  * @param out array in which to store the resulting ids
0445  * @param repo the repository where the commits exist
0446  * @param one one of the commits
0447  * @param two the other commit
0448  * @return 0 on success, GIT_ENOTFOUND if not found or error code
0449  */
0450 GIT_EXTERN(int) git_merge_bases(
0451     git_oidarray *out,
0452     git_repository *repo,
0453     const git_oid *one,
0454     const git_oid *two);
0455 
0456 /**
0457  * Find a merge base given a list of commits
0458  *
0459  * @param out the OID of a merge base considering all the commits
0460  * @param repo the repository where the commits exist
0461  * @param length The number of commits in the provided `input_array`
0462  * @param input_array oids of the commits
0463  * @return Zero on success; GIT_ENOTFOUND or -1 on failure.
0464  */
0465 GIT_EXTERN(int) git_merge_base_many(
0466     git_oid *out,
0467     git_repository *repo,
0468     size_t length,
0469     const git_oid input_array[]);
0470 
0471 /**
0472  * Find all merge bases given a list of commits
0473  *
0474  * @param out array in which to store the resulting ids
0475  * @param repo the repository where the commits exist
0476  * @param length The number of commits in the provided `input_array`
0477  * @param input_array oids of the commits
0478  * @return Zero on success; GIT_ENOTFOUND or -1 on failure.
0479  */
0480 GIT_EXTERN(int) git_merge_bases_many(
0481     git_oidarray *out,
0482     git_repository *repo,
0483     size_t length,
0484     const git_oid input_array[]);
0485 
0486 /**
0487  * Find a merge base in preparation for an octopus merge
0488  *
0489  * @param out the OID of a merge base considering all the commits
0490  * @param repo the repository where the commits exist
0491  * @param length The number of commits in the provided `input_array`
0492  * @param input_array oids of the commits
0493  * @return Zero on success; GIT_ENOTFOUND or -1 on failure.
0494  */
0495 GIT_EXTERN(int) git_merge_base_octopus(
0496     git_oid *out,
0497     git_repository *repo,
0498     size_t length,
0499     const git_oid input_array[]);
0500 
0501 /**
0502  * Merge two files as they exist in the in-memory data structures, using
0503  * the given common ancestor as the baseline, producing a
0504  * `git_merge_file_result` that reflects the merge result.  The
0505  * `git_merge_file_result` must be freed with `git_merge_file_result_free`.
0506  *
0507  * Note that this function does not reference a repository and any
0508  * configuration must be passed as `git_merge_file_options`.
0509  *
0510  * @param out The git_merge_file_result to be filled in
0511  * @param ancestor The contents of the ancestor file
0512  * @param ours The contents of the file in "our" side
0513  * @param theirs The contents of the file in "their" side
0514  * @param opts The merge file options or `NULL` for defaults
0515  * @return 0 on success or error code
0516  */
0517 GIT_EXTERN(int) git_merge_file(
0518     git_merge_file_result *out,
0519     const git_merge_file_input *ancestor,
0520     const git_merge_file_input *ours,
0521     const git_merge_file_input *theirs,
0522     const git_merge_file_options *opts);
0523 
0524 /**
0525  * Merge two files as they exist in the index, using the given common
0526  * ancestor as the baseline, producing a `git_merge_file_result` that
0527  * reflects the merge result.  The `git_merge_file_result` must be freed with
0528  * `git_merge_file_result_free`.
0529  *
0530  * @param out The git_merge_file_result to be filled in
0531  * @param repo The repository
0532  * @param ancestor The index entry for the ancestor file (stage level 1)
0533  * @param ours The index entry for our file (stage level 2)
0534  * @param theirs The index entry for their file (stage level 3)
0535  * @param opts The merge file options or NULL
0536  * @return 0 on success or error code
0537  */
0538 GIT_EXTERN(int) git_merge_file_from_index(
0539     git_merge_file_result *out,
0540     git_repository *repo,
0541     const git_index_entry *ancestor,
0542     const git_index_entry *ours,
0543     const git_index_entry *theirs,
0544     const git_merge_file_options *opts);
0545 
0546 /**
0547  * Frees a `git_merge_file_result`.
0548  *
0549  * @param result The result to free or `NULL`
0550  */
0551 GIT_EXTERN(void) git_merge_file_result_free(git_merge_file_result *result);
0552 
0553 /**
0554  * Merge two trees, producing a `git_index` that reflects the result of
0555  * the merge.  The index may be written as-is to the working directory
0556  * or checked out.  If the index is to be converted to a tree, the caller
0557  * should resolve any conflicts that arose as part of the merge.
0558  *
0559  * The returned index must be freed explicitly with `git_index_free`.
0560  *
0561  * @param out pointer to store the index result in
0562  * @param repo repository that contains the given trees
0563  * @param ancestor_tree the common ancestor between the trees (or null if none)
0564  * @param our_tree the tree that reflects the destination tree
0565  * @param their_tree the tree to merge in to `our_tree`
0566  * @param opts the merge tree options (or null for defaults)
0567  * @return 0 on success or error code
0568  */
0569 GIT_EXTERN(int) git_merge_trees(
0570     git_index **out,
0571     git_repository *repo,
0572     const git_tree *ancestor_tree,
0573     const git_tree *our_tree,
0574     const git_tree *their_tree,
0575     const git_merge_options *opts);
0576 
0577 /**
0578  * Merge two commits, producing a `git_index` that reflects the result of
0579  * the merge.  The index may be written as-is to the working directory
0580  * or checked out.  If the index is to be converted to a tree, the caller
0581  * should resolve any conflicts that arose as part of the merge.
0582  *
0583  * The returned index must be freed explicitly with `git_index_free`.
0584  *
0585  * @param out pointer to store the index result in
0586  * @param repo repository that contains the given trees
0587  * @param our_commit the commit that reflects the destination tree
0588  * @param their_commit the commit to merge in to `our_commit`
0589  * @param opts the merge tree options (or null for defaults)
0590  * @return 0 on success or error code
0591  */
0592 GIT_EXTERN(int) git_merge_commits(
0593     git_index **out,
0594     git_repository *repo,
0595     const git_commit *our_commit,
0596     const git_commit *their_commit,
0597     const git_merge_options *opts);
0598 
0599 /**
0600  * Merges the given commit(s) into HEAD, writing the results into the working
0601  * directory.  Any changes are staged for commit and any conflicts are written
0602  * to the index.  Callers should inspect the repository's index after this
0603  * completes, resolve any conflicts and prepare a commit.
0604  *
0605  * For compatibility with git, the repository is put into a merging
0606  * state. Once the commit is done (or if the user wishes to abort),
0607  * you should clear this state by calling
0608  * `git_repository_state_cleanup()`.
0609  *
0610  * @param repo the repository to merge
0611  * @param their_heads the heads to merge into
0612  * @param their_heads_len the number of heads to merge
0613  * @param merge_opts merge options
0614  * @param checkout_opts checkout options
0615  * @return 0 on success or error code
0616  */
0617 GIT_EXTERN(int) git_merge(
0618     git_repository *repo,
0619     const git_annotated_commit **their_heads,
0620     size_t their_heads_len,
0621     const git_merge_options *merge_opts,
0622     const git_checkout_options *checkout_opts);
0623 
0624 /** @} */
0625 GIT_END_DECL
0626 #endif