* [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).