-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgitFileDates.dpr
More file actions
130 lines (110 loc) · 4.01 KB
/
gitFileDates.dpr
File metadata and controls
130 lines (110 loc) · 4.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
program gitFileDates;
{$APPTYPE CONSOLE}
{$R *.res}
(* ****************************************************************************************
gitFileDates
(c) Michael Schumann
I share this code with anyone who can use it without any warranty for any purpose.
Of course no attibution is required if its used.
Save and restore last file write attribite for those who use git under Windows.
Created because I use to check in all required files for building the application
including DLLs. As some update mechanisms rely on file dates it is important to restore
them before building the package.
How to use
If using TortoiseGit just create a Tortoise hook (in Tortoise settings) calling this program
"on start commit" like this:
gitFileDates /dir <root path to source> /save
creates the file .gitfileattr with all file last modified informations, must be checked in.
When building the project with a runner (gitlab-ci) include one stage after checkout like
this:
gitFileDates /dir <root path to source> /apply
applies the timestamps saved in .gitfileattr to the source tree.
Timestamps of folders will not be modified.
The code is more or less quick and dirty. No try/finally for destroying objects as it quits
anyway and not memory traces are left.
**************************************************************************************** *)
uses
Classes,
Windows,
jclFileUtils,
SysUtils;
var
sl, sl1: TStringList;
i, j, fage: integer;
s, curdir: string;
function PathRelativePathTo(pszPath: PChar; pszFrom: PChar; dwAttrFrom: DWORD; pszTo: PChar; dwAtrTo: DWORD): LongBool;
stdcall; external 'shlwapi.dll' name 'PathRelativePathToW';
function AbsToRel(const AbsPath, BasePath: string): string;
var
Path: array [0 .. MAX_PATH - 1] of char;
begin
PathRelativePathTo(@Path[0], PChar(BasePath), FILE_ATTRIBUTE_DIRECTORY, PChar(AbsPath), 0);
Result := Path;
end;
function PathCanonicalize(lpszDst: PChar; lpszSrc: PChar): LongBool; stdcall;
external 'shlwapi.dll' name 'PathCanonicalizeW';
function RelToAbs(const RelPath, BasePath: string): string;
var
Dst: array [0 .. MAX_PATH - 1] of char;
begin
PathCanonicalize(@Dst[0], PChar(IncludeTrailingBackslash(BasePath) + RelPath));
Result := Dst;
end;
begin
try
if not FindCmdLineSwitch('save') and not FindCmdLineSwitch('apply') then
begin
writeln('Usage: gitFileDates /save or /apply');
exit;
end;
curdir := getCurrentDir;
if FindCmdLineSwitch('dir') then
FindCmdLineSwitch('dir', curdir, true, [clstValueNextParam]);
curdir := IncludeTrailingPathDelimiter(curdir);
if FindCmdLineSwitch('save') then
begin
sl := TStringList.create;
sl1 := TStringList.create;
advBuildFileList(curdir + '*.*', faAnyFile, sl, amSuperSetOf, [flRecursive, flFullNames]);
for i := 0 to sl.count - 1 do
if pos('\.git\', sl[i]) = 0 then
begin
if (extractFileName(sl[i]) <> '.') and (extractFileName(sl[i]) <> '..') and (FileAge(sl[i]) > -1) then
sl1.add(AbsToRel(sl[i], curdir) + ':' + intToStr(FileAge(sl[i])));
end;
sl1.saveToFile(curdir + '.gitfileattr');
sl.free;
sl1.free;
end;
if FindCmdLineSwitch('apply') then
begin
if not fileExists(curdir + '.gitfileattr') then
begin
writeln('File .gitfileattr not found.');
exit;
end;
sl := TStringList.create;
sl1 := TStringList.create;
sl1.delimiter := ':';
sl1.strictDelimiter := true;
sl.loadFromFile(curdir + '.gitfileattr');
for i := 0 to sl.count - 1 do
begin
sl1.delimitedText := sl[i];
s := RelToAbs(sl1[0], curdir);
if (pos('\.git\', s) = 0) and fileExists(s) then
begin
fage := StrToInt(sl1[1]);
j := FileSetDate(s, fage);
if j <> 0 then
writeln('Error ' + intToStr(j) + ' file ' + s);
end;
end;
sl1.free;
sl.free;
end;
except
on E: Exception do
writeln(E.ClassName, ': ', E.Message);
end;
end.