2
2
{
3
3
using GitVersion . Helpers ;
4
4
using System ;
5
+ using System . Collections . Generic ;
5
6
using System . IO ;
6
7
using System . Security . Cryptography ;
7
8
using System . Text ;
9
+ using System . Linq ;
8
10
9
- public class GitVersionCacheKeyFactory
11
+ class GitVersionCacheKeyFactory
10
12
{
11
13
public static GitVersionCacheKey Create ( IFileSystem fileSystem , GitPreparer gitPreparer , Config overrideConfig )
12
14
{
@@ -23,10 +25,101 @@ private static string GetGitSystemHash(GitPreparer gitPreparer, IFileSystem file
23
25
{
24
26
var dotGitDirectory = gitPreparer . GetDotGitDirectory ( ) ;
25
27
26
- // Maybe using timestamp in .git/refs directory is enough?
27
- var lastGitRefsChangedTicks = fileSystem . GetLastDirectoryWrite ( Path . Combine ( dotGitDirectory , "refs" ) ) ;
28
+ // traverse the directory and get a list of files, use that for GetHash
29
+ var contents = CalculateDirectoryContents ( Path . Combine ( dotGitDirectory , "refs" ) ) ;
28
30
29
- return GetHash ( dotGitDirectory , lastGitRefsChangedTicks . ToString ( ) ) ;
31
+ return GetHash ( contents . ToArray ( ) ) ;
32
+ }
33
+
34
+ // based on https://msdn.microsoft.com/en-us/library/bb513869.aspx
35
+ private static List < string > CalculateDirectoryContents ( string root )
36
+ {
37
+ var result = new List < string > ( ) ;
38
+
39
+ // Data structure to hold names of subfolders to be
40
+ // examined for files.
41
+ var dirs = new Stack < string > ( ) ;
42
+
43
+ if ( ! Directory . Exists ( root ) )
44
+ {
45
+ throw new ArgumentException ( ) ;
46
+ }
47
+
48
+ dirs . Push ( root ) ;
49
+
50
+ while ( dirs . Any ( ) )
51
+ {
52
+ string currentDir = dirs . Pop ( ) ;
53
+
54
+ var di = new DirectoryInfo ( currentDir ) ;
55
+ result . Add ( di . Name ) ;
56
+
57
+ string [ ] subDirs ;
58
+ try
59
+ {
60
+ subDirs = Directory . GetDirectories ( currentDir ) ;
61
+ }
62
+ // An UnauthorizedAccessException exception will be thrown if we do not have
63
+ // discovery permission on a folder or file. It may or may not be acceptable
64
+ // to ignore the exception and continue enumerating the remaining files and
65
+ // folders. It is also possible (but unlikely) that a DirectoryNotFound exception
66
+ // will be raised. This will happen if currentDir has been deleted by
67
+ // another application or thread after our call to Directory.Exists. The
68
+ // choice of which exceptions to catch depends entirely on the specific task
69
+ // you are intending to perform and also on how much you know with certainty
70
+ // about the systems on which this code will run.
71
+ catch ( UnauthorizedAccessException e )
72
+ {
73
+ Logger . WriteError ( e . Message ) ;
74
+ continue ;
75
+ }
76
+ catch ( DirectoryNotFoundException e )
77
+ {
78
+ Logger . WriteError ( e . Message ) ;
79
+ continue ;
80
+ }
81
+
82
+ string [ ] files = null ;
83
+ try
84
+ {
85
+ files = Directory . GetFiles ( currentDir ) ;
86
+ }
87
+ catch ( UnauthorizedAccessException e )
88
+ {
89
+ Logger . WriteError ( e . Message ) ;
90
+ continue ;
91
+ }
92
+ catch ( DirectoryNotFoundException e )
93
+ {
94
+ Logger . WriteError ( e . Message ) ;
95
+ continue ;
96
+ }
97
+
98
+ foreach ( string file in files )
99
+ {
100
+ try
101
+ {
102
+ var fi = new FileInfo ( file ) ;
103
+ result . Add ( fi . Name ) ;
104
+ result . Add ( File . ReadAllText ( file ) ) ;
105
+ }
106
+ catch ( IOException e )
107
+ {
108
+ Logger . WriteError ( e . Message ) ;
109
+ continue ;
110
+ }
111
+ }
112
+
113
+ // Push the subdirectories onto the stack for traversal.
114
+ // This could also be done before handing the files.
115
+ // push in reverse order
116
+ for ( int i = subDirs . Length - 1 ; i >= 0 ; i -- )
117
+ {
118
+ dirs . Push ( subDirs [ i ] ) ;
119
+ }
120
+ }
121
+
122
+ return result ;
30
123
}
31
124
32
125
private static string GetRepositorySnapshotHash ( GitPreparer gitPreparer )
0 commit comments