aboutsummaryrefslogtreecommitdiffstats
path: root/src/repository.cpp
diff options
context:
space:
mode:
authorRaja R Harinath <harinath@hurrynot.org>2010-07-06 23:08:23 +0530
committerRaja R Harinath <harinath@hurrynot.org>2010-07-08 19:22:34 +0530
commit4cbcd3021d803012d31356b5cb36982a9921b2df (patch)
treec66d8f0ce1386d343e75441d096fe6bf17aa97eb /src/repository.cpp
parent8d462d3531a702655c5b81c6c6c9409d6a320150 (diff)
downloadsvn2git-4cbcd3021d803012d31356b5cb36982a9921b2df.tar
svn2git-4cbcd3021d803012d31356b5cb36982a9921b2df.tar.gz
svn2git-4cbcd3021d803012d31356b5cb36982a9921b2df.tar.bz2
svn2git-4cbcd3021d803012d31356b5cb36982a9921b2df.tar.xz
svn2git-4cbcd3021d803012d31356b5cb36982a9921b2df.zip
Handle SVN directory deletes that lead to branch deletes
SVN directory deletes often indicate one or more branch deletions. However, since the deleted directory isn't present in the resulting revision, several of the indicators used by the rule-application mechanism aren't present. This forces us to introduce several useless dummy rules to avoid errors. We now note deletions and use the previous revision to determine several properties, including whether the deleted item is a directory or not, and to enumerate the contents of the directory in recurse mode. We add an additional heuristic for unknown repositories -- i.e., when a rule fired, but it's repository was invalid. We recurse in this case hoping to catch a more specific rule. I believe this is safe: because some other rule must've seen the same directory before, when it or a subdirectory was created, and decided _not_ to create a repository at that point -- so recursing and/or ignoring the contents of the just deleted directory won't corrupt the history, it can only improve it. We use mark :0 to note mark deletions internally, and in the progress logs. (Note that cvs2svn creates wierd commits where a whole tree is copied first, and then subtrees are pruned. In such cases, neither the previous revision nor the current revision have the deleted directory -- we ignore this case as before. There's no information loss since the final contents of the revision are exactly what is desired.)
Diffstat (limited to 'src/repository.cpp')
-rw-r--r--src/repository.cpp26
1 files changed, 25 insertions, 1 deletions
diff --git a/src/repository.cpp b/src/repository.cpp
index 5250f71..847771f 100644
--- a/src/repository.cpp
+++ b/src/repository.cpp
@@ -141,7 +141,7 @@ void Repository::createBranch(const QString &branch, int revnum,
branchRef.prepend("refs/heads/");
Branch &br = branches[branch];
- if (br.created && br.created != revnum) {
+ if (br.created && br.created != revnum && br.marks.last()) {
QByteArray backupBranch = branchRef + '_' + QByteArray::number(revnum);
qWarning() << branch << "already exists; backing up to" << backupBranch;
@@ -193,6 +193,30 @@ void Repository::createBranch(const QString &branch, int revnum,
+ "\n\n");
}
+void Repository::deleteBranch(const QString &branch, int revnum)
+{
+ QByteArray branchRef = branch.toUtf8();
+ if (!branchRef.startsWith("refs/"))
+ branchRef.prepend("refs/heads/");
+
+ Branch &br = branches[branch];
+ if (br.created && br.created != revnum && br.marks.last()) {
+ QByteArray backupBranch = branchRef + '_' + QByteArray::number(revnum);
+ qWarning() << "backing up branch" << branch << "to" << backupBranch;
+
+ fastImport.write("reset " + backupBranch + "\nfrom " + branchRef + "\n\n");
+ }
+
+ br.created = revnum;
+ br.commits.append(revnum);
+ br.marks.append(0);
+
+ static QByteArray null_sha(40, '0');
+ fastImport.write("reset " + branchRef + "\nfrom " + null_sha + "\n\n"
+ "progress SVN r" + QByteArray::number(revnum)
+ + " branch " + branch.toUtf8() + " = :0 # delete\n\n");
+}
+
Repository::Transaction *Repository::newTransaction(const QString &branch, const QString &svnprefix,
int revnum)
{