git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] contrib/subtree: Store subtree metadata in .gittrees file
@ 2014-05-30 17:45 Keval Patel
  2014-05-30 17:45 ` [PATCH 2/2] contrib/subtree: List subcmd and modify push/pull to use .gittrees Keval Patel
  0 siblings, 1 reply; 2+ messages in thread
From: Keval Patel @ 2014-05-30 17:45 UTC (permalink / raw)
  To: git; +Cc: Keval Patel, Keval Patel

- 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@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

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [PATCH 2/2] contrib/subtree: List subcmd and modify push/pull to use .gittrees
  2014-05-30 17:45 [PATCH 1/2] contrib/subtree: Store subtree metadata in .gittrees file Keval Patel
@ 2014-05-30 17:45 ` Keval Patel
  0 siblings, 0 replies; 2+ messages in thread
From: Keval Patel @ 2014-05-30 17:45 UTC (permalink / raw)
  To: git; +Cc: Keval Patel, Keval Patel

- Add subtree list sub-command
- git subtree list - Lists the subtrees in current project
- Changes taken from helmo’s repository from following URL:
https://github.com/helmo/git-subtree/blob/master/git-subtree.sh
- Add tests for subtree list and subtree push/pull using .gittrees
- 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@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     |   25 ++++++++++--
 contrib/subtree/t/t7900-subtree.sh |   72 ++++++++++++++++++++++++++++++++++++
 2 files changed, 93 insertions(+), 4 deletions(-)

diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index 7d01b4b..1151884 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -10,9 +10,10 @@ fi
 OPTS_SPEC="\
 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>
+git subtree pull  --prefix=<prefix> [<repository> [<refspec>...]]
+git subtree push  --prefix=<prefix> [<repository> [<refspec>...]]
 git subtree split --prefix=<prefix> <commit...>
+git subtree list
 --
 h,help        show the help
 q             quiet
@@ -102,15 +103,16 @@ command="$1"
 shift
 case "$command" in
 	add|merge|pull) default= ;;
-	split|push) default="--default HEAD" ;;
+	split|push|list) default="--default HEAD" ;;
 	*) die "Unknown command '$command'" ;;
 esac
 
-if [ -z "$prefix" ]; then
+if [ -z "$prefix" -a "$command" != "list" ]; then
 	die "You must provide the --prefix option."
 fi
 
 case "$command" in
+	list);;
 	add) [ -e "$prefix" ] && 
 		die "prefix '$prefix' already exists." ;;
 	*)   [ -e "$prefix" ] || 
@@ -759,4 +761,19 @@ cmd_push()
 	fi
 }
 
+subtree_list() 
+{
+	git config -f .gittrees -l | grep subtree | grep path | grep -o '=.*' | grep -o '[^=].*' |
+	while read path; do 
+		repository=$(git config -f .gittrees subtree.$path.url)
+		refspec=$(git config -f .gittrees subtree.$path.branch)
+		echo "    $path        (merged from $repository branch $refspec) "
+	done
+}
+
+cmd_list()
+{
+	subtree_list
+}
+
 "cmd_$command" "$@"
diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh
index 05110f7..c29993e 100755
--- a/contrib/subtree/t/t7900-subtree.sh
+++ b/contrib/subtree/t/t7900-subtree.sh
@@ -571,4 +571,76 @@ test_expect_success 'add another subtree with master branch' '
         check_equal ''"$(last_commit_message)"'' "Add sub2 subtree"
 '
 
+# Lets commit the changes we made to .gittrees file
+test_expect_success 'Commit chages to .gittrees for sub1 and sub2 in repo' '
+        git add .gittrees &&
+        git commit -m "Add .gittrees file"
+'
+# Tests for subtree list
+# Hardcode expected output to a file
+cat >expect <<-\EOF
+    sub1        (merged from ../shared_projects/subtree1 branch master) 
+    sub2        (merged from ../shared_projects/subtree2 branch master) 
+EOF
+
+test_expect_success 'check subtree list gives correct output' '
+        git subtree list>output &&
+        test_cmp expect output
+'
+# Lets commit the changes to parent1 before proceeding
+test_expect_success 'Commit changes to the repository' '
+        git add --all &&
+        git commit -m "Commit expect and output file additions"
+'
+
+# Tests for individual subtree pull using information in .gittrees
+# Go to subtree1 and make a change
+cd ../shared_projects/subtree1
+
+subtree1_change1="Add_line_to_Sub1_File2"
+
+echo $subtree1_change1>>sub1_file2
+
+# Lets commit the changes to subtree1 before proceeding
+test_expect_success 'Commit changes to the subtree1' '
+        git add --all &&
+        git commit -m "Commit change to sub1_file2"
+'
+
+# Switch to develop branch for a future test to push changes to master
+test_expect_success 'Switch to branch develop' '
+        git checkout -b develop
+'
+
+# Back to parent1
+cd ../../parent1
+
+test_expect_success 'check  git subtree pull <prefix> works' '
+        git subtree pull -P sub1 master &&
+        test_cmp sub1/sub1_file1 ../shared_projects/subtree1/sub1_file1 &&
+        test_cmp sub1/sub1_file2 ../shared_projects/subtree1/sub1_file2
+'
+
+# Now lets make local change on subtree and push it to subtree remote
+cd sub1
+
+local_change="Local addition of line to sub1 file 2"
+echo $local_change1>>sub1_file2
+
+# Back to parent1
+cd ..
+
+# Lets commit the changes to parent1 before proceeding
+test_expect_success 'Commit changes to parent repository' '
+        git add --all &&
+        git commit -m "Commit local changes to sub1/sub1 file2"
+'
+
+test_expect_success 'check git subtree push <prefix> works' '
+        git subtree push -P sub1 &&
+        cd ../shared_projects/subtree1 &&
+        git checkout master &&
+        test_cmp ../../parent1/sub1/sub1_file1 sub1_file1 &&
+        test_cmp ../../parent1/sub1/sub1_file2 sub1_file2
+'
 test_done
-- 
1.7.9

^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2014-05-30 17:45 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-05-30 17:45 [PATCH 1/2] contrib/subtree: Store subtree metadata in .gittrees file Keval Patel
2014-05-30 17:45 ` [PATCH 2/2] contrib/subtree: List subcmd and modify push/pull to use .gittrees Keval Patel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).