Chris Stankevitz ( 9月25日(火)) >>
> Hello,
>
> Please consider the attached steps which create an SVN repo and setup git
> to track it.
>
> 1. Why do "local-newbranch" and "master" not share a common ancestor?
I think the reason is that the method you've used to add the branch to
git-svn treats that branch as a separate remote repository. git-svn
doesn't realise it should be treating it as a branch and so doesn't try
and trace back beyond the first commit to that branch to find the
parent.
>
> 2. How do I make them share a common ancestor?
Add the svn branches directory to the branches parameter for the
existing "svn" remote, rather than adding a new remote. The recommended
way of doing this is to pass --branches or --stdlayout on clone/init,
but if this is impossible, you could try modifying your sequence of
steps thus:
-- >8 --
--- a/steps.txt 2012-09-26 12:09:33.331806620 +0900
+++ b/steps.txt 2012-09-26 12:08:34.383604192 +0900
@@ -23,9 +23,9 @@
# Update the GIT repo to follow the SVN branch
cd ${ROOT}/repo.git
-git config --add svn-remote.newbranch.url
file://${ROOT}/repo.svn/branches/newbranch
-git config --add svn-remote.newbranch.fetch :refs/remotes/newbranch
-git svn fetch newbranch
+git config --add svn-remote.svn.branches "branches/*:refs/remotes/*"
+rm .git/svn/.metadata
+git svn fetch
git checkout -b local-newbranch -t newbranch
git svn rebase newbranch
gitk --all
-- 8< --
Note the removal of the ".git/svn/.metadata" file. When I tried it
without doing that, git-svn didn't notice the new branch settings and
didn't try to fetch the branches. deleting this file forces git-svn to
regenerate it with the latest settings.
>
> 3. Assuming (2) is possible, will I be able to rebase "master" changes onto
> "local-newbranch"
You need to be careful about this, as you can't rewrite history on the
svn side. Essentially svn has no "rebase", only "merge".
What this means is you can use all the git functionality on local
branches, as far back as the last svn commit. As soon as you reach
something that has been committed to svn, though, you have to limit
yourself to svn functionality.
Taking your example, here is the state at the end of steps.txt (with the
patch above applied). I will mark svn branches in caps, and git
branches in lower-case.
--A--BTRUNK, master
\
-C NEWBRANCH, local-newbranch
Say you work on local-newbranch, and other people work on the trunk.
If you do "git svn pull" on master the graph might look like this
(commits which have been committed to SVN in caps, those which only
exist in your local git repo in lower case):
master, TRUNK
|
v
--A--B--F--G--H
\
-C--d--e
^ ^
| |
NEWBRANCH local-newbranch
In this case, commits D and E only exist in git, but everything else has
already been committed to svn. If you want to have access to commits
F-H on the local-newbranch branch, you will need to do it the svn way;
ie by creating a merge commit on NEWBRANCH which pulls in those changes.
You can do that by passing the --squash option to "git merge", thus:-
$ git checkout local-newbranch
$ git merge --squash trunk
Resulting in:
master, TRUNK
|
v
--A--B--F--G--H
\
-C--d--e--m
^^
||
NEWBRANCH local-newbranch
Here M is a single commit containing all of the changes held in commits
F-H. Subversion doesn't support the git concept of "multiple parent
commits", so you lose that element of merge history on the graph. The
merge is marked as having taken place after D and E were written in the
history. Since you said you wanted to rebase, perhaps that isn't what
you want; you might want the merge to have been performed before your
changes. You can accomplish that, provided you haven't dcommitted
local-newbranch:-
$ git checkout -b newbranch-merge newbranch
$ git merge --squash trunk
$ git rebase newbranch-merge local-newbranch
$ git branch -D newbranch-merge
master, TRUNK
|
v
--A--B--F--G--H
\
-C--m--d--e
^^
||
NEWBRANCH local-newbranch
Since newbranch-merge hadn't been committed to svn yet, the rebase was
possible and the merge will go down in history as having happened before
the changes on local-newbranch.
> 4. Assuming (3) is possible, will I be able to dcommit "local-newbranch"?
Running a "git svn dcommit" while "local-newbranch" is checked out
should update the newbranch branch on the SVN side, and running it on
"master" should update "trunk".
I would only recommend doing all this if you need to share these
branches with other users of svn, though. Since branching is so easy
and natural in git, people tend to find themselves making a lot of
local, short-liv