[PATCH] submodule merge support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When merge-recursive gets to a dirlink, it starts an automatic submodule merge
and then uses the resulting merge commit for the top-level tree.
The submodule merge is done in another process to decouple object databases.

Signed-off-by: Martin Waitz <tali@xxxxxxxxxxxxxx>
---
 .gitignore           |    1 +
 Makefile             |    2 +-
 git-dirlink-merge.sh |   28 ++++++++++++++++++++++++++++
 merge-recursive.c    |   36 ++++++++++++++++++++++++++++++++++++
 4 files changed, 66 insertions(+), 1 deletions(-)
 create mode 100644 git-dirlink-merge.sh

diff --git a/.gitignore b/.gitignore
index 8436a83..b076e2f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,6 +38,7 @@ git-diff-files
 git-diff-index
 git-diff-tree
 git-dirlink-checkout
+git-dirlink-merge
 git-describe
 git-fast-import
 git-fetch
diff --git a/Makefile b/Makefile
index fcd0125..ff24477 100644
--- a/Makefile
+++ b/Makefile
@@ -196,7 +196,7 @@ SCRIPT_SH = \
 	git-merge-one-file.sh git-mergetool.sh git-parse-remote.sh \
 	git-pull.sh git-rebase.sh \
 	git-repack.sh git-request-pull.sh git-reset.sh \
-	git-sh-setup.sh git-dirlink-checkout.sh \
+	git-sh-setup.sh git-dirlink-checkout.sh git-dirlink-merge.sh \
 	git-tag.sh git-verify-tag.sh \
 	git-applymbox.sh git-applypatch.sh git-am.sh \
 	git-merge.sh git-merge-stupid.sh git-merge-octopus.sh \
diff --git a/git-dirlink-merge.sh b/git-dirlink-merge.sh
new file mode 100644
index 0000000..e719b1a
--- /dev/null
+++ b/git-dirlink-merge.sh
@@ -0,0 +1,28 @@
+#!/bin/sh -e
+# Merge a submodule
+# (c) 2006 Martin Waitz
+
+USAGE="submodule orig-sha1 a-sha1 b-sha1"
+
+unset GIT_DIR
+cd "$1"
+
+. git-sh-setup
+
+test $# -eq 4 || usage
+
+orig="$2"
+ours="$3"
+theirs="$4"
+
+base=`git-merge-base "$ours" "$theirs"`
+
+if test `git-merge-base "$orig" "$base"` != "$orig"; then
+	die "$1 cannot be merged: other side switched branches"
+fi
+
+if test `git-rev-parse --verify HEAD` != "$ours"; then
+	die "$1: HEAD != ours"
+fi
+
+exec git-merge $theirs
diff --git a/merge-recursive.c b/merge-recursive.c
index 8f72b2c..4b67cd0 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -11,6 +11,7 @@
 #include "diff.h"
 #include "diffcore.h"
 #include "run-command.h"
+#include "refs.h"
 #include "tag.h"
 #include "unpack-trees.h"
 #include "path-list.h"
@@ -574,6 +575,21 @@ static void update_file_flags(const unsigned char *sha,
 		void *buf;
 		unsigned long size;
 
+		if (S_ISDIRLNK(mode)) {
+			/* defer dirlinks to another process, don't try to */
+			/* read the object "sha" here */
+			const char *dirlink_checkout[] = {
+				"dirlink-checkout", path, sha1_to_hex(sha), NULL
+			};
+			struct child_process cmd = {
+				.argv = dirlink_checkout,
+				.git_cmd = 1,
+			};
+
+			run_command(&cmd);
+			goto update_index;
+		}
+
 		buf = read_sha1_file(sha, &type, &size);
 		if (!buf)
 			die("cannot read object %s '%s'", sha1_to_hex(sha), path);
@@ -1069,6 +1085,26 @@ static struct merge_file_info merge_file(struct diff_filespec *o,
 
 			free(result_buf.ptr);
 			result.clean = (merge_status == 0);
+		} else if (S_ISDIRLNK(a->mode)) {
+			const char *dirlink_merge[] = {
+				"dirlink-merge", a->path,
+				sha1_to_hex(o->sha1),
+				sha1_to_hex(a->sha1),
+				sha1_to_hex(b->sha1),
+				NULL
+			};
+			struct child_process cmd = {
+				.argv = dirlink_merge,
+				.git_cmd = 1,
+			};
+			/* recurse into the submodule in a different process */
+			result.clean = !run_command(&cmd);
+			if (result.clean) {
+				/* get the new merged version */
+				if (resolve_gitlink_ref(a->path, "HEAD",
+				                        result.sha) < 0)
+					result.clean = 0;
+			}
 		} else {
 			if (!(S_ISLNK(a->mode) || S_ISLNK(b->mode)))
 				die("cannot merge modes?");
-- 
1.5.1.2.247.gaef5a


-- 
Martin Waitz
-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]