Hello Patrick,
thanks for the information, it was very helpful. The problem seems to be in absolutely another place than where I expected it to be, without ‘jstack’ it would be impossible to identify it.
I would start with the fact that SubGit mostly doesn’t allow one to chage trunk/branches/tags/shelves/excludeBranches options on the fly with some rare exceptions. This is because after such a change the translated part of the SVN repository could contradict a config. For instance, imagine a situation, when I have a ‘branches/branch’ and ‘trunk’ in SVN. ‘branches/branch’ was created from ‘trunk’ and then merged back to it. In Git this would result into a merge commit. Now suppose that I’ve removed ‘branches=’ option or (equivalently in this case) added ‘excludeBranches=branches/*’ option. Then the Git commits corresponding to ‘branches/branch’ should stop to exist and this would influence ‘trunk’ via the merge commit.
To prevent such problems we decided to forbid adding or removing new branches on the fly. There’s a notable exception. Suppose you want to introduce ‘releases/*
’ to your SVN structure. Then you can add ‘branches=releases/*:refs/releases/*
’ rule to SubGit, run “subgit install” to apply the change and only then add ‘releases/*
’ to your SVN. This is allowed.
To distinguish between both cases, “subgit install” runs a check whether it is safe to change trunk/branches/tags/excludeBranches rules or not. To do that, it scans SVN history to check whether the newly added or removed rule could be applied to a branch (trunk, or tag) ever existed in SVN.
And this check is what takes much time in your case.
There’re some work-arounds:
- If you know for sure yourself that none of branches ever translated to Git to the current moment match the rule you add or remove. In particular, for instance, if you add ‘
excludeBranches=tags/nightly-build/2014*/*/product
’, you must be sure that there’s no tag of pattern tags/nightly-build/2014*/*/product
ever translated to Git to the current moment. If this is so, you can trick SubGit to suppress the check. To do that, you can edit GIT_REPO/subgit/.run/config
file to add the 'excludeBranches='
there as well.
How does this work? At every moment GIT_REPO/subgit/.run/config
file contain the config actually used by SubGit. Whenever you change GIT_REPO/subgit/config
, it compares it to GIT_REPO/subgit/.run/config
, finds changed options, checks whether these options are allowed to change (and this takes too much time in your case). If everything is ok, it applies the changes to GIT_REPO/subgit/.run/config
. By applying the changes manually, you bypass the checks at a risk of creating of potentially unsafe situation.
- If some of the excluded tags are already translated to Git, you can find the revision number where these tags appeared for the first time. Then subtract “1” and run
subgit install --rebuild-from-revision REV_MINUS_ONE GIT_REPO
E.g. if you add an exclude for tags/nightly-build/2014*/*/product
and the first tag ever appeared in SVN matching this rule was created at r12345, then you can subtract one: 12345-1=12344 and run
subgit install --rebuild-from-revision 12344 GIT_REPO
Note that unlike “subgit install”, the option --rebuild-from-revision
does not run the checks of whether the config can be changed in that way but just silently applies all changes in GIT_REPO/subgit/config
to GIT_REPO/subgit/.run/config
. So use it with care. Also the option reverts the current state to the revision specified and re-fetches everything with the new config. But I must note that reverting the current state to the revision specified may also take much time if you have too many branches and tags with the new config (it lists all of them and reverts each of them to its older state). So I’m not sure that it would be better for you in the current situation.
Normally, one can’t change trunk/branches/tags/excludeBranches on the fly, that’s why I can only propose a work-around.