@@ -14,21 +14,28 @@ public static void Run(string repositoryPath, IEnumerable<string> filesToDelete,
1414 {
1515 var fileDeleteStrategies = new FileDeletionStrategies ( filesToDelete ) ;
1616 var folderDeleteStrategies = new FolderDeletionStrategies ( foldersToDelete ) ;
17- var rewrittenCommits = RemoveObjectsFromTree ( repositoryPath , fileDeleteStrategies , folderDeleteStrategies ) ;
17+
18+ var relevantPathes =
19+ fileDeleteStrategies . RelevantPaths . Union ( folderDeleteStrategies . RelevantPaths ) . ToList ( ) ;
20+
21+ var rewrittenCommits = RemoveObjectsFromTree ( repositoryPath , fileDeleteStrategies , folderDeleteStrategies ,
22+ relevantPathes ) ;
1823 if ( rewrittenCommits . Any ( ) )
1924 Refs . Update ( repositoryPath , rewrittenCommits ) ;
2025 }
2126
2227 public static Dictionary < ObjectHash , ObjectHash > RemoveObjectsFromTree ( string vcsPath ,
23- FileDeletionStrategies filesToDelete , FolderDeletionStrategies foldersToDelete )
28+ FileDeletionStrategies filesToDelete , FolderDeletionStrategies foldersToDelete ,
29+ List < byte [ ] > relevantPaths )
2430 {
2531 var rewrittenCommits = new Dictionary < ObjectHash , ObjectHash > ( ) ;
2632 var rewrittenTrees = new ConcurrentDictionary < ObjectHash , ObjectHash > ( ) ;
2733
2834 foreach ( var commit in CommitWalker
2935 . CommitsInOrder ( vcsPath ) )
3036 {
31- var newTreeHash = RemoveObjectFromTree ( vcsPath , commit . TreeHash , filesToDelete , foldersToDelete , rewrittenTrees , new byte [ 0 ] ) ;
37+ var newTreeHash = RemoveObjectFromTree ( vcsPath , commit . TreeHash , filesToDelete , foldersToDelete ,
38+ rewrittenTrees , new byte [ 0 ] , relevantPaths ) ;
3239 if ( newTreeHash != commit . TreeHash )
3340 {
3441 var newCommit = Commit . GetSerializedCommitWithChangedTreeAndParents ( commit , newTreeHash ,
@@ -51,17 +58,50 @@ public static Dictionary<ObjectHash, ObjectHash> RemoveObjectsFromTree(string vc
5158 private static readonly ArrayPool < byte > FilePathPool = ArrayPool < byte > . Shared ;
5259 private static readonly TreeLineByHashComparer TreeLineByHashComparer = new TreeLineByHashComparer ( ) ;
5360
61+ private static bool IsPathRelevant ( in ReadOnlySpan < byte > currentPath , List < byte [ ] > relevantPathes )
62+ {
63+ if ( currentPath . Length == 0 || ! relevantPathes . Any ( ) )
64+ return true ;
65+
66+ for ( int i = relevantPathes . Count - 1 ; i >= 0 ; i -- )
67+ {
68+ var path = relevantPathes [ i ] ;
69+
70+ if ( currentPath . Length > path . Length )
71+ continue ;
72+
73+ var isRelevant = true ;
74+ for ( int j = currentPath . Length - 1 ; j >= 0 ; j -- )
75+ {
76+ if ( currentPath [ j ] != path [ j ] )
77+ {
78+ isRelevant = false ;
79+ break ;
80+ }
81+ }
82+
83+ if ( isRelevant )
84+ return true ;
85+ }
86+
87+ return false ;
88+ }
89+
5490 private static ObjectHash RemoveObjectFromTree (
5591 string vcsPath ,
5692 ObjectHash treeHash ,
5793 FileDeletionStrategies filesToRemove ,
5894 FolderDeletionStrategies foldersToRemove ,
5995 ConcurrentDictionary < ObjectHash , ObjectHash > rewrittenTrees ,
60- ReadOnlySpan < byte > currentPath )
96+ in ReadOnlySpan < byte > currentPath ,
97+ List < byte [ ] > relevantPathes )
6198 {
6299 if ( rewrittenTrees . TryGetValue ( treeHash , out var rewrittenHash ) )
63100 return rewrittenHash ;
64101
102+ if ( ! IsPathRelevant ( currentPath , relevantPathes ) )
103+ return treeHash ;
104+
65105 var tree = GitObjectFactory . ReadTree ( vcsPath , treeHash ) ;
66106 var resultingLines = new List < Tree . TreeLine > ( ) ;
67107 foreach ( var line in tree . Lines )
@@ -89,7 +129,8 @@ private static ObjectHash RemoveObjectFromTree(
89129 filesToRemove ,
90130 foldersToRemove ,
91131 rewrittenTrees ,
92- path ) ;
132+ path ,
133+ relevantPathes ) ;
93134
94135 FilePathPool . Return ( rentedPathBytes ) ;
95136
0 commit comments