From: Jonathon Mah <me@JonathonMah.com>
To: git@vger.kernel.org
Cc: Jonathon Mah <me@JonathonMah.com>
Subject: [PATCH] mergetool: Teach about submodules
Date: Fri, 8 Apr 2011 20:59:30 -0700 [thread overview]
Message-ID: <1302321570-85987-1-git-send-email-me@JonathonMah.com> (raw)
Mergetool mildly clobbered submodules, attempting to move and copy their
directories. It now recognizes submodules and offers a resolution:
Submodule merge conflict for 'Shared':
{local}: commit ad9f12e3e6205381bf2163a793d1e596a9e211d0
{remote}: commit f5893fb70ec5646efcd9aa643c5136753ac89253
Use (l)ocal or (r)emote, or (a)bort?
Selecting a commit will stage it, but not update the submodule (as it
would had there been no conflict). Type changes are also supported,
should the path be a submodule on one side, and a file on the other.
Signed-off-by: Jonathon Mah <me@JonathonMah.com>
---
git-mergetool.sh | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 64 insertions(+), 3 deletions(-)
diff --git a/git-mergetool.sh b/git-mergetool.sh
index bacbda2..83351d6 100755
--- a/git-mergetool.sh
+++ b/git-mergetool.sh
@@ -21,6 +21,10 @@ is_symlink () {
test "$1" = 120000
}
+is_submodule () {
+ test "$1" = 160000
+}
+
local_present () {
test -n "$local_mode"
}
@@ -52,6 +56,8 @@ describe_file () {
echo "deleted"
elif is_symlink "$mode" ; then
echo "a symbolic link -> '$(cat "$file")'"
+ elif is_submodule "$mode" ; then
+ echo "commit $file"
else
if base_present; then
echo "modified"
@@ -112,6 +118,51 @@ resolve_deleted_merge () {
done
}
+resolve_submodule_merge () {
+ while true; do
+ printf "Use (l)ocal or (r)emote, or (a)bort? "
+ read ans
+ case "$ans" in
+ [lL]*)
+ local_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==2) print $1;}')
+ if is_submodule "$local_mode"; then
+ stage_submodule "$MERGED" $(git ls-files -u -- "$MERGED" | awk '{if ($3==2) print $2;}')
+ else
+ git checkout-index -f --stage=2 -- "$MERGED"
+ git add -- "$MERGED"
+ fi
+ return 0
+ ;;
+ [rR]*)
+ remote_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==3) print $1;}')
+ if is_submodule "$remote_mode"; then
+ stage_submodule "$MERGED" $(git ls-files -u -- "$MERGED" | awk '{if ($3==3) print $2;}')
+ else
+ git checkout-index -f --stage=2 -- "$MERGED"
+ git add -- "$MERGED"
+ fi
+ return 0
+ ;;
+ [aA]*)
+ return 1
+ ;;
+ esac
+ done
+}
+
+stage_submodule () {
+ path="$1"
+ submodule_sha1="$2"
+
+ submodule_basename=$(basename "$path")
+ tree_with_module=$(echo "160000 commit $submodule_sha1 \"$submodule_basename\"" | git mktree --missing 2>/dev/null)
+ if test -z "$tree_with_module" ; then
+ echo "$path: unable to stage commit $sha1"
+ return 1
+ fi
+ git checkout $tree_with_module -- "$path"
+}
+
checkout_staged_file () {
tmpfile=$(expr "$(git checkout-index --temp --stage="$1" "$2")" : '\([^ ]*\) ')
@@ -139,13 +190,23 @@ merge_file () {
REMOTE="./$MERGED.REMOTE.$ext"
BASE="./$MERGED.BASE.$ext"
- mv -- "$MERGED" "$BACKUP"
- cp -- "$BACKUP" "$MERGED"
-
base_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==1) print $1;}')
local_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==2) print $1;}')
remote_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==3) print $1;}')
+ if is_submodule "$local_mode" || is_submodule "$remote_mode"; then
+ echo "Submodule merge conflict for '$MERGED':"
+ local_sha1=$(git ls-files -u -- "$MERGED" | awk '{if ($3==2) print $2;}')
+ remote_sha1=$(git ls-files -u -- "$MERGED" | awk '{if ($3==3) print $2;}')
+ describe_file "$local_mode" "local" "$local_sha1"
+ describe_file "$remote_mode" "remote" "$remote_sha1"
+ resolve_submodule_merge
+ return
+ fi
+
+ mv -- "$MERGED" "$BACKUP"
+ cp -- "$BACKUP" "$MERGED"
+
base_present && checkout_staged_file 1 "$MERGED" "$BASE"
local_present && checkout_staged_file 2 "$MERGED" "$LOCAL"
remote_present && checkout_staged_file 3 "$MERGED" "$REMOTE"
--
1.7.5.rc1.1.g64431
next reply other threads:[~2011-04-09 3:59 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-04-09 3:59 Jonathon Mah [this message]
2011-04-09 12:03 ` [PATCH] mergetool: Teach about submodules David Aguilar
2011-04-10 10:15 ` Jonathon Mah
2011-04-10 10:18 ` [PATCH] mergetool: Added tests for submodule Jonathon Mah
2011-04-11 19:53 ` [PATCH] mergetool: Teach about submodules Junio C Hamano
2011-04-13 10:00 ` Jonathon Mah
2011-04-13 10:00 ` [PATCH v2] " Jonathon Mah
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1302321570-85987-1-git-send-email-me@JonathonMah.com \
--to=me@jonathonmah.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).