From: Keval Patel <patel.keval88@gmail.com>
To: <git@vger.kernel.org>
Cc: Keval Patel <patel.keval88@gmail.com>, Keval Patel <kapatel@lutron.com>
Subject: [PATCH 1/2] contrib/subtree: Store subtree metadata in .gittrees file
Date: Fri, 30 May 2014 13:45:14 -0400 [thread overview]
Message-ID: <1401471915-47195-1-git-send-email-kapatel@lutron.com> (raw)
- 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
next reply other threads:[~2014-05-30 17:45 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-05-30 17:45 Keval Patel [this message]
2014-05-30 17:45 ` [PATCH 2/2] contrib/subtree: List subcmd and modify push/pull to use .gittrees Keval Patel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1401471915-47195-1-git-send-email-kapatel@lutron.com \
--to=patel.keval88@gmail.com \
--cc=git@vger.kernel.org \
--cc=kapatel@lutron.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).