Use Test Harness
[gitweb.git] / git-subtree.sh
index a86cfd8b9f8fd9a50e577f0612fea7a7a2b90213..920c664bb7c7a4e1aa455479e2caef3d6c6dc786 100755 (executable)
@@ -28,9 +28,11 @@ rejoin        merge the new branch back into HEAD
  options for 'add', 'merge', 'pull' and 'push'
 squash        merge subtree changes as a single commit
 "
-eval $(echo "$OPTS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?)
-PATH=$(git --exec-path):$PATH
+eval "$(echo "$OPTS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?)"
+
+PATH=$PATH:$(git --exec-path)
 . git-sh-setup
+
 require_work_tree
 
 quiet=
@@ -136,6 +138,7 @@ cache_setup()
        cachedir="$GIT_DIR/subtree-cache/$$"
        rm -rf "$cachedir" || die "Can't delete old cachedir: $cachedir"
        mkdir -p "$cachedir" || die "Can't create new cachedir: $cachedir"
+       mkdir -p "$cachedir/notree" || die "Can't create new cachedir: $cachedir/notree"
        debug "Using cachedir: $cachedir" >&2
 }
 
@@ -149,6 +152,30 @@ cache_get()
        done
 }
 
+cache_miss()
+{
+       for oldrev in $*; do
+               if [ ! -r "$cachedir/$oldrev" ]; then
+                       echo $oldrev
+               fi
+       done
+}
+
+check_parents()
+{
+       missed=$(cache_miss $*)
+       for miss in $missed; do
+               if [ ! -r "$cachedir/notree/$miss" ]; then
+                       debug "  incorrect order: $miss"
+               fi
+       done
+}
+
+set_notree()
+{
+       echo "1" > "$cachedir/notree/$1"
+}
+
 cache_set()
 {
        oldrev="$1"
@@ -370,7 +397,8 @@ subtree_for_commit()
        git ls-tree "$commit" -- "$dir" |
        while read mode type tree name; do
                assert [ "$name" = "$dir" ]
-               assert [ "$type" = "tree" ]
+               assert [ "$type" = "tree" -o "$type" = "commit" ]
+               [ "$type" = "commit" ] && continue  # ignore submodules
                echo $tree
                break
        done
@@ -545,7 +573,7 @@ cmd_split()
        # We can't restrict rev-list to only $dir here, because some of our
        # parents have the $dir contents the root, and those won't match.
        # (and rev-list --follow doesn't seem to solve this)
-       grl='git rev-list --reverse --parents $revs $unrevs'
+       grl='git rev-list --topo-order --reverse --parents $revs $unrevs'
        revmax=$(eval "$grl" | wc -l)
        revcount=0
        createcount=0
@@ -566,10 +594,13 @@ cmd_split()
                
                tree=$(subtree_for_commit $rev "$dir")
                debug "  tree is: $tree"
+
+               check_parents $parents
                
                # ugly.  is there no better way to tell if this is a subtree
                # vs. a mainline commit?  Does it matter?
                if [ -z $tree ]; then
+                       set_notree $rev
                        if [ -n "$newparents" ]; then
                                cache_set $rev $rev
                        fi