]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'tr/submodule-relative-scp-url'
authorJunio C Hamano <gitster@pobox.com>
Thu, 13 Jan 2011 19:34:39 +0000 (11:34 -0800)
committerJunio C Hamano <gitster@pobox.com>
Thu, 13 Jan 2011 19:34:39 +0000 (11:34 -0800)
* tr/submodule-relative-scp-url:
  submodule: fix relative url parsing for scp-style origin

1  2 
git-submodule.sh
t/t7400-submodule-basic.sh

diff --combined git-submodule.sh
index c21b77aee54cd045b7bb64ae7337387569bbf65a,ac371e62536641df62e340d8f2105c9e9505a5a7..8b9058971767dbb4d94e996876f6ba7ed178ddd6
@@@ -5,7 -5,7 +5,7 @@@
  # Copyright (c) 2007 Lars Hjemli
  
  dashless=$(basename "$0" | sed -e 's/-/ /')
 -USAGE="[--quiet] add [-b branch] [--reference <repository>] [--] <repository> [<path>]
 +USAGE="[--quiet] add [-b branch] [-f|--force] [--reference <repository>] [--] <repository> [<path>]
     or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]
     or: $dashless [--quiet] init [--] [<path>...]
     or: $dashless [--quiet] update [--init] [-N|--no-fetch] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]
@@@ -19,7 -19,6 +19,7 @@@ require_work_tre
  
  command=
  branch=
 +force=
  reference=
  cached=
  recursive=
@@@ -37,12 -36,24 +37,24 @@@ resolve_relative_url (
                die "remote ($remote) does not have a url defined in .git/config"
        url="$1"
        remoteurl=${remoteurl%/}
+       sep=/
        while test -n "$url"
        do
                case "$url" in
                ../*)
                        url="${url#../}"
-                       remoteurl="${remoteurl%/*}"
+                       case "$remoteurl" in
+                       */*)
+                               remoteurl="${remoteurl%/*}"
+                               ;;
+                       *:*)
+                               remoteurl="${remoteurl%:*}"
+                               sep=:
+                               ;;
+                       *)
+                               die "cannot strip one component off url '$remoteurl'"
+                               ;;
+                       esac
                        ;;
                ./*)
                        url="${url#./}"
@@@ -51,7 -62,7 +63,7 @@@
                        break;;
                esac
        done
-       echo "$remoteurl/${url%/}"
+       echo "$remoteurl$sep${url%/}"
  }
  
  #
@@@ -93,6 -104,20 +105,6 @@@ module_clone(
        url=$2
        reference="$3"
  
 -      # If there already is a directory at the submodule path,
 -      # expect it to be empty (since that is the default checkout
 -      # action) and try to remove it.
 -      # Note: if $path is a symlink to a directory the test will
 -      # succeed but the rmdir will fail. We might want to fix this.
 -      if test -d "$path"
 -      then
 -              rmdir "$path" 2>/dev/null ||
 -              die "Directory '$path' exists, but is neither empty nor a git repository"
 -      fi
 -
 -      test -e "$path" &&
 -      die "A file already exist at path '$path'"
 -
        if test -n "$reference"
        then
                git-clone "$reference" -n "$url" "$path"
@@@ -120,9 -145,6 +132,9 @@@ cmd_add(
                        branch=$2
                        shift
                        ;;
 +              -f | --force)
 +                      force=$1
 +                      ;;
                -q|--quiet)
                        GIT_QUIET=1
                        ;;
        git ls-files --error-unmatch "$path" > /dev/null 2>&1 &&
        die "'$path' already exists in the index"
  
 +      if test -z "$force" && ! git add --dry-run --ignore-missing "$path" > /dev/null 2>&1
 +      then
 +              echo >&2 "The following path is ignored by one of your .gitignore files:" &&
 +              echo >&2 $path &&
 +              echo >&2 "Use -f if you really want to add it."
 +              exit 1
 +      fi
 +
        # perhaps the path exists and is already a git repo, else clone it
        if test -e "$path"
        then
                        # ash fails to wordsplit ${branch:+-b "$branch"...}
                        case "$branch" in
                        '') git checkout -f -q ;;
 -                      ?*) git checkout -f -q -b "$branch" "origin/$branch" ;;
 +                      ?*) git checkout -f -q -B "$branch" "origin/$branch" ;;
                        esac
                ) || die "Unable to checkout submodule '$path'"
        fi
  
 -      git add "$path" ||
 +      git add $force "$path" ||
        die "Failed to add submodule '$path'"
  
        git config -f .gitmodules submodule."$path".path "$path" &&
        git config -f .gitmodules submodule."$path".url "$repo" &&
 -      git add .gitmodules ||
 +      git add --force .gitmodules ||
        die "Failed to register submodule '$path'"
  }
  
@@@ -269,8 -283,6 +281,8 @@@ cmd_foreach(
                shift
        done
  
 +      toplevel=$(pwd)
 +
        module_list |
        while read mode sha1 stage path
        do
@@@ -360,35 -372,41 +372,35 @@@ cmd_init(
  cmd_update()
  {
        # parse $args after "submodule ... update".
 -      orig_args="$@"
 +      orig_flags=
        while test $# -ne 0
        do
                case "$1" in
                -q|--quiet)
 -                      shift
                        GIT_QUIET=1
                        ;;
                -i|--init)
                        init=1
 -                      shift
                        ;;
                -N|--no-fetch)
 -                      shift
                        nofetch=1
                        ;;
                -r|--rebase)
 -                      shift
                        update="rebase"
                        ;;
                --reference)
                        case "$2" in '') usage ;; esac
                        reference="--reference=$2"
 -                      shift 2
 +                      orig_flags="$orig_flags $(git rev-parse --sq-quote "$1")"
 +                      shift
                        ;;
                --reference=*)
                        reference="$1"
 -                      shift
                        ;;
                -m|--merge)
 -                      shift
                        update="merge"
                        ;;
                --recursive)
 -                      shift
                        recursive=1
                        ;;
                --)
                        break
                        ;;
                esac
 +              orig_flags="$orig_flags $(git rev-parse --sq-quote "$1")"
 +              shift
        done
  
        if test -n "$init"
  
                if test -n "$recursive"
                then
 -                      (clear_local_git_env; cd "$path" && cmd_update $orig_args) ||
 +                      (clear_local_git_env; cd "$path" && eval cmd_update "$orig_flags") ||
                        die "Failed to recurse into submodule path '$path'"
                fi
        done
@@@ -551,17 -567,12 +563,17 @@@ cmd_summary() 
  
        test $summary_limit = 0 && return
  
 -      if rev=$(git rev-parse -q --verify "$1^0")
 +      if rev=$(git rev-parse -q --verify --default HEAD ${1+"$1"})
        then
                head=$rev
 -              shift
 +              test $# = 0 || shift
 +      elif test -z "$1" -o "$1" = "HEAD"
 +      then
 +              # before the first commit: compare with an empty tree
 +              head=$(git hash-object -w -t tree --stdin </dev/null)
 +              test -z "$1" || shift
        else
 -              head=HEAD
 +              head="HEAD"
        fi
  
        if [ -n "$files" ]
  
        cd_to_toplevel
        # Get modified modules cared by user
 -      modules=$(git $diff_cmd $cached --raw $head -- "$@" |
 +      modules=$(git $diff_cmd $cached --ignore-submodules=dirty --raw $head -- "$@" |
                sane_egrep '^:([0-7]* )?160000' |
                while read mod_src mod_dst sha1_src sha1_dst status name
                do
  
        test -z "$modules" && return
  
 -      git $diff_cmd $cached --raw $head -- $modules |
 +      git $diff_cmd $cached --ignore-submodules=dirty --raw $head -- $modules |
        sane_egrep '^:([0-7]* )?160000' |
        cut -c2- |
        while read mod_src mod_dst sha1_src sha1_dst status name
                                range=$sha1_dst
                        fi
                        GIT_DIR="$name/.git" \
 -                      git log --pretty=oneline --first-parent $range | wc -l
 +                      git rev-list --first-parent $range -- | wc -l
                        )
                        total_commits=" ($(($total_commits + 0)))"
                        ;;
  cmd_status()
  {
        # parse $args after "submodule ... status".
 -      orig_args="$@"
 +      orig_flags=
        while test $# -ne 0
        do
                case "$1" in
                        break
                        ;;
                esac
 +              orig_flags="$orig_flags $(git rev-parse --sq-quote "$1")"
                shift
        done
  
                        continue;
                fi
                set_name_rev "$path" "$sha1"
 -              if git diff-files --quiet -- "$path"
 +              if git diff-files --ignore-submodules=dirty --quiet -- "$path"
                then
                        say " $sha1 $displaypath$revname"
                else
                                prefix="$displaypath/"
                                clear_local_git_env
                                cd "$path" &&
 -                              cmd_status $orig_args
 +                              eval cmd_status "$orig_args"
                        ) ||
                        die "Failed to recurse into submodule path '$path'"
                fi
@@@ -819,15 -829,13 +831,15 @@@ cmd_sync(
                        ;;
                esac
  
 +              say "Synchronizing submodule url for '$name'"
 +              git config submodule."$name".url "$url"
 +
                if test -e "$path"/.git
                then
                (
                        clear_local_git_env
                        cd "$path"
                        remote=$(get_default_remote)
 -                      say "Synchronizing submodule url for '$name'"
                        git config remote."$remote".url "$url"
                )
                fi
index 2c49db9f6244225db7f82b574f21f05b58bfdc26,8b004f60d68561d0a4d6701bfc0ad8525a596117..874279e32da98ac2c20137a207a0d115f073e444
@@@ -11,317 -11,226 +11,317 @@@ subcommands of git submodule
  
  . ./test-lib.sh
  
 -#
 -# Test setup:
 -#  -create a repository in directory init
 -#  -add a couple of files
 -#  -add directory init to 'superproject', this creates a DIRLINK entry
 -#  -add a couple of regular files to enable testing of submodule filtering
 -#  -mv init subrepo
 -#  -add an entry to .gitmodules for submodule 'example'
 -#
 -test_expect_success 'Prepare submodule testing' '
 -      : > t &&
 +test_expect_success 'setup - initial commit' '
 +      >t &&
        git add t &&
        git commit -m "initial commit" &&
 -      git branch initial HEAD &&
 +      git branch initial
 +'
 +
 +test_expect_success 'setup - repository in init subdirectory' '
        mkdir init &&
 -      cd init &&
 -      git init &&
 -      echo a >a &&
 -      git add a &&
 -      git commit -m "submodule commit 1" &&
 -      git tag -a -m "rev-1" rev-1 &&
 -      rev1=$(git rev-parse HEAD) &&
 -      if test -z "$rev1"
 -      then
 -              echo "[OOPS] submodule git rev-parse returned nothing"
 -              false
 -      fi &&
 -      cd .. &&
 +      (
 +              cd init &&
 +              git init &&
 +              echo a >a &&
 +              git add a &&
 +              git commit -m "submodule commit 1" &&
 +              git tag -a -m "rev-1" rev-1
 +      )
 +'
 +
 +test_expect_success 'setup - commit with gitlink' '
        echo a >a &&
        echo z >z &&
        git add a init z &&
 -      git commit -m "super commit 1" &&
 -      mv init .subrepo &&
 -      GIT_CONFIG=.gitmodules git config submodule.example.url git://example.com/init.git
 +      git commit -m "super commit 1"
 +'
 +
 +test_expect_success 'setup - hide init subdirectory' '
 +      mv init .subrepo
  '
  
 -test_expect_success 'Prepare submodule add testing' '
 -      submodurl=$(pwd)
 +test_expect_success 'setup - repository to add submodules to' '
 +      git init addtest &&
 +      git init addtest-ignore
 +'
 +
 +# The 'submodule add' tests need some repository to add as a submodule.
 +# The trash directory is a good one as any.
 +submodurl=$TRASH_DIRECTORY
 +
 +listbranches() {
 +      git for-each-ref --format='%(refname)' 'refs/heads/*'
 +}
 +
 +inspect() {
 +      dir=$1 &&
 +      dotdot="${2:-..}" &&
 +
        (
 -              mkdir addtest &&
 -              cd addtest &&
 -              git init
 +              cd "$dir" &&
 +              listbranches >"$dotdot/heads" &&
 +              { git symbolic-ref HEAD || :; } >"$dotdot/head" &&
 +              git rev-parse HEAD >"$dotdot/head-sha1" &&
 +              git update-index --refresh &&
 +              git diff-files --exit-code &&
 +              git clean -n -d -x >"$dotdot/untracked"
        )
 -'
 +}
  
  test_expect_success 'submodule add' '
 +      echo "refs/heads/master" >expect &&
 +      >empty &&
 +
        (
                cd addtest &&
                git submodule add "$submodurl" submod &&
                git submodule init
 +      ) &&
 +
 +      rm -f heads head untracked &&
 +      inspect addtest/submod ../.. &&
 +      test_cmp expect heads &&
 +      test_cmp expect head &&
 +      test_cmp empty untracked
 +'
 +
 +test_expect_success 'submodule add to .gitignored path fails' '
 +      (
 +              cd addtest-ignore &&
 +              cat <<-\EOF >expect &&
 +              The following path is ignored by one of your .gitignore files:
 +              submod
 +              Use -f if you really want to add it.
 +              EOF
 +              # Does not use test_commit due to the ignore
 +              echo "*" > .gitignore &&
 +              git add --force .gitignore &&
 +              git commit -m"Ignore everything" &&
 +              ! git submodule add "$submodurl" submod >actual 2>&1 &&
 +              test_cmp expect actual
 +      )
 +'
 +
 +test_expect_success 'submodule add to .gitignored path with --force' '
 +      (
 +              cd addtest-ignore &&
 +              git submodule add --force "$submodurl" submod
        )
  '
  
  test_expect_success 'submodule add --branch' '
 +      echo "refs/heads/initial" >expect-head &&
 +      cat <<-\EOF >expect-heads &&
 +      refs/heads/initial
 +      refs/heads/master
 +      EOF
 +      >empty &&
 +
        (
                cd addtest &&
                git submodule add -b initial "$submodurl" submod-branch &&
 -              git submodule init &&
 -              cd submod-branch &&
 -              git branch | grep initial
 -      )
 +              git submodule init
 +      ) &&
 +
 +      rm -f heads head untracked &&
 +      inspect addtest/submod-branch ../.. &&
 +      test_cmp expect-heads heads &&
 +      test_cmp expect-head head &&
 +      test_cmp empty untracked
  '
  
  test_expect_success 'submodule add with ./ in path' '
 +      echo "refs/heads/master" >expect &&
 +      >empty &&
 +
        (
                cd addtest &&
                git submodule add "$submodurl" ././dotsubmod/./frotz/./ &&
                git submodule init
 -      )
 +      ) &&
 +
 +      rm -f heads head untracked &&
 +      inspect addtest/dotsubmod/frotz ../../.. &&
 +      test_cmp expect heads &&
 +      test_cmp expect head &&
 +      test_cmp empty untracked
  '
  
  test_expect_success 'submodule add with // in path' '
 +      echo "refs/heads/master" >expect &&
 +      >empty &&
 +
        (
                cd addtest &&
                git submodule add "$submodurl" slashslashsubmod///frotz// &&
                git submodule init
 -      )
 +      ) &&
 +
 +      rm -f heads head untracked &&
 +      inspect addtest/slashslashsubmod/frotz ../../.. &&
 +      test_cmp expect heads &&
 +      test_cmp expect head &&
 +      test_cmp empty untracked
  '
  
  test_expect_success 'submodule add with /.. in path' '
 +      echo "refs/heads/master" >expect &&
 +      >empty &&
 +
        (
                cd addtest &&
                git submodule add "$submodurl" dotdotsubmod/../realsubmod/frotz/.. &&
                git submodule init
 -      )
 +      ) &&
 +
 +      rm -f heads head untracked &&
 +      inspect addtest/realsubmod ../.. &&
 +      test_cmp expect heads &&
 +      test_cmp expect head &&
 +      test_cmp empty untracked
  '
  
  test_expect_success 'submodule add with ./, /.. and // in path' '
 +      echo "refs/heads/master" >expect &&
 +      >empty &&
 +
        (
                cd addtest &&
                git submodule add "$submodurl" dot/dotslashsubmod/./../..////realsubmod2/a/b/c/d/../../../../frotz//.. &&
                git submodule init
 -      )
 +      ) &&
 +
 +      rm -f heads head untracked &&
 +      inspect addtest/realsubmod2 ../.. &&
 +      test_cmp expect heads &&
 +      test_cmp expect head &&
 +      test_cmp empty untracked
 +'
 +
 +test_expect_success 'setup - add an example entry to .gitmodules' '
 +      GIT_CONFIG=.gitmodules \
 +      git config submodule.example.url git://example.com/init.git
  '
  
  test_expect_success 'status should fail for unmapped paths' '
 -      if git submodule status
 -      then
 -              echo "[OOPS] submodule status succeeded"
 -              false
 -      elif ! GIT_CONFIG=.gitmodules git config submodule.example.path init
 -      then
 -              echo "[OOPS] git config failed to update .gitmodules"
 -              false
 -      fi
 +      test_must_fail git submodule status
 +'
 +
 +test_expect_success 'setup - map path in .gitmodules' '
 +      cat <<\EOF >expect &&
 +[submodule "example"]
 +      url = git://example.com/init.git
 +      path = init
 +EOF
 +
 +      GIT_CONFIG=.gitmodules git config submodule.example.path init &&
 +
 +      test_cmp expect .gitmodules
  '
  
  test_expect_success 'status should only print one line' '
 -      lines=$(git submodule status | wc -l) &&
 -      test $lines = 1
 +      git submodule status >lines &&
 +      test $(wc -l <lines) = 1
 +'
 +
 +test_expect_success 'setup - fetch commit name from submodule' '
 +      rev1=$(cd .subrepo && git rev-parse HEAD) &&
 +      printf "rev1: %s\n" "$rev1" &&
 +      test -n "$rev1"
  '
  
  test_expect_success 'status should initially be "missing"' '
 -      git submodule status | grep "^-$rev1"
 +      git submodule status >lines &&
 +      grep "^-$rev1" lines
  '
  
  test_expect_success 'init should register submodule url in .git/config' '
 +      echo git://example.com/init.git >expect &&
 +
        git submodule init &&
 -      url=$(git config submodule.example.url) &&
 -      if test "$url" != "git://example.com/init.git"
 -      then
 -              echo "[OOPS] init succeeded but submodule url is wrong"
 -              false
 -      elif test_must_fail git config submodule.example.url ./.subrepo
 -      then
 -              echo "[OOPS] init succeeded but update of url failed"
 -              false
 -      fi
 +      git config submodule.example.url >url &&
 +      git config submodule.example.url ./.subrepo &&
 +
 +      test_cmp expect url
  '
  
  test_expect_success 'update should fail when path is used by a file' '
 +      echo hello >expect &&
 +
        echo "hello" >init &&
 -      if git submodule update
 -      then
 -              echo "[OOPS] update should have failed"
 -              false
 -      elif test "$(cat init)" != "hello"
 -      then
 -              echo "[OOPS] update failed but init file was molested"
 -              false
 -      else
 -              rm init
 -      fi
 +      test_must_fail git submodule update &&
 +
 +      test_cmp expect init
  '
  
  test_expect_success 'update should fail when path is used by a nonempty directory' '
 +      echo hello >expect &&
 +
 +      rm -fr init &&
        mkdir init &&
        echo "hello" >init/a &&
 -      if git submodule update
 -      then
 -              echo "[OOPS] update should have failed"
 -              false
 -      elif test "$(cat init/a)" != "hello"
 -      then
 -              echo "[OOPS] update failed but init/a was molested"
 -              false
 -      else
 -              rm init/a
 -      fi
 +
 +      test_must_fail git submodule update &&
 +
 +      test_cmp expect init/a
  '
  
  test_expect_success 'update should work when path is an empty dir' '
 -      rm -rf init &&
 +      rm -fr init &&
 +      rm -f head-sha1 &&
 +      echo "$rev1" >expect &&
 +
        mkdir init &&
        git submodule update &&
 -      head=$(cd init && git rev-parse HEAD) &&
 -      if test -z "$head"
 -      then
 -              echo "[OOPS] Failed to obtain submodule head"
 -              false
 -      elif test "$head" != "$rev1"
 -      then
 -              echo "[OOPS] Submodule head is $head but should have been $rev1"
 -              false
 -      fi
 +
 +      inspect init &&
 +      test_cmp expect head-sha1
  '
  
  test_expect_success 'status should be "up-to-date" after update' '
 -      git submodule status | grep "^ $rev1"
 +      git submodule status >list &&
 +      grep "^ $rev1" list
  '
  
  test_expect_success 'status should be "modified" after submodule commit' '
 -      cd init &&
 -      echo b >b &&
 -      git add b &&
 -      git commit -m "submodule commit 2" &&
 -      rev2=$(git rev-parse HEAD) &&
 -      cd .. &&
 -      if test -z "$rev2"
 -      then
 -              echo "[OOPS] submodule git rev-parse returned nothing"
 -              false
 -      fi &&
 -      git submodule status | grep "^+$rev2"
 +      (
 +              cd init &&
 +              echo b >b &&
 +              git add b &&
 +              git commit -m "submodule commit 2"
 +      ) &&
 +
 +      rev2=$(cd init && git rev-parse HEAD) &&
 +      test -n "$rev2" &&
 +      git submodule status >list &&
 +
 +      grep "^+$rev2" list
  '
  
  test_expect_success 'the --cached sha1 should be rev1' '
 -      git submodule --cached status | grep "^+$rev1"
 +      git submodule --cached status >list &&
 +      grep "^+$rev1" list
  '
  
  test_expect_success 'git diff should report the SHA1 of the new submodule commit' '
 -      git diff | grep "^+Subproject commit $rev2"
 +      git diff >diff &&
 +      grep "^+Subproject commit $rev2" diff
  '
  
  test_expect_success 'update should checkout rev1' '
 +      rm -f head-sha1 &&
 +      echo "$rev1" >expect &&
 +
        git submodule update init &&
 -      head=$(cd init && git rev-parse HEAD) &&
 -      if test -z "$head"
 -      then
 -              echo "[OOPS] submodule git rev-parse returned nothing"
 -              false
 -      elif test "$head" != "$rev1"
 -      then
 -              echo "[OOPS] init did not checkout correct head"
 -              false
 -      fi
 +      inspect init &&
 +
 +      test_cmp expect head-sha1
  '
  
  test_expect_success 'status should be "up-to-date" after update' '
 -      git submodule status | grep "^ $rev1"
 +      git submodule status >list &&
 +      grep "^ $rev1" list
  '
  
  test_expect_success 'checkout superproject with subproject already present' '
  '
  
  test_expect_success 'apply submodule diff' '
 +      >empty &&
 +
        git branch second &&
        (
                cd init &&
        git format-patch -1 --stdout >P.diff &&
        git checkout second &&
        git apply --index P.diff &&
 -      D=$(git diff --cached master) &&
 -      test -z "$D"
 +
 +      git diff --cached master >staged &&
 +      test_cmp empty staged
  '
  
  test_expect_success 'update --init' '
 -
        mv init init2 &&
        git config -f .gitmodules submodule.example.url "$(pwd)/init2" &&
 -      git config --remove-section submodule.example
 +      git config --remove-section submodule.example &&
 +      test_must_fail git config submodule.example.url &&
 +
        git submodule update init > update.out &&
 +      cat update.out &&
        grep "not initialized" update.out &&
 -      test ! -d init/.git &&
 +      ! test -d init/.git &&
 +
        git submodule update --init init &&
        test -d init/.git
 -
  '
  
  test_expect_success 'do not add files from a submodule' '
@@@ -413,37 -317,56 +413,75 @@@ test_expect_success 'submodule <invalid
  
  test_expect_success 'add submodules without specifying an explicit path' '
        mkdir repo &&
 -      cd repo &&
 -      git init &&
 -      echo r >r &&
 -      git add r &&
 -      git commit -m "repo commit 1" &&
 -      cd .. &&
 +      (
 +              cd repo &&
 +              git init &&
 +              echo r >r &&
 +              git add r &&
 +              git commit -m "repo commit 1"
 +      ) &&
        git clone --bare repo/ bare.git &&
 -      cd addtest &&
 -      git submodule add "$submodurl/repo" &&
 -      git config -f .gitmodules submodule.repo.path repo &&
 -      git submodule add "$submodurl/bare.git" &&
 -      git config -f .gitmodules submodule.bare.path bare
 +      (
 +              cd addtest &&
 +              git submodule add "$submodurl/repo" &&
 +              git config -f .gitmodules submodule.repo.path repo &&
 +              git submodule add "$submodurl/bare.git" &&
 +              git config -f .gitmodules submodule.bare.path bare
 +      )
 +'
 +
 +test_expect_success 'add should fail when path is used by a file' '
 +      (
 +              cd addtest &&
 +              touch file &&
 +              test_must_fail  git submodule add "$submodurl/repo" file
 +      )
 +'
 +
 +test_expect_success 'add should fail when path is used by an existing directory' '
 +      (
 +              cd addtest &&
 +              mkdir empty-dir &&
 +              test_must_fail git submodule add "$submodurl/repo" empty-dir
 +      )
  '
  
+ test_expect_success 'set up for relative path tests' '
+       mkdir reltest &&
+       (
+               cd reltest &&
+               git init &&
+               mkdir sub &&
+               (
+                       cd sub &&
+                       git init &&
+                       test_commit foo
+               ) &&
+               git add sub &&
+               git config -f .gitmodules submodule.sub.path sub &&
+               git config -f .gitmodules submodule.sub.url ../subrepo &&
+               cp .git/config pristine-.git-config
+       )
+ '
+ test_expect_success 'relative path works with URL' '
+       (
+               cd reltest &&
+               cp pristine-.git-config .git/config &&
+               git config remote.origin.url ssh://hostname/repo &&
+               git submodule init &&
+               test "$(git config submodule.sub.url)" = ssh://hostname/subrepo
+       )
+ '
+ test_expect_success 'relative path works with user@host:path' '
+       (
+               cd reltest &&
+               cp pristine-.git-config .git/config &&
+               git config remote.origin.url user@host:repo &&
+               git submodule init &&
+               test "$(git config submodule.sub.url)" = user@host:subrepo
+       )
+ '
  test_done