Skip to content

Commit 189d926

Browse files
eric-h-itesofttnyblom
authored andcommitted
empty-dirs option now manages existing folder becaming empty and merging with empty fodlers
1 parent f5bd7b0 commit 189d926

File tree

1 file changed

+102
-1
lines changed

1 file changed

+102
-1
lines changed

src/svn.cpp

+102-1
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,10 @@ class SvnRevision
441441
apr_hash_t *changes, apr_pool_t *pool);
442442
int addGitIgnore(apr_pool_t *pool, const char *key, QString path,
443443
svn_fs_root_t *fs_root, Repository::Transaction *txn, const char *content = NULL);
444+
int checkParentNotEmpty(apr_pool_t *pool, const char *key, QString path,
445+
svn_fs_root_t *fs_root, Repository::Transaction *txn);
446+
int addGitIgnoreOnBranch(apr_pool_t *pool, QString key, QString path,
447+
svn_fs_root_t *fs_root, Repository::Transaction *txn);
444448
int fetchIgnoreProps(QString *ignore, apr_pool_t *pool, const char *key, svn_fs_root_t *fs_root);
445449
int fetchUnknownProps(apr_pool_t *pool, const char *key, svn_fs_root_t *fs_root);
446450
private:
@@ -835,8 +839,29 @@ int SvnRevision::exportInternal(const char *key, const svn_fs_path_change2_t *ch
835839
<< qPrintable(prevbranch);
836840
}
837841

838-
if (repo->createBranch(branch, revnum, prevbranch, rev_from) == EXIT_FAILURE)
842+
if (repo->createBranch(branch, revnum, prevbranch, rev_from) == EXIT_FAILURE) {
839843
return EXIT_FAILURE;
844+
}
845+
846+
if(CommandLineParser::instance()->contains("empty-dirs")) {
847+
Repository::Transaction *txn = transactions.value(repository + branch, 0);
848+
if (!txn) {
849+
txn = repo->newTransaction(branch, svnprefix, revnum);
850+
if (!txn)
851+
return EXIT_FAILURE;
852+
transactions.insert(repository + branch, txn);
853+
}
854+
855+
AprAutoPool pool_from(pool.data());
856+
svn_fs_root_t *fs_root_from;
857+
if (svn_fs_revision_root(&fs_root_from, fs, rev_from, pool_from) != SVN_NO_ERROR) {
858+
return EXIT_FAILURE;
859+
}
860+
861+
QString qkey = QString::fromUtf8(key);
862+
addGitIgnoreOnBranch(pool_from, qkey, "", fs_root_from, txn);
863+
}
864+
840865

841866
if(CommandLineParser::instance()->contains("svn-branches")) {
842867
Repository::Transaction *txn = transactions.value(repository + branch, 0);
@@ -850,6 +875,7 @@ int SvnRevision::exportInternal(const char *key, const svn_fs_path_change2_t *ch
850875
if(ruledebug)
851876
qDebug() << "Create a true SVN copy of branch (" << key << "->" << branch << path << ")";
852877
txn->deleteFile(path);
878+
checkParentNotEmpty(pool, key, path, fs_root, txn);
853879
recursiveDumpDir(txn, fs, fs_root, key, path, pool, revnum, rule, matchRules, ruledebug);
854880
}
855881
if (rule.annotate) {
@@ -886,11 +912,13 @@ int SvnRevision::exportInternal(const char *key, const svn_fs_path_change2_t *ch
886912
if(ruledebug)
887913
qDebug() << "replaced with empty path (" << branch << path << ")";
888914
txn->deleteFile(path);
915+
checkParentNotEmpty(pool, key, path, fs_root, txn);
889916
}
890917
if (change->change_kind == svn_fs_path_change_delete) {
891918
if(ruledebug)
892919
qDebug() << "delete (" << branch << path << ")";
893920
txn->deleteFile(path);
921+
checkParentNotEmpty(pool, key, path, fs_root, txn);
894922
} else if (!current.endsWith('/')) {
895923
if(ruledebug)
896924
qDebug() << "add/change file (" << key << "->" << branch << path << ")";
@@ -908,6 +936,7 @@ int SvnRevision::exportInternal(const char *key, const svn_fs_path_change2_t *ch
908936
}
909937

910938
txn->deleteFile(path);
939+
checkParentNotEmpty(pool, key, path, fs_root, txn);
911940

912941
// Add GitIgnore with svn:ignore
913942
int ignoreSet = false;
@@ -1051,6 +1080,78 @@ int SvnRevision::addGitIgnore(apr_pool_t *pool, const char *key, QString path,
10511080
return EXIT_SUCCESS;
10521081
}
10531082

1083+
int SvnRevision::checkParentNotEmpty(apr_pool_t *pool, const char *key, QString path,
1084+
svn_fs_root_t *fs_root, Repository::Transaction *txn)
1085+
{
1086+
if (!CommandLineParser::instance()->contains("empty-dirs")) {
1087+
return EXIT_FAILURE;
1088+
}
1089+
QString slash = "/";
1090+
QString qkey = QString::fromUtf8(key);
1091+
while (qkey.endsWith('/'))
1092+
qkey = qkey.mid(0, qkey.length()-1);
1093+
int index = qkey.lastIndexOf(slash);
1094+
if (index == -1) {
1095+
return EXIT_FAILURE;
1096+
}
1097+
QString parentKey = qkey.left(index);
1098+
1099+
apr_hash_t *entries;
1100+
SVN_ERR(svn_fs_dir_entries(&entries, fs_root, parentKey.toStdString().c_str(), pool));
1101+
if (apr_hash_count(entries)!=0) {
1102+
return EXIT_FAILURE;
1103+
}
1104+
1105+
QString cleanPath = path;
1106+
while (cleanPath.endsWith('/'))
1107+
cleanPath = cleanPath.mid(0, cleanPath.length()-1);
1108+
index = cleanPath.lastIndexOf(slash);
1109+
QString parentPath = cleanPath.left(index);
1110+
1111+
// Add gitignore-File
1112+
QString gitIgnorePath = parentPath + "/.gitignore";
1113+
QIODevice *io = txn->addFile(gitIgnorePath, 33188, 0);
1114+
if (!CommandLineParser::instance()->contains("dry-run")) {
1115+
io->putChar('\n');
1116+
}
1117+
1118+
return EXIT_SUCCESS;
1119+
}
1120+
1121+
int SvnRevision::addGitIgnoreOnBranch(apr_pool_t *pool, QString key, QString path,
1122+
svn_fs_root_t *fs_root, Repository::Transaction *txn)
1123+
{
1124+
apr_hash_t *entries;
1125+
if (svn_fs_dir_entries(&entries, fs_root, key.toStdString().c_str(), pool) != SVN_NO_ERROR) {
1126+
return EXIT_FAILURE;
1127+
}
1128+
1129+
QMap<QByteArray, svn_node_kind_t> map;
1130+
for (apr_hash_index_t *i = apr_hash_first(pool, entries); i; i = apr_hash_next(i)) {
1131+
const void *vkey;
1132+
void *value;
1133+
apr_hash_this(i, &vkey, NULL, &value);
1134+
svn_fs_dirent_t *dirent = reinterpret_cast<svn_fs_dirent_t *>(value);
1135+
map.insertMulti(QByteArray(dirent->name), dirent->kind);
1136+
}
1137+
1138+
QMapIterator<QByteArray, svn_node_kind_t> i(map);
1139+
while (i.hasNext()) {
1140+
i.next();
1141+
QString entryName = key + "/" + i.key();
1142+
QString entryFinalName = path + QString::fromUtf8(i.key());
1143+
1144+
if (i.value() == svn_node_dir) {
1145+
entryFinalName += "/";
1146+
if (addGitIgnore(pool, entryName.toStdString().c_str(), entryFinalName, fs_root, txn) == EXIT_FAILURE) {
1147+
addGitIgnoreOnBranch(pool, entryName, entryFinalName, fs_root, txn);
1148+
}
1149+
}
1150+
}
1151+
1152+
return EXIT_SUCCESS;
1153+
}
1154+
10541155
int SvnRevision::fetchIgnoreProps(QString *ignore, apr_pool_t *pool, const char *key, svn_fs_root_t *fs_root)
10551156
{
10561157
// Get svn:ignore

0 commit comments

Comments
 (0)