blob: c77d95037770cdfb1fff7119bd99d1da499d6473 (
plain)
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
|
/*
* Copyright (C) 2021, Tencent.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
* https://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.internal.storage.commitgraph;
import java.io.IOException;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectIdOwnerMap;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.revwalk.RevSort;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.util.BlockList;
/**
* The commits which are used by the commit-graph writer to:
* <ul>
* <li>List commits in SHA1 order.</li>
* <li>Get the position of a specific SHA1 in the list.</li>
* </ul>
*
* @since 6.5
*/
public class GraphCommits implements Iterable<RevCommit> {
/**
* Prepare and create the commits for
* {@link org.eclipse.jgit.internal.storage.commitgraph.CommitGraphWriter}
* from the RevWalk.
*
* @param pm
* progress monitor.
* @param wants
* the list of wanted objects, writer walks commits starting at
* these. Must not be {@code null}.
* @param walk
* the RevWalk to use. Must not be {@code null}.
* @return the commits' collection which are used by the commit-graph
* writer. Never null.
* @throws IOException
* if an error occurred
*/
public static GraphCommits fromWalk(ProgressMonitor pm,
@NonNull Set<? extends ObjectId> wants, @NonNull RevWalk walk)
throws IOException {
walk.reset();
walk.sort(RevSort.NONE);
walk.setRetainBody(false);
for (ObjectId id : wants) {
RevObject o = walk.parseAny(id);
if (o instanceof RevCommit) {
walk.markStart((RevCommit) o);
}
}
List<RevCommit> commits = new BlockList<>();
RevCommit c;
pm.beginTask(JGitText.get().findingCommitsForCommitGraph,
ProgressMonitor.UNKNOWN);
while ((c = walk.next()) != null) {
pm.update(1);
commits.add(c);
}
pm.endTask();
return new GraphCommits(commits, walk.getObjectReader());
}
private final List<RevCommit> sortedCommits;
private final ObjectIdOwnerMap<CommitWithPosition> commitPosMap;
private final int extraEdgeCnt;
private final ObjectReader objectReader;
/**
* Initialize the GraphCommits.
*
* @param commits
* list of commits with their headers already parsed.
* @param objectReader
* object reader
*/
private GraphCommits(List<RevCommit> commits, ObjectReader objectReader) {
Collections.sort(commits); // sorted by name
sortedCommits = commits;
commitPosMap = new ObjectIdOwnerMap<>();
int cnt = 0;
for (int i = 0; i < commits.size(); i++) {
RevCommit c = sortedCommits.get(i);
if (c.getParentCount() > 2) {
cnt += c.getParentCount() - 1;
}
commitPosMap.add(new CommitWithPosition(c, i));
}
this.extraEdgeCnt = cnt;
this.objectReader = objectReader;
}
int getOidPosition(RevCommit c) throws MissingObjectException {
CommitWithPosition commitWithPosition = commitPosMap.get(c);
if (commitWithPosition == null) {
throw new MissingObjectException(c, Constants.OBJ_COMMIT);
}
return commitWithPosition.position;
}
int getExtraEdgeCnt() {
return extraEdgeCnt;
}
int size() {
return sortedCommits.size();
}
ObjectReader getObjectReader() {
return objectReader;
}
@Override
public Iterator<RevCommit> iterator() {
return sortedCommits.iterator();
}
private static class CommitWithPosition extends ObjectIdOwnerMap.Entry {
final int position;
CommitWithPosition(AnyObjectId id, int position) {
super(id);
this.position = position;
}
}
}
|