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
11
public class GitVersionCacheKeyFactory
10
12
{
@@ -23,10 +25,103 @@ 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
+
88
+ catch ( UnauthorizedAccessException e )
89
+ {
90
+ Logger . WriteError ( e . Message ) ;
91
+ continue ;
92
+ }
93
+
94
+ catch ( DirectoryNotFoundException e )
95
+ {
96
+ Logger . WriteError ( e . Message ) ;
97
+ continue ;
98
+ }
99
+
100
+ foreach ( string file in files )
101
+ {
102
+ try
103
+ {
104
+ var fi = new FileInfo ( file ) ;
105
+ result . Add ( fi . Name ) ;
106
+ result . Add ( File . ReadAllText ( file ) ) ;
107
+ }
108
+ catch ( IOException e )
109
+ {
110
+ Logger . WriteError ( e . Message ) ;
111
+ continue ;
112
+ }
113
+ }
114
+
115
+ // Push the subdirectories onto the stack for traversal.
116
+ // This could also be done before handing the files.
117
+ // push in reverse order
118
+ for ( int i = subDirs . Length - 1 ; i >= 0 ; i -- )
119
+ {
120
+ dirs . Push ( subDirs [ i ] ) ;
121
+ }
122
+ }
123
+
124
+ return result ;
30
125
}
31
126
32
127
private static string GetRepositorySnapshotHash ( GitPreparer gitPreparer )
0 commit comments