6 USAGE
='abort|branch-point|checkout|attach [--dry-run] URL [branch_name]'
9 abort : to abort an import
10 branch-point : return branch point svn revision
11 checkout : retrieve a new branch
12 attach : attach previously imported (see above) branch to
13 corresponding branch point.
16 URL : the full url to subversion branch
17 branch_name : the name of the remote branch to use
18 (default is the name of the subversion branch)
19 the local branch name is the basename of this name,
20 prefixed with '$prefix'
21 --dry-run : nothing will changed in the local Git repository
22 --prefix=name : prefix to apply to the name of the local branch
26 $ git svn-new-branch checkout svn+ssh://server/svn/branches/relA
27 $ git svn-new-branch attach svn+ssh://server/svn/branches/relA
29 Before attaching, it is possible to check the branch-point that will be
30 used to connect the branch history to the master:
32 $ git svn-new-branch branch-point svn+ssh://server/svn/branches/relA
37 exec_path
=$
(git
--exec-path)
38 .
$exec_path/git-sh-setup
41 set_reflog_action svn-new-branch
43 # Get require_work_tree from git-rebase--interactive.sh
44 require_clean_work_tree
() {
45 # test if working tree is dirty
46 git rev-parse
--verify HEAD
> /dev
/null
&&
47 git update-index
--ignore-submodules --refresh &&
48 git diff-files
--quiet --ignore-submodules &&
49 git diff-index
--cached --quiet HEAD
--ignore-submodules -- ||
50 die
"Working tree is dirty"
53 parse_command_line
() {
54 requires_url
=${1:-True}
57 shift # remove requires_url
59 TEMP
=`getopt -o dp: --long dry-run,prefix: -n git-svn-new-branch -- "$@"`
60 if [ $?
!= 0 ]; then exit 1; fi
65 -d|
--dry-run) dryrun
=echo;
66 echo "Restart without --dry-run if you want to execute"\
67 "the following commands:"
69 -p|
--prefix) prefix
="$2"; shift 2;;
75 if [ $requires_url = True
]; then
78 if [ "$URL" == "" ]; then
83 if [ "$2" = "" ]; then
84 branch_name
=$
(basename $URL)
85 local_branch
=$prefix$branch_name
88 local_branch
=$prefix$
(basename $branch_name)
92 echo Track
$URL on branch
: $branch_name
93 echo on
local branch
: $local_branch
99 parse_command_line False
"$@"
100 require_clean_work_tree
101 head=$
(grep HEAD .git
/SVN_NEW_BRANCH |
sed -e "s/HEAD: //")
102 branch_name
=$
(grep BRANCH_NAME .git
/SVN_NEW_BRANCH |
103 sed -e s
"/BRANCH_NAME: //")
104 $dryrun git checkout
$head
105 $dryrun git update-ref
-d refs
/remotes
/$branch_name
106 $dryrun find .git
-name "*_map*" -print -exec rm -f {} \
;
107 $dryrun git branch
-D $local_branch
113 head=$
(git symbolic-ref
-q HEAD
) ||
114 head=$
(git rev-parse
--verify HEAD
) ||
115 die
"Bad HEAD - I need a HEAD"
117 require_clean_work_tree
119 rm -f .git
/SVN_NEW_BRANCH
120 echo HEAD
: ${head#refs/heads/} >> .git
/SVN_NEW_BRANCH
122 parse_command_line True
"$@"
124 echo BRANCH_NAME
: $branch_name >> .git
/SVN_NEW_BRANCH
126 echo Check
if local branches exist
128 if [ "$(git branch -r | grep $branch_name)" != "" ]; then
129 die Remote branch
$branch_name already imported.
132 if [ "$(git branch | grep $local_branch)" != "" ]; then
133 die Local branch
$local_branch already present.
136 echo Check
if remote branch exists
138 svn list
$URL > /dev
/null
2>&1
141 die The given URL does not exists.
144 if [ "$dryrun" == "" ]; then
145 git config svn-remote.
$local_branch.url
$URL
146 git config svn-remote.
$local_branch.fetch
:refs
/remotes
/$branch_name
148 echo Fetch branch data
149 git svn fetch
--no-follow-parent $local_branch
150 git branch
--track $local_branch $branch_name
152 echo Only branch
history has been fetched
, consider using
153 echo $program attach
--prefix=\"$prefix\" $URL $branch_name
154 echo to attach the old
history to the branch.
159 parse_command_line True
"$@"
161 echo Finding branch point
162 rsvn
=$
(get_branch_point
$URL)
163 if [ "$rsvn" = "" ]; then
164 die
"Can not find branch point"
167 echo Subversion branch point
: $rsvn
169 nrsvn
=$
(find_nearest_rev
$rsvn)
171 rgit
=$
(git svn find-rev r
$nrsvn)
172 # Run it twice to avoid the svn rebuilding .rev_map messages
173 rgit
=$
(git svn find-rev r
$nrsvn)
175 if [ "$rgit" = "" ]; then
176 echo "Can not find corresponding Git rev !"
177 echo "Maybe the subversion repository is set incorrectly, trying different approach"
178 rgit
=$
(find_previous_svn_rev
$URL)
179 if [ "$rgit" = "" ]; then
180 die
"Could not find git revision for branch point"
184 echo Corresponding Git revision
: $rgit
187 git log
$rgit^..
$rgit |
cat -
189 echo Checkout
local branch
190 $dryrun git checkout
$local_branch
192 $dryrun git filter-branch
-f --tag-name-filter cat \
193 --parent-filter "sed -e 's/^$/-p $rgit/'" $local_branch &&
194 $dryrun git
reset --hard $local_branch &&
195 $dryrun git update-ref refs
/remotes
/$branch_name $local_branch &&
196 $dryrun find .git
-name "*_map*" -print -exec rm -f {} \
; &&
197 $dryrun git svn rebase
198 ) || die
"Failed ! Use --abort to revert all changes"
201 get_branch_point
() {
203 rev=$
(svn log
--verbose --stop-on-copy $branch |
grep '(from' |
204 grep -E -o ":([0-9]+)" | cut
-c2- |
tail -1)
208 find_previous_svn_rev
() {
210 rev_on_branch
=$
(svn log
-q --stop-on-copy $branch | fgrep r |
wc -l)
212 # "+5" is to give us some more revisions to work with, in case the svn
213 # repository is really messed up
214 fetch
=`expr $rev_on_branch + 5`
215 prev
=$
(svn log
-q $branch | fgrep r |
head -$fetch |
grep -o -E 'r[0-9]+' | cut
-c2-)
218 # When the repository is messed up, it seems that "find-rev" will not
219 # work correctly either, so try differently
220 # rgit=$(git svn find-rev r$p)
222 rgit
=$
(git log |
grep -e commit
-e git-svn-id |
grep "@$p " -B1 |
head -1 | cut
-f2 -d\
)
224 if [ "$rgit" != "" ]; then
228 echo "No matching git revision for subversion's $p" >/dev
/stderr
235 find_nearest_rev
() {
240 git svn log
--oneline |
grep -o -E 'r[0-9]+' | cut
-c2-
241 ) |
sort -n |
grep -E "^$rev" -B1 |
head -1)
245 test "$#" = "0" && usage
&& exit 1;
257 test "$1" != "" && get_branch_point
"$@"
265 test "$1" != "" && find_nearest_rev
"$@"
269 test "$1" != "" && get_new_branch
"$@";;
271 echo "Invalid command : $1"