1
2
3
4
5
6
7
8
9
10
11 package org.eclipse.jgit.internal.storage.file;
12
13 import static java.nio.charset.StandardCharsets.UTF_8;
14
15 import java.io.File;
16 import java.io.IOException;
17 import java.nio.file.Files;
18 import java.nio.file.NoSuchFileException;
19 import java.nio.file.attribute.FileTime;
20 import java.text.ParseException;
21 import java.time.Instant;
22
23 import org.eclipse.jgit.api.errors.JGitInternalException;
24 import org.eclipse.jgit.lib.ConfigConstants;
25 import org.eclipse.jgit.util.FileUtils;
26 import org.eclipse.jgit.util.GitDateParser;
27 import org.eclipse.jgit.util.SystemReader;
28
29
30
31
32 class GcLog {
33 private final FileRepository repo;
34
35 private final File logFile;
36
37 private final LockFile lock;
38
39 private Instant gcLogExpire;
40
41 private static final String LOG_EXPIRY_DEFAULT = "1.day.ago";
42
43 private boolean nonEmpty = false;
44
45
46
47
48
49
50
51 GcLog(FileRepository repo) {
52 this.repo = repo;
53 logFile = new File(repo.getDirectory(), "gc.log");
54 lock = new LockFile(logFile);
55 }
56
57 private Instant getLogExpiry() throws ParseException {
58 if (gcLogExpire == null) {
59 String logExpiryStr = repo.getConfig().getString(
60 ConfigConstants.CONFIG_GC_SECTION, null,
61 ConfigConstants.CONFIG_KEY_LOGEXPIRY);
62 if (logExpiryStr == null) {
63 logExpiryStr = LOG_EXPIRY_DEFAULT;
64 }
65 gcLogExpire = GitDateParser.parse(logExpiryStr, null,
66 SystemReader.getInstance().getLocale()).toInstant();
67 }
68 return gcLogExpire;
69 }
70
71 private boolean autoGcBlockedByOldLockFile() {
72 try {
73 FileTime lastModified = Files.getLastModifiedTime(FileUtils.toPath(logFile));
74 if (lastModified.toInstant().compareTo(getLogExpiry()) > 0) {
75
76 return true;
77 }
78 } catch (NoSuchFileException e) {
79
80 } catch (IOException | ParseException e) {
81 throw new JGitInternalException(e.getMessage(), e);
82 }
83 return false;
84 }
85
86
87
88
89
90
91 boolean lock() {
92 try {
93 if (!lock.lock()) {
94 return false;
95 }
96 } catch (IOException e) {
97 throw new JGitInternalException(e.getMessage(), e);
98 }
99 if (autoGcBlockedByOldLockFile()) {
100 lock.unlock();
101 return false;
102 }
103 return true;
104 }
105
106
107
108
109 void unlock() {
110 lock.unlock();
111 }
112
113
114
115
116
117
118
119 boolean commit() {
120 if (nonEmpty) {
121 return lock.commit();
122 }
123 logFile.delete();
124 lock.unlock();
125 return true;
126 }
127
128
129
130
131
132
133
134
135
136 void write(String content) throws IOException {
137 if (content.length() > 0) {
138 nonEmpty = true;
139 }
140 lock.write(content.getBytes(UTF_8));
141 }
142 }