@@ -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, " " 
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 (" " ->" " )" 
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 (" " )" 
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 (" " )" 
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 (" " ->" " )" 
@@ -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 + " /" 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