summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/checkout.c21
-rw-r--r--src/merge.c14
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;