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 # Use default C as language to ensure that the regexp parsing Subversion
41 exec_path
=$
(git
--exec-path)
42 .
$exec_path/git-sh-setup
45 set_reflog_action svn-new-branch
47 # Get require_work_tree from git-rebase--interactive.sh
48 require_clean_work_tree
() {
49 # test if working tree is dirty
50 git rev-parse
--verify HEAD
> /dev
/null
&&
51 git update-index
--ignore-submodules --refresh &&
52 git diff-files
--quiet --ignore-submodules &&
53 git diff-index
--cached --quiet HEAD
--ignore-submodules -- ||
54 die
"Working tree is dirty"
57 parse_command_line
() {
58 requires_url
=${1:-True}
61 shift # remove requires_url
63 TEMP
=`getopt -o dp: --long dry-run,prefix: -n git-svn-new-branch -- "$@"`
64 if [ $?
!= 0 ]; then exit 1; fi
69 -d|
--dry-run) dryrun
=echo;
70 echo "Restart without --dry-run if you want to execute"\
71 "the following commands:"
73 -p|
--prefix) prefix
="$2"; shift 2;;
79 if [ $requires_url = True
]; then
82 if [ "$URL" = "" ]; then
87 if [ "$2" = "" ]; then
88 branch_name
=$
(basename $URL)
89 local_branch
=$prefix$branch_name
92 local_branch
=$prefix$
(basename $branch_name)
96 echo Track
$URL on branch
: $branch_name
97 echo on
local branch
: $local_branch
103 parse_command_line False
"$@"
104 require_clean_work_tree
105 head=$
(grep HEAD .git
/SVN_NEW_BRANCH |
sed -e "s/HEAD: //")
106 branch_name
=$
(grep BRANCH_NAME .git
/SVN_NEW_BRANCH |
107 sed -e s
"/BRANCH_NAME: //")
108 $dryrun git checkout
$head
109 $dryrun git update-ref
-d refs
/remotes
/$branch_name
110 $dryrun find .git
-name "*_map*" -print -exec rm -f {} \
;
111 $dryrun git branch
-D $local_branch
117 head=$
(git symbolic-ref
-q HEAD
) ||
118 head=$
(git rev-parse
--verify HEAD
) ||
119 die
"Bad HEAD - I need a HEAD"
121 require_clean_work_tree
123 rm -f .git
/SVN_NEW_BRANCH
124 echo HEAD
: ${head#refs/heads/} >> .git
/SVN_NEW_BRANCH
126 parse_command_line True
"$@"
128 echo BRANCH_NAME
: $branch_name >> .git
/SVN_NEW_BRANCH
130 echo Check
if local branches exist
132 if [ "$(git branch -r | grep $branch_name)" != "" ]; then
133 die Remote branch
$branch_name already imported.
136 if [ "$(git branch | grep $local_branch)" != "" ]; then
137 die Local branch
$local_branch already present.
140 echo Check
if remote branch exists
142 svn list
$URL > /dev
/null
2>&1
145 die The given URL does not exists.
148 if [ "$dryrun" = "" ]; then
149 git config svn-remote.
$local_branch.url
$URL
150 git config svn-remote.
$local_branch.fetch
:refs
/remotes
/$branch_name
152 echo Fetch branch data
153 git svn fetch
--no-follow-parent $local_branch
154 git branch
--track $local_branch $branch_name
156 echo Only branch
history has been fetched
, consider using
157 echo $program attach
--prefix=\"$prefix\" $URL $branch_name
158 echo to attach the old
history to the branch.
163 parse_command_line True
"$@"
165 echo Finding branch point
166 rsvn
=$
(get_branch_point
$URL)
167 if [ "$rsvn" = "" ]; then
168 die
"Can not find branch point"
171 echo Subversion branch point
: $rsvn
173 nrsvn
=$
(find_nearest_rev
$rsvn)
175 rgit
=$
(git svn find-rev r
$nrsvn)
176 # Run it twice to avoid the svn rebuilding .rev_map messages
177 rgit
=$
(git svn find-rev r
$nrsvn)
179 if [ "$rgit" = "" ]; then
180 echo "Can not find corresponding Git rev !"
181 echo "Maybe the subversion repository is set incorrectly, trying different approach"
182 rgit
=$
(find_previous_svn_rev
$URL)
183 if [ "$rgit" = "" ]; then
184 die
"Could not find git revision for branch point"
188 echo Corresponding Git revision
: $rgit
191 git log
$rgit^..
$rgit |
cat -
193 echo Checkout
local branch
194 $dryrun git checkout
$local_branch
196 $dryrun git filter-branch
-f --tag-name-filter cat \
197 --parent-filter "sed -e 's/^$/-p $rgit/'" $local_branch &&
198 $dryrun git
reset --hard $local_branch &&
199 $dryrun git update-ref refs
/remotes
/$branch_name $local_branch &&
200 $dryrun find .git
-name "*_map*" -print -exec rm -f {} \
; &&
201 $dryrun git svn rebase
202 ) || die
"Failed ! Use --abort to revert all changes"
205 get_branch_point
() {
207 rev=$
(svn log
--verbose --stop-on-copy $branch |
grep '(from' |
208 grep -E -o ":([0-9]+)" | cut
-c2- |
tail -1)
212 find_previous_svn_rev
() {
214 rev_on_branch
=$
(svn log
-q --stop-on-copy $branch | fgrep r |
wc -l)
216 # "+5" is to give us some more revisions to work with, in case the svn
217 # repository is really messed up
218 fetch
=`expr $rev_on_branch + 5`
219 prev
=$
(svn log
-q $branch | fgrep r |
head -$fetch |
grep -o -E 'r[0-9]+' | cut
-c2-)
222 # When the repository is messed up, it seems that "find-rev" will not
223 # work correctly either, so try differently
224 # rgit=$(git svn find-rev r$p)
226 rgit
=$
(git log |
grep -e commit
-e git-svn-id |
grep "@$p " -B1 |
head -1 | cut
-f2 -d\
)
228 if [ "$rgit" != "" ]; then
232 echo "No matching git revision for subversion's $p" >/dev
/stderr
239 find_nearest_rev
() {
244 git svn log
--oneline |
grep -o -E 'r[0-9]+' | cut
-c2-
245 ) |
sort -n |
grep -E "^$rev" -B1 |
head -1)
249 test "$#" = "0" && usage
&& exit 1;
261 test "$1" != "" && get_branch_point
"$@"
269 test "$1" != "" && find_nearest_rev
"$@"
273 test "$1" != "" && get_new_branch
"$@";;
275 echo "Invalid command : $1"