forked from git-commit-id/git-commit-id-maven-plugin
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDescribeResult.java
More file actions
234 lines (196 loc) · 8.28 KB
/
DescribeResult.java
File metadata and controls
234 lines (196 loc) · 8.28 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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/*
* This file is part of git-commit-id-plugin by Konrad Malawski <konrad.malawski@java.pl>
*
* git-commit-id-plugin is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* git-commit-id-plugin is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with git-commit-id-plugin. If not, see <http://www.gnu.org/licenses/>.
*/
package pl.project13.jgit;
import static com.google.common.collect.Lists.newArrayList;
import java.io.IOException;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.eclipse.jgit.lib.AbbreviatedObjectId;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectReader;
import com.google.common.base.Joiner;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
/**
* Represents the result of a <code>git describe</code> command.
* <p/>
* See {@link pl.project13.jgit.DescribeResult#toString()} for a detailed information how this result looks like.
*/
public class DescribeResult {
private Optional<String> tagName = Optional.absent();
private Optional<ObjectId> commitId = Optional.absent();
private Optional<AbbreviatedObjectId> abbreviatedObjectId = Optional.absent();
private int abbrev = 7;
private int commitsAwayFromTag;
private boolean dirty;
private String dirtyMarker;
private ObjectReader objectReader;
public static final DescribeResult EMPTY = new DescribeResult("");
public DescribeResult(@Nonnull String tagName) {
this(tagName, false, Optional.<String>absent());
}
public DescribeResult(@Nonnull ObjectReader objectReader, String tagName, int commitsAwayFromTag, @Nullable ObjectId commitId) {
this(objectReader, tagName, commitsAwayFromTag, commitId, false, Optional.<String>absent());
}
public DescribeResult(@Nonnull ObjectReader objectReader, @Nonnull ObjectId commitId) {
this.objectReader = objectReader;
this.commitId = Optional.of(commitId);
this.abbreviatedObjectId = createAbbreviatedCommitId(objectReader, commitId, this.abbrev);
}
public DescribeResult(@Nonnull ObjectReader objectReader, String tagName, int commitsAwayFromTag, ObjectId commitId, boolean dirty, String dirtyMarker) {
this(objectReader, tagName, commitsAwayFromTag, commitId, dirty, Optional.of(dirtyMarker));
}
public DescribeResult(@Nonnull ObjectReader objectReader, String tagName, int commitsAwayFromTag, ObjectId commitId, boolean dirty, Optional<String> dirtyMarker) {
this(objectReader, commitId, dirty, dirtyMarker);
this.tagName = Optional.of(tagName);
this.commitsAwayFromTag = commitsAwayFromTag;
}
public DescribeResult(@Nonnull ObjectReader objectReader, @Nonnull ObjectId commitId, boolean dirty, @Nonnull Optional<String> dirtyMarker) {
this.objectReader = objectReader;
this.commitId = Optional.of(commitId);
this.abbreviatedObjectId = createAbbreviatedCommitId(objectReader, commitId, this.abbrev);
this.dirty = dirty;
this.dirtyMarker = dirtyMarker.or("");
}
public DescribeResult(@Nonnull String tagName, boolean dirty, @Nonnull Optional<String> dirtyMarker) {
this.tagName = Optional.of(tagName);
this.dirty = dirty;
this.dirtyMarker = dirtyMarker.or("");
}
@Nonnull
public DescribeResult withCommitIdAbbrev(int n) {
Preconditions.checkArgument(n >= 0, String.format("The --abbrev parameter must be >= 0, but it was: [%s]", n));
this.abbrev = n;
this.abbreviatedObjectId = createAbbreviatedCommitId(this.objectReader, this.commitId.get(), this.abbrev);
return this;
}
/**
* The format of a describe result is defined as:
* <pre>
* v1.0.4-14-g2414721-DEV
* ^ ^ ^ ^
* | | | |-- if a dirtyMarker was given, it will appear here if the repository is in "dirty" state
* | | |---------- the "g" prefixed commit id. The prefix is compatible with what git-describe would return - weird, but true.
* | |--------------- the number of commits away from the found tag. So "2414721" is 14 commits ahead of "v1.0.4", in this example.
* |-------------------- the "nearest" tag, to the mentioned commit.
* </pre>
* <p/>
* Other outputs may look like:
* <pre>
* v1.0.4 -- if the repository is "on a tag"
* v1.0.4-DEV -- if the repository is "on a tag", but in "dirty" state
* 2414721 -- a plain commit id hash if not tags were defined (of determined "near" this commit).
* It does NOT include the "g" prefix, that is used in the "full" describe output format!
* </pre>
* <p/>
* For more details (on when what output will be returned etc), see <code>man git-describe</code>.
* In general, you can assume it's a "best effort" approach, to give you as much info about the repo state as possible.
*
* @return the String representation of this Describe command
*/
@Override
public String toString() {
List<String> parts;
if (abbrevZeroHidesCommitsPartOfDescribe()) {
parts = newArrayList(tag());
} else {
parts = newArrayList(tag(), commitsAwayFromTag(), prefixedCommitId());
}
return Joiner.on("-").skipNulls().join(parts) + dirtyMarker(); // like in the describe spec the entire "-dirty" is configurable (incl. "-")
}
private boolean abbrevZeroHidesCommitsPartOfDescribe() {
return abbrev == 0;
}
@Nullable
public String commitsAwayFromTag() {
return commitsAwayFromTag == 0 ? null : String.valueOf(commitsAwayFromTag);
}
@Nullable
public String dirtyMarker() {
return dirty ? dirtyMarker : "";
}
/**
* <p>The (possibly) "g" prefixed <strong>abbriverated</strong> object id of a commit.</p>
* <p>
* The "g" prefix is prepended to be compatible with git's describe output, please refer to
* <b>man git-describe</b> to check why it's included.
* </p>
* <p>
* The "g" prefix is used when a tag is defined on this result. If it's not, this method yields a plain commit id hash.
* This is following git's behaviour - so any git tooling should be happy with this output.
* </p>
* <p>
* Notes about the abbriverated object id:<br/>
* Git will try to use your given abbrev lenght, but when it's to short to guarantee uniqueness -
* a longer one will be used (which WILL guarantee uniqueness).
* If you need the full commit id, it's always available via {@link pl.project13.jgit.DescribeResult#commitObjectId()}.
* </p>
*/
@Nullable
public String prefixedCommitId() {
if (abbreviatedObjectId.isPresent()) {
String name = abbreviatedObjectId.get().name();
return gPrefixedCommitId(name);
} else if (commitId.isPresent()) {
String name = commitId.get().name();
return gPrefixedCommitId(name);
} else {
return null;
}
}
private String gPrefixedCommitId(String name) {
if (tagName.isPresent()) {
return "g" + name;
} else {
return name;
}
}
/**
* JGit won't ever use 1 char as abbreviated ID, that's why only values of:
* <ul>
* <li>0 (special meaning - don't show commit id at all),</li>
* <li>the range from 2 to 40 (inclusive) are valid</li>
* </ul>
*
* @return the abbreviated commit id, possibly longer than the requested len (if it wouldn't be unique)
*/
private static Optional<AbbreviatedObjectId> createAbbreviatedCommitId(@Nonnull ObjectReader objectReader, ObjectId commitId, int requestedLenght) {
if(requestedLenght < 2) {
// 0 means we don't want to print commit id's at all
return Optional.absent();
}
try {
AbbreviatedObjectId abbreviatedObjectId = objectReader.abbreviate(commitId, requestedLenght);
return Optional.of(abbreviatedObjectId);
} catch (IOException e) {
return Optional.absent();
}
}
@Nullable
public ObjectId commitObjectId() {
if (commitId.isPresent()) {
return commitId.get();
} else {
return null;
}
}
@Nullable
public String tag() {
return tagName.orNull();
}
}