MCPcopy Create free account
hub / github.com/git/git / twoway_merge

Function twoway_merge

unpack-trees.c:2911–2986  ·  view source on GitHub ↗

* Two-way merge. * * The rule is to "carry forward" what is in the index without losing * information across a "fast-forward", favoring a successful merge * over a merge failure when it makes sense. For details of the * "carry forward" rule, please see . * */

Source from the content-addressed store, hash-verified

2909 *
2910 */
2911int twoway_merge(const struct cache_entry * const *src,
2912 struct unpack_trees_options *o)
2913{
2914 const struct cache_entry *current = src[0];
2915 const struct cache_entry *oldtree = src[1];
2916 const struct cache_entry *newtree = src[2];
2917
2918 if (o->internal.merge_size != 2)
2919 return error("Cannot do a twoway merge of %d trees",
2920 o->internal.merge_size);
2921
2922 if (oldtree == o->df_conflict_entry)
2923 oldtree = NULL;
2924 if (newtree == o->df_conflict_entry)
2925 newtree = NULL;
2926
2927 if (current) {
2928 if (current->ce_flags & CE_CONFLICTED) {
2929 if (same(oldtree, newtree) || o->reset) {
2930 if (!newtree)
2931 return deleted_entry(current, current, o);
2932 else
2933 return merged_entry(newtree, current, o);
2934 }
2935 return reject_merge(current, o);
2936 } else if ((!oldtree && !newtree) || /* 4 and 5 */
2937 (!oldtree && newtree &&
2938 same(current, newtree)) || /* 6 and 7 */
2939 (oldtree && newtree &&
2940 same(oldtree, newtree)) || /* 14 and 15 */
2941 (oldtree && newtree &&
2942 !same(oldtree, newtree) && /* 18 and 19 */
2943 same(current, newtree))) {
2944 return keep_entry(current, o);
2945 } else if (oldtree && !newtree && same(current, oldtree)) {
2946 /* 10 or 11 */
2947 return deleted_entry(oldtree, current, o);
2948 } else if (oldtree && newtree &&
2949 same(current, oldtree) && !same(current, newtree)) {
2950 /* 20 or 21 */
2951 return merged_entry(newtree, current, o);
2952 } else if (current && !oldtree && newtree &&
2953 S_ISSPARSEDIR(current->ce_mode) != S_ISSPARSEDIR(newtree->ce_mode) &&
2954 ce_stage(current) == 0) {
2955 /*
2956 * This case is a directory/file conflict across the sparse-index
2957 * boundary. When we are changing from one path to another via
2958 * 'git checkout', then we want to replace one entry with another
2959 * via merged_entry(). If there are staged changes, then we should
2960 * reject the merge instead.
2961 */
2962 return merged_entry(newtree, current, o);
2963 } else if (S_ISSPARSEDIR(current->ce_mode)) {
2964 /*
2965 * The sparse directories differ, but we don't know whether that's
2966 * because of two different files in the directory being modified
2967 * (can be trivially merged) or if there is a real file conflict.
2968 * Merge the sparse directory by OID to compare file-by-file.

Callers

nothing calls this directly

Calls 7

errorFunction · 0.85
sameFunction · 0.85
deleted_entryFunction · 0.85
merged_entryFunction · 0.85
reject_mergeFunction · 0.85
merged_sparse_dirFunction · 0.85
keep_entryFunction · 0.70

Tested by

no test coverage detected