- Most of the changes are taken from helmo’s repository from following
URL:
https://github.com/helmo/git-subtree/blob/master/git-subtree.sh
- Add code to create a file named .gittrees which can store information
on the subtree that is getting merged to the super-repository. The
advantage is ‘subtree push’ and ‘subtree pull’ subcommands can be
called with only the —prefix option and no need to provide remote url
- Add tests for new feature additions. All existing and new tests pass
successfully
Files changed in this commit:
1. git/contrib/subtree/git-subtree.sh
2. git/contrib/subtree/t/t7900-subtree.sh

Signed-off-by: Keval Patel <kapa...@lutron.com>
---
A selection of updates to git-subtree were offered to the list by couple of 
people
($gmane/196667) by Herman van Rink and ($gmane/217820) by Paul Campbell
For various reasons the work stalled and I would like to pick it up from there

The following patches take a selection of these commits and rebase them 
against the tip of master.
The make test works and I have added more tests to cover the new commands and 
use of .gittrees file for storing the subtree metadata

Thanks-to and Based-on-patch-by:
- Herman van Rink
- Matt Hoffman
- Michael Hart
- Nate Jones
- Paul Campbell
- Paul Cartwright
- Peter Jaros
- bibendi

 contrib/subtree/git-subtree.sh     |   98 +++++++++++++++++++++------------
 contrib/subtree/t/t7900-subtree.sh |  106 ++++++++++++++++++++++++++++++++++++
 2 files changed, 168 insertions(+), 36 deletions(-)

diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index db925ca..7d01b4b 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -8,8 +8,7 @@ if [ $# -eq 0 ]; then
     set -- -h
 fi
 OPTS_SPEC="\
-git subtree add   --prefix=<prefix> <commit>
-git subtree add   --prefix=<prefix> <repository> <ref>
+git subtree add   --prefix=<prefix> <repository> <refspec>
 git subtree merge --prefix=<prefix> <commit>
 git subtree pull  --prefix=<prefix> <repository> <ref>
 git subtree push  --prefix=<prefix> <repository> <ref>
@@ -490,12 +489,6 @@ ensure_clean()
        fi
 }
 
-ensure_valid_ref_format()
-{
-       git check-ref-format "refs/heads/$1" ||
-           die "'$1' does not look like a ref"
-}
-
 cmd_add()
 {
        if [ -e "$dir" ]; then
@@ -505,22 +498,12 @@ cmd_add()
        ensure_clean
        
        if [ $# -eq 1 ]; then
-           git rev-parse -q --verify "$1^{commit}" >/dev/null ||
-           die "'$1' does not refer to a commit"
-
-           "cmd_add_commit" "$@"
+               "cmd_add_commit" "$@"
        elif [ $# -eq 2 ]; then
-           # Technically we could accept a refspec here but we're
-           # just going to turn around and add FETCH_HEAD under the
-           # specified directory.  Allowing a refspec might be
-           # misleading because we won't do anything with any other
-           # branches fetched via the refspec.
-           ensure_valid_ref_format "$2"
-
-           "cmd_add_repository" "$@"
+               "cmd_add_repository" "$@"
        else
-           say "error: parameters were '$@'"
-           die "Provide either a commit or a repository and commit."
+               say "error: parameters were '$@'"
+               die "Provide either a refspec or a repository and refspec."
        fi
 }
 
@@ -533,6 +516,24 @@ cmd_add_repository()
        revs=FETCH_HEAD
        set -- $revs
        cmd_add_commit "$@"
+       
+       revs=$(git rev-parse $default --revs-only "$@") || exit $?
+       set -- $revs
+       rev="$1"
+       
+       subtree_mainline_merge=$(git rev-parse HEAD) || exit $?
+       
+       # now add it to our list of repos 
+       git config -f .gittrees --unset subtree.$dir.url
+       git config -f .gittrees --add subtree.$dir.url $repository
+       git config -f .gittrees --unset subtree.$dir.path
+       git config -f .gittrees --add subtree.$dir.path $dir
+       git config -f .gittrees --unset subtree.$dir.branch
+       git config -f .gittrees --add subtree.$dir.branch $refspec
+       git config -f .gittrees --unset subtree.$dir.subtreeCommit
+       git config -f .gittrees --add subtree.$dir.subtreeCommit $rev
+       git config -f .gittrees --unset subtree.$dir.subtreeMergeCommit
+       git config -f .gittrees --add subtree.$dir.subtreeMergeCommit 
$subtree_mainline_merge
 }
 
 cmd_add_commit()
@@ -598,7 +599,7 @@ cmd_split()
        eval "$grl" |
        while read rev parents; do
                revcount=$(($revcount + 1))
-               say -n "$revcount/$revmax ($createcount)
"
+               say -n "$revcount/$revmax ($createcount)"
                debug "Processing commit: $rev"
                exists=$(cache_get $rev)
                if [ -n "$exists" ]; then
@@ -705,31 +706,56 @@ cmd_merge()
 
 cmd_pull()
 {
-       if [ $# -ne 2 ]; then
-           die "You must provide <repository> <ref>"
+       if [ $# -gt 2 ]; then
+               die "You should provide either <refspec> or <repository> 
<refspec>"
        fi
+       if [ -e "$dir" ]; then
        ensure_clean
-       ensure_valid_ref_format "$2"
-       git fetch "$@" || exit $?
+               if [ $# -eq 1 ]; then 
+                       repository=$(git config -f .gittrees 
subtree.$prefix.url)
+                       refspec=$1
+               elif [ $# -eq 2 ]; then 
+                       repository=$1
+                       refspec=$2
+               else 
+                       repository=$(git config -f .gittrees 
subtree.$prefix.url)
+                       refspec=$(git config -f .gittrees 
subtree.$prefix.branch)
+               fi
+               git fetch $repository $refspec || exit $?
+               echo "git fetch using: " $repository $refspec
        revs=FETCH_HEAD
        set -- $revs
        cmd_merge "$@"
+       else
+               die "'$dir' must already exist. Try 'git subtree add'."
+       fi
 }
 
 cmd_push()
 {
-       if [ $# -ne 2 ]; then
-           die "You must provide <repository> <ref>"
+       if [ $# -gt 2 ]; then
+               die "You should provide either <refspec> or <repository> 
<refspec>"
        fi
-       ensure_valid_ref_format "$2"
        if [ -e "$dir" ]; then
-           repository=$1
-           refspec=$2
-           echo "git push using: " $repository $refspec
-           localrev=$(git subtree split --prefix="$prefix") || die
-           git push $repository $localrev:refs/heads/$refspec
+               if [ $# -eq 1 ]; then 
+                       repository=$(git config -f .gittrees 
subtree.$prefix.url)
+                       refspec=$1
+               elif [ $# -eq 2 ]; then 
+               repository=$1
+               refspec=$2
+               else
+                       repository=$(git config -f .gittrees 
subtree.$prefix.url)
+                       refspec=$(git config -f .gittrees 
subtree.$prefix.branch)
+               fi
+               echo "git push using: " $repository $refspec
+               rev=$(git subtree split --prefix=$prefix)
+               if [ -n "$rev" ]; then
+                       git push $repository $rev:refs/heads/$refspec
+               else
+                       die "Couldn't push, 'git subtree split' failed."
+               fi
        else
-           die "'$dir' must already exist. Try 'git subtree add'."
+               die "'$dir' must already exist. Try 'git subtree add'."
        fi
 }
 
diff --git a/contrib/subtree/t/t7900-subtree.sh 
b/contrib/subtree/t/t7900-subtree.sh
index 66ce4b0..05110f7 100755
--- a/contrib/subtree/t/t7900-subtree.sh
+++ b/contrib/subtree/t/t7900-subtree.sh
@@ -60,6 +60,11 @@ last_commit_message()
        git log --pretty=format:%s -1
 }
 
+last_commit_id()
+{
+    git log --format="%H" -n 1
+}
+
 test_expect_success 'init subproj' '
         test_create_repo subproj
 '
@@ -464,5 +469,106 @@ test_expect_success 'verify one file change per commit' '
                check_equal "$x" 1
         ))
 '
+# Tests for subtree add which creates .gittrees for storing metadata
+
+# Back to mainline and create new directory for testing
+cd ../..
+
+mkdir test_sub
+cd test_sub
+
+mkdir shared_projects
+# To shared_projects!
+cd shared_projects
+
+# Create couple of Git repos in shared_projects folder which can be
+# added as subtrees to our parent projects
+test_expect_success 'add subtree1' '
+        test_create_repo subtree1 &&
+        cd subtree1 &&
+        create sub1_file1 &&
+        git commit -m "Initial subtree1 commit"
+'
+
+# Store the latest commit value for future use
+expected_subtreeCommit=`echo $(last_commit_id)`
+expected_branch=`echo $(git rev-parse --abbrev-ref HEAD)`
+
+# Back to shared_projects
+cd ..
+
+test_expect_success 'add subtree2' '
+        test_create_repo subtree2 &&
+        cd subtree2 &&
+        create sub2_file1 &&
+        git commit -m "Initial subtree2 commit"
+'
+
+# Back to test_sub
+cd ../..
+
+# Create test parent repos that will add subtrees to itself
+test_expect_success 'add parent1' '
+        test_create_repo parent1 &&
+        cd parent1 &&
+        create parent1_file1 &&
+        git commit -m "Initial parent1 commit"
+'
+
+# Back to test_sub from parent1
+cd ..
+
+test_expect_success 'add parent2' '
+        test_create_repo parent2 &&
+        cd parent2 &&
+        create parent2_file1 &&
+        git commit -m "Initial parent2 commit"
+'
+
+
+# To parent1 now. Start the tests
+cd ../parent1
+
+# .gittrees file creation tests
+test_expect_success 'check add for subtree with master branch' '
+        git subtree add -m "Add sub1 subtree" -P sub1 
../shared_projects/subtree1 master &&
+        check_equal ''"$(last_commit_message)"'' "Add sub1 subtree"
+'
+
+# Store latest commit id for future use
+expected_subtreeMergeCommit=$(last_commit_id)
+
+test_expect_success 'check if .gittrees file was created' '
+        test -a '.gittrees'
+'
+# Now lets test if the .gittrees file has the correct information
+# Hardcoded some expected results for checking data inside .gittrees file
+expected_url='../shared_projects/subtree1'
+expected_path='sub1'
+
+echo $expected_url>>expected_gittrees
+echo $expected_path>>expected_gittrees
+echo $expected_branch>>expected_gittrees
+echo $expected_subtreeCommit>>expected_gittrees
+echo $expected_subtreeMergeCommit>>expected_gittrees
+
+grep = .gittrees | cut -f2 -d"=" | cut -f2 -d" " > actual_gittrees
+
+test_expect_success 'check .gittrees file has the necessary changes' '
+        test_cmp actual_gittrees expected_gittrees
+'
+
+test_expect_success 'check subtree does not get created with incorrect remote 
url' '
+        test_must_fail git subtree add -P s2 ../shared_projects/subbtree1 
master
+'
+
+test_expect_success 'check that subtree does not get created with incorrect 
branch' '
+        test_must_fail git subtree add -P s2 ../shared_projects/subtree1 
development
+'
+
+test_expect_success 'add another subtree with master branch' '
+        git subtree add -m "Add sub2 subtree" -P sub2 
../shared_projects/subtree2 master &&
+        check_equal ''"$(last_commit_message)"'' "Add sub2 subtree"
+'
 
 test_done
-- 
1.7.9

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to