[PATCH 1/2] contrib/subtree: Store subtree metadata in .gittrees file

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



- 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 <kapatel@xxxxxxxxxx>
---
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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]