From: David Aguilar <davvid@gmail.com>
To: Jonathon Mah <me@JonathonMah.com>
Cc: git@vger.kernel.org, Charles Bailey <charles@hashpling.org>
Subject: Re: [PATCH] mergetool: Teach about submodules
Date: Sat, 9 Apr 2011 05:03:03 -0700 [thread overview]
Message-ID: <20110409120301.GA1369@gmail.com> (raw)
In-Reply-To: <1302321570-85987-1-git-send-email-me@JonathonMah.com>
I added Charles Bailey to the cc list.
On Fri, Apr 08, 2011 at 08:59:30PM -0700, Jonathon Mah wrote:
> 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>
> ---
This is a nice patch. It fixes a bug by introducing a great
new feature. Thank you.
One thing that could make it better, though, would be if it
also added tests for the feature to t/t7610-mergetool.sh.
That will help prevent someone (like me) from accidentally
breaking it in the future.
Cheers,
--
David
> 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 prev parent reply other threads:[~2011-04-09 12:03 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-04-09 3:59 [PATCH] mergetool: Teach about submodules Jonathon Mah
2011-04-09 12:03 ` David Aguilar [this message]
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=20110409120301.GA1369@gmail.com \
--to=davvid@gmail.com \
--cc=charles@hashpling.org \
--cc=git@vger.kernel.org \
--cc=me@JonathonMah.com \
/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).