diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/checkout.c | 21 | ||||
-rw-r--r-- | src/merge.c | 14 |
2 files changed, 29 insertions, 6 deletions
diff --git a/src/checkout.c b/src/checkout.c index 960bc6140..cfb0e72ab 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -71,7 +71,8 @@ typedef struct { int name_collision:1, directoryfile:1, one_to_two:1, - binary:1; + binary:1, + submodule:1; } checkout_conflictdata; static int checkout_notify( @@ -682,11 +683,22 @@ GIT_INLINE(bool) conflict_pathspec_match( return false; } +GIT_INLINE(int) checkout_conflict_detect_submodule(checkout_conflictdata *conflict) +{ + conflict->submodule = ((conflict->ancestor && S_ISGITLINK(conflict->ancestor->mode)) || + (conflict->ours && S_ISGITLINK(conflict->ours->mode)) || + (conflict->theirs && S_ISGITLINK(conflict->theirs->mode))); + return 0; +} + GIT_INLINE(int) checkout_conflict_detect_binary(git_repository *repo, checkout_conflictdata *conflict) { git_blob *ancestor_blob = NULL, *our_blob = NULL, *their_blob = NULL; int error = 0; + if (conflict->submodule) + return 0; + if (conflict->ancestor) { if ((error = git_blob_lookup(&ancestor_blob, repo, &conflict->ancestor->oid)) < 0) goto done; @@ -740,7 +752,8 @@ static int checkout_conflicts_load(checkout_data *data, git_iterator *workdir, g conflict->ours = ours; conflict->theirs = theirs; - if ((error = checkout_conflict_detect_binary(data->repo, conflict)) < 0) + if ((error = checkout_conflict_detect_submodule(conflict)) < 0 || + (error = checkout_conflict_detect_binary(data->repo, conflict)) < 0) goto done; git_vector_insert(&data->conflicts, conflict); @@ -1791,6 +1804,10 @@ static int checkout_create_conflicts(checkout_data *data) else if (S_ISLNK(conflict->theirs->mode)) error = checkout_write_entry(data, conflict, conflict->ours); + /* If any side is a gitlink, do nothing. */ + else if (conflict->submodule) + error = 0; + /* If any side is binary, write the ours side */ else if (conflict->binary) error = checkout_write_entry(data, conflict, conflict->ours); diff --git a/src/merge.c b/src/merge.c index 04c74212a..2fb1c5898 100644 --- a/src/merge.c +++ b/src/merge.c @@ -42,6 +42,7 @@ #include "git2/sys/index.h" #define GIT_MERGE_INDEX_ENTRY_EXISTS(X) ((X).mode != 0) +#define GIT_MERGE_INDEX_ENTRY_ISFILE(X) S_ISREG((X).mode) typedef enum { TREE_IDX_ANCESTOR = 0, @@ -447,7 +448,6 @@ static int merge_conflict_resolve_one_removed( return error; } - static int merge_conflict_resolve_one_renamed( int *resolved, git_merge_diff_list *diff_list, @@ -533,6 +533,12 @@ static int merge_conflict_resolve_automerge( if (conflict->type == GIT_MERGE_DIFF_DIRECTORY_FILE) return 0; + /* Reject submodules. */ + if (S_ISGITLINK(conflict->ancestor_entry.mode) || + S_ISGITLINK(conflict->our_entry.mode) || + S_ISGITLINK(conflict->their_entry.mode)) + return 0; + /* Reject link/file conflicts. */ if ((S_ISLNK(conflict->ancestor_entry.mode) ^ S_ISLNK(conflict->our_entry.mode)) || (S_ISLNK(conflict->ancestor_entry.mode) ^ S_ISLNK(conflict->their_entry.mode))) @@ -1156,7 +1162,7 @@ GIT_INLINE(int) merge_diff_detect_binary( git_blob *ancestor_blob = NULL, *our_blob = NULL, *their_blob = NULL; int error = 0; - if (GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->ancestor_entry)) { + if (GIT_MERGE_INDEX_ENTRY_ISFILE(conflict->ancestor_entry)) { if ((error = git_blob_lookup(&ancestor_blob, repo, &conflict->ancestor_entry.oid)) < 0) goto done; @@ -1164,7 +1170,7 @@ GIT_INLINE(int) merge_diff_detect_binary( } if (!conflict->binary && - GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry)) { + GIT_MERGE_INDEX_ENTRY_ISFILE(conflict->our_entry)) { if ((error = git_blob_lookup(&our_blob, repo, &conflict->our_entry.oid)) < 0) goto done; @@ -1172,7 +1178,7 @@ GIT_INLINE(int) merge_diff_detect_binary( } if (!conflict->binary && - GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry)) { + GIT_MERGE_INDEX_ENTRY_ISFILE(conflict->their_entry)) { if ((error = git_blob_lookup(&their_blob, repo, &conflict->their_entry.oid)) < 0) goto done; |