@@ -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);
446450private:
@@ -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+
10541155int 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