Code

Merge branch 'sn/doc-update-index-assume-unchanged' into maint-1.7.3
[git.git] / git-submodule.sh
index 3319b836b217a26b4ac55ae5ced328ffafa0a015..9e752904b3d492ef899f172291160c88bf2fa51b 100755 (executable)
@@ -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,6 +19,7 @@ require_work_tree
 
 command=
 branch=
+force=
 reference=
 cached=
 recursive=
@@ -36,12 +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#./}"
@@ -50,7 +63,7 @@ resolve_relative_url ()
                        break;;
                esac
        done
-       echo "$remoteurl/${url%/}"
+       echo "$remoteurl$sep${url%/}"
 }
 
 #
@@ -92,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"
@@ -133,6 +132,9 @@ cmd_add()
                        branch=$2
                        shift
                        ;;
+               -f | --force)
+                       force=$1
+                       ;;
                -q|--quiet)
                        GIT_QUIET=1
                        ;;
@@ -201,6 +203,14 @@ cmd_add()
        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
@@ -229,17 +239,17 @@ cmd_add()
                        # 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'"
 }
 
@@ -271,6 +281,8 @@ cmd_foreach()
                shift
        done
 
+       toplevel=$(pwd)
+
        module_list |
        while read mode sha1 stage path
        do
@@ -578,7 +590,7 @@ cmd_summary() {
 
        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
@@ -592,7 +604,7 @@ cmd_summary() {
 
        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
@@ -650,7 +662,7 @@ cmd_summary() {
                                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)))"
                        ;;
@@ -758,7 +770,7 @@ cmd_status()
                        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
@@ -822,13 +834,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