Hmm... can't actually filter rev-list on the subdir name.
[gitweb.git] / git-subtree.sh
index a31b0b2f6a6ebc11e1c21c61a934ddb68d7275da..1e1237f52006db612a4e69d1565672456bc07854 100755 (executable)
@@ -13,7 +13,7 @@ git subtree does foo and bar!
 h,help   show the help
 q        quiet
 v        verbose
-onto=    existing subtree revision to connect, if any
+onto=    existing subtree revision to search for parent
 rejoin   merge the new branch back into HEAD
 "
 eval $(echo "$OPTS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?)
@@ -46,7 +46,6 @@ assert()
 
 while [ $# -gt 0 ]; do
        opt="$1"
-       debug "option: $1"
        shift
        case "$opt" in
                -q) quiet=1 ;;
@@ -108,6 +107,30 @@ cache_set()
        echo "$newrev" >"$cachedir/$oldrev"
 }
 
+find_existing_splits()
+{
+       debug "Looking for prior splits..."
+       dir="$1"
+       revs="$2"
+       git log --grep="^git-subtree-dir: $dir\$" \
+               --pretty=format:'%s%n%n%b%nEND' "$revs" |
+       while read a b junk; do
+               case "$a" in
+                       git-subtree-mainline:) main="$b" ;;
+                       git-subtree-split:) sub="$b" ;;
+                       *)
+                               if [ -n "$main" -a -n "$sub" ]; then
+                                       debug "  Prior: $main -> $sub"
+                                       cache_set $main $sub
+                                       echo "^$main^ ^$sub^"
+                                       main=
+                                       sub=
+                               fi
+                               ;;
+               esac
+       done
+}
+
 copy_commit()
 {
        # We're doing to set some environment vars here, so
@@ -136,10 +159,11 @@ merge_msg()
        latest_old="$2"
        latest_new="$3"
        cat <<-EOF
-               Split changes from '$dir/' into commit '$latest_new'
+               Split '$dir/' into commit '$latest_new'
                
                git-subtree-dir: $dir
-               git-subtree-includes: $latest_old
+               git-subtree-mainline: $latest_old
+               git-subtree-split: $latest_new
        EOF
 }
 
@@ -148,11 +172,32 @@ cmd_split()
        debug "Splitting $dir..."
        cache_setup || exit $?
        
-       git rev-list --reverse --parents $revs -- "$dir" |
+       if [ -n "$onto" ]; then
+               echo "Reading history for --onto=$onto..."
+               git rev-list $onto |
+               while read rev; do
+                       # the 'onto' history is already just the subdir, so
+                       # any parent we find there can be used verbatim
+                       debug "  cache: $rev"
+                       cache_set $rev $rev
+               done
+       fi
+       
+       unrevs="$(find_existing_splits "$dir" "$revs")"
+       
+       debug "git rev-list --reverse $revs $unrevs"
+       git rev-list --reverse --parents $revs $unrevsx |
        while read rev parents; do
-               newparents=$(cache_get $parents)
                debug
-               debug "Processing commit: $rev / $newparents"
+               debug "Processing commit: $rev"
+               exists=$(cache_get $rev)
+               if [ -n "$exists" ]; then
+                       debug "  prior: $exists"
+                       continue
+               fi
+               debug "  parents: $parents"
+               newparents=$(cache_get $parents)
+               debug "  newparents: $newparents"
                
                git ls-tree $rev -- "$dir" |
                while read mode type tree name; do