0

I have an SVN structure of the following:

- Project A
  - Folder 1
    - Folder a
    - Folder b
      - Folder 1
        - trunk
        - tags
          ...
      - Folder n
        - trunk
        - tags
  - Folder 2
  - Folder 3
- Project B

In terms of writing KDE matching rules for svn2git, is the following correct:

create repository repo
end repository

match Project A/Folder 1/Folder b/([^/]+)/trunk/([^/]+)/
  repository repo/Project A/Folder b/([^/]+)
  branch master
end match

# Add a prefix to all tag branches so we can fix them later.
match Project A/Folder 1/Folder b/([^/]+)/tags/([^/]+)/
  repository repo/Project A/Folder b/([^/]+)
  branch tag--\1
end match

# Ignore all other directories.
match /
end match

Also, do I have to create all the folders in my Git repo beforehand, or will svn2git do it for me?

Idris.AH
  • 410
  • 1
  • 10
  • 22
  • No your rules are not correct, I can give you corrected version, but I need some more info. 1. Do the folders, especially the `Folder n`s between `Folder b` and `trunk` really have spaces in their name or not? 2. Do you want as result one Git repo per `Folder n`, or all in one Git repo with a path-prefix. 3. Why exactly do you want to prefix the tags as branches instead of directly creating the correctly named tags? – Vampire Feb 01 '18 at 09:47
  • And if in separate repositories, should they be in the first level directly where you execute `svn2git` or inside `repo/Project A/Folder b/`? – Vampire Feb 01 '18 at 09:50
  • I added an answer based on assumed answers to my questions. – Vampire Feb 01 '18 at 10:13

1 Answers1

1

svn2git will create the directories for you, but you have to define the repositories explicitly in the rules file. If you reference a repository that is note defined (e. g. because the match regex matched something you didn't create, then the migration will stop with an error message.

Your rules are not correct though, I think it should be more like

create repository repo
end repository

match /(Project A/Folder 1/Folder b/[^/]+/)trunk/
  repository repo
  prefix \1
  branch master
end match

match /(Project A/Folder 1/Folder b/[^/]+/)tags/([^/]+)/
  repository repo
  prefix \1
  branch refs/tags/\2
end match

# Ignore all other directories.
match /
end match
Vampire
  • 35,631
  • 4
  • 76
  • 102
  • 1. Some folders have spaces in them at each level have spaces in them, including some in Folder ns. 2. End result, I want one Git repo with many folders inside, and of course inside those there will be sub-folders. 3. I would actually like to create the tags as proper tags in Git. I only included the rule like that because I had seen an example online and I don't understand the rule. What does `s/ /_/` mean? The structure of my SVN repo is a: - Top level with many folders and a couple files - Each of these folders have many sub-folders and files in the next level and so on. – Idris.AH Feb 01 '18 at 13:15
  • - Some folders and files have spaces in their names. - Some folders have a trunk and tags folder inside, some don't and some just have either trunk or tags folder. This is not my own personal repo, but, a very messy company repo. – Idris.AH Feb 01 '18 at 13:16
  • Believe me, it cannot be as messy as the one I'm currently working on migrate and the rules are mighty enough to resolve the mess if you do it right. :-D – Vampire Feb 01 '18 at 14:47
  • If I understood your answers correctly, the updated rules should do I think. Spaces are only a "problem" in the repository name, as there `svn2git` does currently not support spaces. Hence teh substituion rules that replaced spaces by underscores. – Vampire Feb 01 '18 at 14:50
  • Thanks for the updated rules, I'm slowly understanding them more. What does the prefix rule do? So in the first rule, would `prefix \1`, correspond to "Project A"? Also, my SVN repository doesn't have any explicit "branch" folders. Does that mean I don't need the second rule matching a branch? – Idris.AH Feb 01 '18 at 16:03
  • The prefix rules, well, define the prefix to use. Everything matched under that path will be put into the sole Git repo under that path. `\1` means the first match group (parentesized part of the regex), so in your case e. g. `Project A/Folder 1/Folder b/Folder n`. Actually I forgot the final slash that is not implied, I added it now. And yes, if you only worked with trunk and tags, but no branches, you can leave out the branch rule of course, removed it from the answer. – Vampire Feb 01 '18 at 16:21
  • For folders that don't use a trunk/tags/branch, and just folders, then do I have to match each folder/file or can I just match a top level directory. Lets say Folder b had just loads of files and sub folders with more files and sub folders etc inside, would the following rule be correct? `match /(Project A/Folder 1/Folder b/[^/]+/)` – Idris.AH Feb 06 '18 at 10:10
  • Or am I matching the folders and not the files? – Idris.AH Feb 06 '18 at 13:29
  • You can match folder, you can match files, up to you. But why should you have a varying part in your match rule at all if not treating them differently like when they got to different repositories. In your case just `match /(Project A/Folder 1/Folder b/`. – Vampire Feb 06 '18 at 15:57
  • Do I not need to use the recurse rule at all? – Idris.AH Feb 07 '18 at 11:10
  • I don't think so. The recurse action is a hack to tell svn2git to recurse into a directory it has just copied or that existed because it is of interest. Example: if we are importing kdelibs, it exists in `trunk/KDE/kdelibs`. At branching, someone did: `svn cp $SVNROOT/trunk/KDE $SVNROOT/branches/KDE/4.4` SVN recorded in that commit that `branches/KDE/4.4` was the only path changed. That means the rule `branches/KDE/[^/]+/kdelibs/` will not match. We need to tell the tool that something interesting happened inside and it should recurse. Then it will apply again all rules to the files that – Vampire Feb 08 '18 at 08:21
  • Btw., you can also change the rules to generate annotated tags instead of lightweight ones. – Vampire Feb 08 '18 at 08:22
  • https://i.imgur.com/e38Yfjb.png - I keep getting this error. My rules that include tags are all like this: `match /(/Source//[^/]+/)tags/ repository repo prefix \1 branch refs/tags/\2 end match` How can I correct these rules? – Idris.AH Feb 16 '18 at 14:47
  • Your rule doesn't make sense. You have one match group in your regex (thing in parentheses), but you use two back references (backslash + number). I guess it's erroring out because of that. Compare your tag rule to my example and you should see the difference. – Vampire Feb 16 '18 at 22:20
  • Your comment has fixed the previous error, however, now I am getting a bunch the following errors: `WARN: Branch "refs/tags/<...>" in repository "repo" doesn't exist at revision 1 -- did you resume from the wrong revision?` Then I am getting `Failed to write to process: Error writing to process for repository repo 91 modifications from SVN ... ... Aborted (core dumped)` Could you please clarify what this means for me please? – Idris.AH Feb 18 '18 at 20:26
  • In the fast_import_crash file it says that: `fatal: Branch name doesn't conform to GIT standards: refs/tags/WIN-2FS-XSLT SpecialcharacterFix_May_2017` Could the space in the file name be causing the issue? And if so, what is the fix for that? – Idris.AH Feb 18 '18 at 20:40
  • Yes, spaces in branch names are invalid. Use a substitution rule like `substitute branch s/ /_/` inside your match block. – Vampire Feb 18 '18 at 21:33
  • I added this rule to all my of tags match blocks. I believe the conversion from SVN to Git finished this time since it ended with `done`, however, I got a bunch of "Branch ... doesn't exist at revision 1 -- did you resume from the wrong revision?" Is this just a warning and something I don't need to worry about or does this mean the conversion completed incorrectly? – Idris.AH Feb 19 '18 at 23:10
  • Also, I can't see any of the files in the git repo it created. For my svn repo, the only way I can see the files is using svnserve -d -r. Is there something similar I need to do with the Git repo or has something gone wrong? – Idris.AH Feb 19 '18 at 23:11
  • What you created is a bare repository. Something that is typically on some server, not something you work with. You usually clone that bare repository with `git clone` into a non-bare repository that has a `.git` folder that has the repo in it and the worktree with the checked out files. But you can investigate the contents of the bare repository with git commands too of course. – Vampire Feb 20 '18 at 00:09
  • The "branch doesn't exist" warnings are usually ok if you converted from start to end. It just say that it found a commit in that branch and no other commit was in that branch before, so it creates this branch from scratch now. – Vampire Feb 20 '18 at 00:10