@@ -441,6 +441,10 @@ class SvnRevision
441
441
apr_hash_t *changes, apr_pool_t *pool);
442
442
int addGitIgnore (apr_pool_t *pool, const char *key, QString path,
443
443
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);
444
448
int fetchIgnoreProps (QString *ignore, apr_pool_t *pool, const char *key, svn_fs_root_t *fs_root);
445
449
int fetchUnknownProps (apr_pool_t *pool, const char *key, svn_fs_root_t *fs_root);
446
450
private:
@@ -835,8 +839,29 @@ int SvnRevision::exportInternal(const char *key, const svn_fs_path_change2_t *ch
835
839
<< qPrintable (prevbranch);
836
840
}
837
841
838
- if (repo->createBranch (branch, revnum, prevbranch, rev_from) == EXIT_FAILURE)
842
+ if (repo->createBranch (branch, revnum, prevbranch, rev_from) == EXIT_FAILURE) {
839
843
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
+
840
865
841
866
if (CommandLineParser::instance ()->contains (" svn-branches" )) {
842
867
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
850
875
if (ruledebug)
851
876
qDebug () << " Create a true SVN copy of branch (" << key << " ->" << branch << path << " )" ;
852
877
txn->deleteFile (path);
878
+ checkParentNotEmpty (pool, key, path, fs_root, txn);
853
879
recursiveDumpDir (txn, fs, fs_root, key, path, pool, revnum, rule, matchRules, ruledebug);
854
880
}
855
881
if (rule.annotate ) {
@@ -886,11 +912,13 @@ int SvnRevision::exportInternal(const char *key, const svn_fs_path_change2_t *ch
886
912
if (ruledebug)
887
913
qDebug () << " replaced with empty path (" << branch << path << " )" ;
888
914
txn->deleteFile (path);
915
+ checkParentNotEmpty (pool, key, path, fs_root, txn);
889
916
}
890
917
if (change->change_kind == svn_fs_path_change_delete) {
891
918
if (ruledebug)
892
919
qDebug () << " delete (" << branch << path << " )" ;
893
920
txn->deleteFile (path);
921
+ checkParentNotEmpty (pool, key, path, fs_root, txn);
894
922
} else if (!current.endsWith (' /' )) {
895
923
if (ruledebug)
896
924
qDebug () << " add/change file (" << key << " ->" << branch << path << " )" ;
@@ -908,6 +936,7 @@ int SvnRevision::exportInternal(const char *key, const svn_fs_path_change2_t *ch
908
936
}
909
937
910
938
txn->deleteFile (path);
939
+ checkParentNotEmpty (pool, key, path, fs_root, txn);
911
940
912
941
// Add GitIgnore with svn:ignore
913
942
int ignoreSet = false ;
@@ -1051,6 +1080,78 @@ int SvnRevision::addGitIgnore(apr_pool_t *pool, const char *key, QString path,
1051
1080
return EXIT_SUCCESS;
1052
1081
}
1053
1082
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
+
1054
1155
int SvnRevision::fetchIgnoreProps (QString *ignore, apr_pool_t *pool, const char *key, svn_fs_root_t *fs_root)
1055
1156
{
1056
1157
// Get svn:ignore
0 commit comments