Add --reference option to git submodule.
authorMichael S. Tsirkin <mst@redhat.com>
Mon, 4 May 2009 19:30:01 +0000 (22:30 +0300)
committerJunio C Hamano <gitster@pobox.com>
Sat, 9 May 2009 15:27:52 +0000 (08:27 -0700)
This adds --reference option to git submodule add and
git submodule update commands, which is passed to git clone.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-submodule.txt
git-submodule.sh
t/t7406-submodule-reference.sh [new file with mode: 0755]
index 3b8df4467377d73d613f76875c725cbf8544ee77..14256c695b3817014be8ba4f45a62a2cd588939c 100644 (file)
@@ -9,10 +9,12 @@ git-submodule - Initialize, update or inspect submodules
 SYNOPSIS
 --------
 [verse]
 SYNOPSIS
 --------
 [verse]
-'git submodule' [--quiet] add [-b branch] [--] <repository> <path>
+'git submodule' [--quiet] add [-b branch]
+             [--reference <repository>] [--] <repository> <path>
 'git submodule' [--quiet] status [--cached] [--] [<path>...]
 'git submodule' [--quiet] init [--] [<path>...]
 'git submodule' [--quiet] status [--cached] [--] [<path>...]
 'git submodule' [--quiet] init [--] [<path>...]
-'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--] [<path>...]
+'git submodule' [--quiet] update [--init] [-N|--no-fetch]
+             [--reference <repository>] [--] [<path>...]
 'git submodule' [--quiet] summary [--summary-limit <n>] [commit] [--] [<path>...]
 'git submodule' [--quiet] foreach <command>
 'git submodule' [--quiet] sync [--] [<path>...]
 'git submodule' [--quiet] summary [--summary-limit <n>] [commit] [--] [<path>...]
 'git submodule' [--quiet] foreach <command>
 'git submodule' [--quiet] sync [--] [<path>...]
@@ -177,6 +179,14 @@ OPTIONS
        This option is only valid for the update command.
        Don't fetch new objects from the remote site.
 
        This option is only valid for the update command.
        Don't fetch new objects from the remote site.
 
+--reference <repository>::
+       This option is only valid for add and update commands.  These
+       commands sometimes need to clone a remote repository. In this case,
+       this option will be passed to the linkgit:git-clone[1] command.
++
+*NOTE*: Do *not* use this option unless you have read the note
+for linkgit:git-clone[1]'s --reference and --shared options carefully.
+
 <path>...::
        Paths to submodule(s). When specified this will restrict the command
        to only operate on the submodules found at the specified paths.
 <path>...::
        Paths to submodule(s). When specified this will restrict the command
        to only operate on the submodules found at the specified paths.
index 8e234a4028d22e11baedba11f871d33f56945716..ab1ed02a663b7e6252fe33f5224cb9653bcd50f2 100755 (executable)
@@ -15,6 +15,7 @@ require_work_tree
 command=
 branch=
 quiet=
 command=
 branch=
 quiet=
+reference=
 cached=
 nofetch=
 
 cached=
 nofetch=
 
@@ -91,6 +92,7 @@ module_clone()
 {
        path=$1
        url=$2
 {
        path=$1
        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
 
        # If there already is a directory at the submodule path,
        # expect it to be empty (since that is the default checkout
@@ -106,7 +108,12 @@ module_clone()
        test -e "$path" &&
        die "A file already exist at path '$path'"
 
        test -e "$path" &&
        die "A file already exist at path '$path'"
 
-       git-clone -n "$url" "$path" ||
+       if test -n "$reference"
+       then
+               git-clone "$reference" -n "$url" "$path"
+       else
+               git-clone -n "$url" "$path"
+       fi ||
        die "Clone of '$url' into submodule path '$path' failed"
 }
 
        die "Clone of '$url' into submodule path '$path' failed"
 }
 
@@ -131,6 +138,15 @@ cmd_add()
                -q|--quiet)
                        quiet=1
                        ;;
                -q|--quiet)
                        quiet=1
                        ;;
+               --reference)
+                       case "$2" in '') usage ;; esac
+                       reference="--reference=$2"
+                       shift
+                       ;;
+               --reference=*)
+                       reference="$1"
+                       shift
+                       ;;
                --)
                        shift
                        break
                --)
                        shift
                        break
@@ -203,7 +219,7 @@ cmd_add()
                git config submodule."$path".url "$url"
        else
 
                git config submodule."$path".url "$url"
        else
 
-               module_clone "$path" "$realrepo" || exit
+               module_clone "$path" "$realrepo" "$reference" || exit
                (
                        unset GIT_DIR
                        cd "$path" &&
                (
                        unset GIT_DIR
                        cd "$path" &&
@@ -314,13 +330,22 @@ cmd_update()
                        quiet=1
                        ;;
                -i|--init)
                        quiet=1
                        ;;
                -i|--init)
+                       init=1
                        shift
                        shift
-                       cmd_init "$@" || return
                        ;;
                -N|--no-fetch)
                        shift
                        nofetch=1
                        ;;
                        ;;
                -N|--no-fetch)
                        shift
                        nofetch=1
                        ;;
+               --reference)
+                       case "$2" in '') usage ;; esac
+                       reference="--reference=$2"
+                       shift 2
+                       ;;
+               --reference=*)
+                       reference="$1"
+                       shift
+                       ;;
                --)
                        shift
                        break
                --)
                        shift
                        break
@@ -334,6 +359,11 @@ cmd_update()
                esac
        done
 
                esac
        done
 
+       if test -n "$init"
+       then
+               cmd_init "--" "$@" || return
+       fi
+
        module_list "$@" |
        while read mode sha1 stage path
        do
        module_list "$@" |
        while read mode sha1 stage path
        do
@@ -351,7 +381,7 @@ cmd_update()
 
                if ! test -d "$path"/.git -o -f "$path"/.git
                then
 
                if ! test -d "$path"/.git -o -f "$path"/.git
                then
-                       module_clone "$path" "$url" || exit
+                       module_clone "$path" "$url" "$reference"|| exit
                        subsha1=
                else
                        subsha1=$(unset GIT_DIR; cd "$path" &&
                        subsha1=
                else
                        subsha1=$(unset GIT_DIR; cd "$path" &&
diff --git a/t/t7406-submodule-reference.sh b/t/t7406-submodule-reference.sh
new file mode 100755 (executable)
index 0000000..cc16d3f
--- /dev/null
@@ -0,0 +1,81 @@
+#!/bin/sh
+#
+# Copyright (c) 2009, Red Hat Inc, Author: Michael S. Tsirkin (mst@redhat.com)
+#
+
+test_description='test clone --reference'
+. ./test-lib.sh
+
+base_dir=`pwd`
+
+U=$base_dir/UPLOAD_LOG
+
+test_expect_success 'preparing first repository' \
+'test_create_repo A && cd A &&
+echo first > file1 &&
+git add file1 &&
+git commit -m A-initial'
+
+cd "$base_dir"
+
+test_expect_success 'preparing second repository' \
+'git clone A B && cd B &&
+echo second > file2 &&
+git add file2 &&
+git commit -m B-addition &&
+git repack -a -d &&
+git prune'
+
+cd "$base_dir"
+
+test_expect_success 'preparing supermodule' \
+'test_create_repo super && cd super &&
+echo file > file &&
+git add file &&
+git commit -m B-super-initial'
+
+cd "$base_dir"
+
+test_expect_success 'submodule add --reference' \
+'cd super && git submodule add --reference ../B "file://$base_dir/A" sub &&
+git commit -m B-super-added'
+
+cd "$base_dir"
+
+test_expect_success 'after add: existence of info/alternates' \
+'test `wc -l <super/sub/.git/objects/info/alternates` = 1'
+
+cd "$base_dir"
+
+test_expect_success 'that reference gets used with add' \
+'cd super/sub &&
+echo "0 objects, 0 kilobytes" > expected &&
+git count-objects > current &&
+diff expected current'
+
+cd "$base_dir"
+
+test_expect_success 'cloning supermodule' \
+'git clone super super-clone'
+
+cd "$base_dir"
+
+test_expect_success 'update with reference' \
+'cd super-clone && git submodule update --init --reference ../B'
+
+cd "$base_dir"
+
+test_expect_success 'after update: existence of info/alternates' \
+'test `wc -l <super-clone/sub/.git/objects/info/alternates` = 1'
+
+cd "$base_dir"
+
+test_expect_success 'that reference gets used with update' \
+'cd super-clone/sub &&
+echo "0 objects, 0 kilobytes" > expected &&
+git count-objects > current &&
+diff expected current'
+
+cd "$base_dir"
+
+test_done