I have created a simple script to migrate fairly large SVN repository. Instead of using git svn clone
, I am using git svn init
and git svn fetch
so that I could specify the revision and fetch it chunk by chunk. More or less, it is something like this:
while [ "$CURRENT_REVISION" -lt "$MAX_REVISION" ]; do
END_REVISION=$((CURRENT_REVISION + 100))
if [ "$END_REVISION" -ge "$MAX_REVISION" ]
then
END_REVISION=$MAX_REVISION
fi
git svn fetch -r "$CURRENT_REVISION":"$END_REVISION" --authors-file="$AUTHORS_FILE"
#increasing the current and end revision
CURRENT_REVISION=$END_REVISION
END_REVISION=$((CURRENT_REVISION + 100))
done
However, I understand that by default the behavior of the fetch/clone will not retain empty directories. Thus, I might need to manually check in those empty directories (*which I'm trying to avoid).
There is a --preserve-empty-dirs
parameter in the git svn clone
but not in git svn fetch
.
Is there any workaround to trick this out?
UPDATE
Even though it is not mentioned in the official documentation that we can use the config key for the fetch, it is actually works
There is detailed explanation by @Vampire related to this question. So I'll simplify this.
After doing the init repository, I had to change the configuration of my remote branch:
git config svn-remote.<remote name>.preserve-empty-dirs "true"
git config svn-remote.<remote name>.placeholder-filename ".gitkeep"
You can verify the configuration by looking at /.git/config. Just do normal fetch and your directory will be preserved.
To get Git to recognize an empty directory, the unwritten rule is to put a file named . gitkeep in it. Git will see the . gitkeep file in the otherwise empty folder and make that folder part of the next commit or push.
This retrieves all the changes from the SVN repository and applies them on top of your local commits in your current branch. This works like, you know, a rebase between two branches :) You can also use git svn fetch to retrieve the changes from the SVN repository but without applying them to your local branch.
Since Git won't track empty directories, you have to trick it into doing so by adding a file in the directory to Git's index. Usually, people store a file called . gitkeep in a directory that they wish to track, but where the directory should stay empty for the time being.
git-svn
is not the right tool for one-time conversions of repositories. It is a great tool if you want to use Git as frontend for an existing SVN server, but for one-time conversions you should not use git-svn
, but svn2git
which is much more suited for this use-case.
There are pleny tools called svn2git
, the probably best one is the KDE one from https://github.com/svn-all-fast-export/svn2git. I strongly recommend using that svn2git
tool. It is the best I know available out there and it is very flexible in what you can do with its rules files.
If you are not 100% about the history of your repository, svneverever
from http://blog.hartwork.org/?p=763 is a great tool to investigate the history of an SVN repository when migrating it to Git.
If you still want to use git svn
, you don't need to manally hunk your fetching. Just do git svn clone ...
, if you want to pause, cancel the execution and then do git svn fetch
to continue the fetching process. It will automatically continue where it stopped working and even validate the last fetched revision on whether it was fetched completely or needs to be refetched.
If you still want to manually hunk your fetching, be aware that git svn clone ...
is exactly the same as git svn init ...
followed by git svn fetch
, with the exception that according to the clone
specific parameters the config properties svn-remote.<remote name>.preserve-empty-dirs
is set to true
and svn-remote.<remote name>.placeholder-filename
is set to the argument you gave it between init
and fetch
. So just do that manually after your init and before your fetch and you are fine.
One note though: preserve-empty-dirs
afair is only necessary if you need to have those empty directories in the Git repository and you are only using the Git repository afterwards. As long as you only use git svn
as frontend to an exiting SVN repository, the emtpy dirs should automatically be created in your workspace and need not be part of the actual repository history. What preserve-empty-dirs
does, is to add an empty .gitignore
file (or whatever you configured with the other parameter / config property) to the commit, so that the folder essentially is not empty anymore. This is done so as Git is a content tracker, not a filesystem tracker. It tracks your sourcecode that happens to be stored in files, not the files and folders itself. That is also why there is no such thing as an explicit move
or copy
operation in Git, because moves and copies are determined on the fly where necessary and wanted. Technically it is just a remove
and add
for move
or a simple add
for copy
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With