3

I used reposurgeon to convert my svn into a git repository here: (How do I convert an svn repo to git using reposurgeon?).

The problem is, that the converted tags are shown in the log at the place when I created the tag and not at the place of the revision they belong to. In SVN they are shown at the right place in the log where they belong, no matter how long later I created them.

It seems like this has to do something with that reposurgeon adds a commit for .gitignore in each tag that looks like this:

# A simulation of Subversion default ignores, generated by reposurgeon.
*.o
*.lo
...
*.pyo
*.rej
*~
.#*
.*.swp
.DS_store
# The contents of the svn:ignoreproperty on the branch root.
*~
nbproject
*.project

How can I make reposurgeon not create such a commit for gitignore in all tags? And let it create simple tags that don't appear in the timeline as a commit?

The reposurgeon manual sais:

user-generated .gitignore

This message means means reposurgeon has found a .gitignore file in the Subversion repository it is analyzing. This probably happened because somebody was using git-svn as a live gateway, and created ignores which may or may not be congruent with those in the generated .gitignore files that the Subversion ignore properties will be translated into. You'll need to make a policy decision about which set of ignores to use in the conversion, and possibly to delete either the generated .gitignore files or the user-created ones.

But no example how to make that decision. How can I manage this?

Community
  • 1
  • 1
rubo77
  • 19,527
  • 31
  • 134
  • 226
  • You might have to do some additional 'surgery' using `git-filter-branch` to make the converted repository look how you want. It is possible to do things like strip a file completely from history, or edit files in history, or move tags, etc., but hard to post a generic answer to that – 6EQUJ5 Jun 11 '14 at 07:08
  • The main problem seems to be, that the SVN was already used with git over SVN which created the `.gitignore` files – rubo77 Jun 11 '14 at 10:33

4 Answers4

2

You'll need to make a policy decision about which set of ignores to use in the conversion, and possibly to delete either the generated .gitignore files or the user-created ones.

Do you have a .gitignore from before the conversion? If so compare it to the one from after. It seems like this policy decision is separate from your "sequence of commits" question, right? Basically, the policy question is just "get a final .gitignore you like". Do what it takes to get there.

In git, the .gitignore file is managed exactly like any other file. So you can say git log .gitignore and see what commits contribute to it. Say that the entire .gitignore file was commited in one block 10 commits ago and you want it parted out. If so, you can do a git rebase --interactive HEAD~11 and edit the commit in question. Do git add --partial .gitignore; git commit for each line you want broken out. Then git rebase --continue to conclude.

If you want the newly itemized commits to each be part of a larger code commit that they correspond to, then you would rebase -i again to shift the order around and squash them with their partner commit. If this sounds like unnecessary work, it probably is. If you can, I would recommend you focus on the integrity of the end state of the repo and less about a perfect expression of history.

Note: I don't understand your use of the term "tag" in this context, since both SVN and git have "tags", but you seem not to be referring to either. Perhaps "ignore line" or "entry" would be clearer.

To purge history in version control is problematic. Changing history on all branches is effectively creating a new repository, since there is no longer continuity to downstream followers for anything (everybody must rebase). But if you want to do it, for each branch, find all the .gitignores in the filesystem and see what commits touched them:

  git log `find . -name .gitignore`

Then you can do the rebase --interactive steps described above to alter those commits. If the commit affects only the .gitignore, you can delete it. But obviously if the commit touches 100 files including the .gitignore, you have to separate out the good from the bad.

Alternatively, if you know the paths of all the .gitignore files (checkout each branch and run the find from above), then you can do something like github has documented with filter-branch:

git filter-branch --force --index-filter      \
 'git rm --cached --ignore-unmatch .gitignore path/to/other/.gitignore'  \
 --prune-empty --tag-name-filter cat -- --all

They also mention a BFG java tool, but filter-branch should do what you need.

Joe Atzberger
  • 3,079
  • 1
  • 18
  • 16
  • I don't want any.gitignore files at all. svn doesn't have them and they only mess things up here. I will create one (and only one!) when I am finished converting. – rubo77 Jun 12 '14 at 05:34
  • With tags I mean version tags. They are a standard. There are branches and tags. Tags usually don't contain commits. But after my conversion they all contain one empty commit with this gitignore file – rubo77 Jun 12 '14 at 05:37
  • Could you add an example how I can remove all .gitignore files from all branches and tags in the whole history? – rubo77 Jun 17 '14 at 06:38
  • Added. The last example is probably what you want. – Joe Atzberger Jul 02 '14 at 17:28
  • You can use `find` to find all instances of `.gitignore` in the repo and pass this to your command: `git filter-branch --force --index-filter "git rm --cached --ignore-unmatch $(find . -name .gitignore|xargs )" --prune-empty --tag-name-filter cat -- --all ` – rubo77 Aug 22 '14 at 05:30
  • You should move the "Alternative" to the top of your answer, cause that is how it works with an acceptable amount of work. Your other tips are good, but produce far too much work with hundredths of tags and branches – rubo77 Aug 22 '14 at 06:53
2

After reading in your subversionrepository, just add:

expunge /gitignore/

That will remove all the .gitignore files that reposurgeon automatically added.

Tom Mayfield
  • 6,235
  • 2
  • 32
  • 43
  • Will it just remove them with another commit? or will it delete them from history and also delete the commits that added them? – rubo77 Aug 15 '14 at 21:26
  • They're added as part of existing commits, IIRC. This purges those files from the history completely (as if they had never existed). – Tom Mayfield Aug 15 '14 at 21:27
  • If they are indeed their own commits, you can figure out the commit message marker, and then `/whatever-marker/ squash --pushback` will delete the commit. – Tom Mayfield Aug 15 '14 at 21:31
  • expunge seems to delete all .gitignores, that is great!. But now there are hundredths of emptycommits in between: http://i.stack.imgur.com/ZdXEQ.png Can I get rid of those too? – rubo77 Aug 22 '14 at 05:10
  • Are they actually empty commits, or just tags with the name "emptycommit"? – Tom Mayfield Aug 22 '14 at 17:07
  • I don't know. But the screenshot shows them: http://i.stack.imgur.com/ZdXEQ.png How could I find out more details on them? I always use smartGit/hg – rubo77 Aug 22 '14 at 19:07
  • @rubo77: no it will remove them without another commit. That is: it will appear as if the files never existed. But beware of inconsistencies you can introduce this way. – 0xC0000022L Mar 18 '15 at 08:27
  • @0xC0000022L: yes, but did you see the remaining problem? – rubo77 Mar 18 '15 at 08:30
  • @rubo77: obviously with `/^emptycommit-/n delete` ;) (`n` is to look for "names", like tags - and those are actually by default tags after `expunge`) – 0xC0000022L Mar 18 '15 at 09:01
0

I've never used reposurgeon, but I've converted many svn repositories to git using the built-in git svn ... commands. I've followed the directons on http://trac.parrot.org/parrot/wiki/git-svn-tutorial and http://john.albin.net/git/convert-subversion-to-git.

robrich
  • 13,017
  • 7
  • 36
  • 63
0

@robrich

Author of reposurgeon here. Do not use git-svn for conversions! It's a disaster area. See this PSA:

http://esr.ibiblio.org/?p=6778

ESR
  • 574
  • 1
  • 5
  • 10