Rewrite resolve in terms of RevWalk
We want to eventually get rid of the mapCommit, mapTree APIs on Repository and force everyone into the faster parsers that exist in RevWalk. Rewriting resolve in terms of the faster parsers is a good first step. It actually simplifies the code a bit, as we no longer need to keep track of an ObjectId and an Object (the parsed form), since all RevObjects implicitly have their ObjectId readily available. Change-Id: I4d234630195616e2c263e7e70038b55a1be4e7a3 Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This commit is contained in:
parent
47c07e1a0d
commit
b6ba9739d5
|
@ -67,6 +67,10 @@
|
|||
import org.eclipse.jgit.errors.ConfigInvalidException;
|
||||
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
|
||||
import org.eclipse.jgit.errors.RevisionSyntaxException;
|
||||
import org.eclipse.jgit.revwalk.RevBlob;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
import org.eclipse.jgit.revwalk.RevObject;
|
||||
import org.eclipse.jgit.revwalk.RevWalk;
|
||||
import org.eclipse.jgit.util.FS;
|
||||
import org.eclipse.jgit.util.IO;
|
||||
import org.eclipse.jgit.util.RawParseUtils;
|
||||
|
@ -745,36 +749,37 @@ public RefRename renameRef(final String fromRef, final String toRef) throws IOEx
|
|||
*
|
||||
* Currently supported is combinations of these.
|
||||
* <ul>
|
||||
* <li>SHA-1 - a SHA-1</li>
|
||||
* <li>refs/... - a ref name</li>
|
||||
* <li>ref^n - nth parent reference</li>
|
||||
* <li>ref~n - distance via parent reference</li>
|
||||
* <li>ref@{n} - nth version of ref</li>
|
||||
* <li>ref^{tree} - tree references by ref</li>
|
||||
* <li>ref^{commit} - commit references by ref</li>
|
||||
* <li>SHA-1 - a SHA-1</li>
|
||||
* <li>refs/... - a ref name</li>
|
||||
* <li>ref^n - nth parent reference</li>
|
||||
* <li>ref~n - distance via parent reference</li>
|
||||
* <li>ref@{n} - nth version of ref</li>
|
||||
* <li>ref^{tree} - tree references by ref</li>
|
||||
* <li>ref^{commit} - commit references by ref</li>
|
||||
* </ul>
|
||||
*
|
||||
* Not supported is
|
||||
* Not supported is:
|
||||
* <ul>
|
||||
* <li>timestamps in reflogs, ref@{full or relative timestamp}</li>
|
||||
* <li>abbreviated SHA-1's</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param revstr A git object references expression
|
||||
* @param revstr
|
||||
* A git object references expression
|
||||
* @return an ObjectId or null if revstr can't be resolved to any ObjectId
|
||||
* @throws IOException on serious errors
|
||||
* @throws IOException
|
||||
* on serious errors
|
||||
*/
|
||||
public ObjectId resolve(final String revstr) throws IOException {
|
||||
char[] rev = revstr.toCharArray();
|
||||
Object ref = null;
|
||||
ObjectId refId = null;
|
||||
RevObject ref = null;
|
||||
RevWalk rw = new RevWalk(this);
|
||||
for (int i = 0; i < rev.length; ++i) {
|
||||
switch (rev[i]) {
|
||||
case '^':
|
||||
if (refId == null) {
|
||||
String refstr = new String(rev,0,i);
|
||||
refId = resolveSimple(refstr);
|
||||
if (refId == null)
|
||||
if (ref == null) {
|
||||
ref = parseSimple(rw, new String(rev, 0, i));
|
||||
if (ref == null)
|
||||
return null;
|
||||
}
|
||||
if (i + 1 < rev.length) {
|
||||
|
@ -790,19 +795,12 @@ public ObjectId resolve(final String revstr) throws IOException {
|
|||
case '8':
|
||||
case '9':
|
||||
int j;
|
||||
ref = mapObject(refId, null);
|
||||
while (ref instanceof Tag) {
|
||||
Tag tag = (Tag)ref;
|
||||
refId = tag.getObjId();
|
||||
ref = mapObject(refId, null);
|
||||
}
|
||||
if (!(ref instanceof Commit))
|
||||
throw new IncorrectObjectTypeException(refId, Constants.TYPE_COMMIT);
|
||||
for (j=i+1; j<rev.length; ++j) {
|
||||
ref = rw.parseCommit(ref);
|
||||
for (j = i + 1; j < rev.length; ++j) {
|
||||
if (!Character.isDigit(rev[j]))
|
||||
break;
|
||||
}
|
||||
String parentnum = new String(rev, i+1, j-i-1);
|
||||
String parentnum = new String(rev, i + 1, j - i - 1);
|
||||
int pnum;
|
||||
try {
|
||||
pnum = Integer.parseInt(parentnum);
|
||||
|
@ -812,123 +810,83 @@ public ObjectId resolve(final String revstr) throws IOException {
|
|||
revstr);
|
||||
}
|
||||
if (pnum != 0) {
|
||||
final ObjectId parents[] = ((Commit) ref)
|
||||
.getParentIds();
|
||||
if (pnum > parents.length)
|
||||
refId = null;
|
||||
RevCommit commit = (RevCommit) ref;
|
||||
if (pnum > commit.getParentCount())
|
||||
ref = null;
|
||||
else
|
||||
refId = parents[pnum - 1];
|
||||
ref = commit.getParent(pnum - 1);
|
||||
}
|
||||
i = j - 1;
|
||||
break;
|
||||
case '{':
|
||||
int k;
|
||||
String item = null;
|
||||
for (k=i+2; k<rev.length; ++k) {
|
||||
for (k = i + 2; k < rev.length; ++k) {
|
||||
if (rev[k] == '}') {
|
||||
item = new String(rev, i+2, k-i-2);
|
||||
item = new String(rev, i + 2, k - i - 2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
i = k;
|
||||
if (item != null)
|
||||
if (item.equals("tree")) {
|
||||
ref = mapObject(refId, null);
|
||||
while (ref instanceof Tag) {
|
||||
Tag t = (Tag)ref;
|
||||
refId = t.getObjId();
|
||||
ref = mapObject(refId, null);
|
||||
}
|
||||
if (ref instanceof Treeish)
|
||||
refId = ((Treeish)ref).getTreeId();
|
||||
else
|
||||
throw new IncorrectObjectTypeException(refId, Constants.TYPE_TREE);
|
||||
}
|
||||
else if (item.equals("commit")) {
|
||||
ref = mapObject(refId, null);
|
||||
while (ref instanceof Tag) {
|
||||
Tag t = (Tag)ref;
|
||||
refId = t.getObjId();
|
||||
ref = mapObject(refId, null);
|
||||
}
|
||||
if (!(ref instanceof Commit))
|
||||
throw new IncorrectObjectTypeException(refId, Constants.TYPE_COMMIT);
|
||||
}
|
||||
else if (item.equals("blob")) {
|
||||
ref = mapObject(refId, null);
|
||||
while (ref instanceof Tag) {
|
||||
Tag t = (Tag)ref;
|
||||
refId = t.getObjId();
|
||||
ref = mapObject(refId, null);
|
||||
}
|
||||
if (!(ref instanceof byte[]))
|
||||
throw new IncorrectObjectTypeException(refId, Constants.TYPE_BLOB);
|
||||
}
|
||||
else if (item.equals("")) {
|
||||
ref = mapObject(refId, null);
|
||||
while (ref instanceof Tag) {
|
||||
Tag t = (Tag)ref;
|
||||
refId = t.getObjId();
|
||||
ref = mapObject(refId, null);
|
||||
}
|
||||
}
|
||||
else
|
||||
ref = rw.parseTree(ref);
|
||||
} else if (item.equals("commit")) {
|
||||
ref = rw.parseCommit(ref);
|
||||
} else if (item.equals("blob")) {
|
||||
ref = rw.peel(ref);
|
||||
if (!(ref instanceof RevBlob))
|
||||
throw new IncorrectObjectTypeException(ref,
|
||||
Constants.TYPE_BLOB);
|
||||
} else if (item.equals("")) {
|
||||
ref = rw.peel(ref);
|
||||
} else
|
||||
throw new RevisionSyntaxException(revstr);
|
||||
else
|
||||
throw new RevisionSyntaxException(revstr);
|
||||
break;
|
||||
default:
|
||||
ref = mapObject(refId, null);
|
||||
if (ref instanceof Commit) {
|
||||
final ObjectId parents[] = ((Commit) ref)
|
||||
.getParentIds();
|
||||
if (parents.length == 0)
|
||||
refId = null;
|
||||
ref = rw.parseAny(ref);
|
||||
if (ref instanceof RevCommit) {
|
||||
RevCommit commit = ((RevCommit) ref);
|
||||
if (commit.getParentCount() == 0)
|
||||
ref = null;
|
||||
else
|
||||
refId = parents[0];
|
||||
ref = commit.getParent(0);
|
||||
} else
|
||||
throw new IncorrectObjectTypeException(refId, Constants.TYPE_COMMIT);
|
||||
throw new IncorrectObjectTypeException(ref,
|
||||
Constants.TYPE_COMMIT);
|
||||
|
||||
}
|
||||
} else {
|
||||
ref = mapObject(refId, null);
|
||||
while (ref instanceof Tag) {
|
||||
Tag tag = (Tag)ref;
|
||||
refId = tag.getObjId();
|
||||
ref = mapObject(refId, null);
|
||||
}
|
||||
if (ref instanceof Commit) {
|
||||
final ObjectId parents[] = ((Commit) ref)
|
||||
.getParentIds();
|
||||
if (parents.length == 0)
|
||||
refId = null;
|
||||
ref = rw.peel(ref);
|
||||
if (ref instanceof RevCommit) {
|
||||
RevCommit commit = ((RevCommit) ref);
|
||||
if (commit.getParentCount() == 0)
|
||||
ref = null;
|
||||
else
|
||||
refId = parents[0];
|
||||
ref = commit.getParent(0);
|
||||
} else
|
||||
throw new IncorrectObjectTypeException(refId, Constants.TYPE_COMMIT);
|
||||
throw new IncorrectObjectTypeException(ref,
|
||||
Constants.TYPE_COMMIT);
|
||||
}
|
||||
break;
|
||||
case '~':
|
||||
if (ref == null) {
|
||||
String refstr = new String(rev,0,i);
|
||||
refId = resolveSimple(refstr);
|
||||
if (refId == null)
|
||||
ref = parseSimple(rw, new String(rev, 0, i));
|
||||
if (ref == null)
|
||||
return null;
|
||||
ref = mapObject(refId, null);
|
||||
}
|
||||
while (ref instanceof Tag) {
|
||||
Tag tag = (Tag)ref;
|
||||
refId = tag.getObjId();
|
||||
ref = mapObject(refId, null);
|
||||
}
|
||||
if (!(ref instanceof Commit))
|
||||
throw new IncorrectObjectTypeException(refId, Constants.TYPE_COMMIT);
|
||||
ref = rw.peel(ref);
|
||||
if (!(ref instanceof RevCommit))
|
||||
throw new IncorrectObjectTypeException(ref,
|
||||
Constants.TYPE_COMMIT);
|
||||
int l;
|
||||
for (l = i + 1; l < rev.length; ++l) {
|
||||
if (!Character.isDigit(rev[l]))
|
||||
break;
|
||||
}
|
||||
String distnum = new String(rev, i+1, l-i-1);
|
||||
String distnum = new String(rev, i + 1, l - i - 1);
|
||||
int dist;
|
||||
try {
|
||||
dist = Integer.parseInt(distnum);
|
||||
|
@ -937,13 +895,14 @@ else if (item.equals("")) {
|
|||
JGitText.get().invalidAncestryLength, revstr);
|
||||
}
|
||||
while (dist > 0) {
|
||||
final ObjectId[] parents = ((Commit) ref).getParentIds();
|
||||
if (parents.length == 0) {
|
||||
refId = null;
|
||||
RevCommit commit = (RevCommit) ref;
|
||||
if (commit.getParentCount() == 0) {
|
||||
ref = null;
|
||||
break;
|
||||
}
|
||||
refId = parents[0];
|
||||
ref = mapCommit(refId);
|
||||
commit = commit.getParent(0);
|
||||
rw.parseHeaders(commit);
|
||||
ref = commit;
|
||||
--dist;
|
||||
}
|
||||
i = l - 1;
|
||||
|
@ -951,30 +910,35 @@ else if (item.equals("")) {
|
|||
case '@':
|
||||
int m;
|
||||
String time = null;
|
||||
for (m=i+2; m<rev.length; ++m) {
|
||||
for (m = i + 2; m < rev.length; ++m) {
|
||||
if (rev[m] == '}') {
|
||||
time = new String(rev, i+2, m-i-2);
|
||||
time = new String(rev, i + 2, m - i - 2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (time != null)
|
||||
throw new RevisionSyntaxException(JGitText.get().reflogsNotYetSupportedByRevisionParser, revstr);
|
||||
throw new RevisionSyntaxException(
|
||||
JGitText.get().reflogsNotYetSupportedByRevisionParser,
|
||||
revstr);
|
||||
i = m - 1;
|
||||
break;
|
||||
default:
|
||||
if (refId != null)
|
||||
if (ref != null)
|
||||
throw new RevisionSyntaxException(revstr);
|
||||
}
|
||||
}
|
||||
if (refId == null)
|
||||
refId = resolveSimple(revstr);
|
||||
return refId;
|
||||
return ref != null ? ref.copy() : resolveSimple(revstr);
|
||||
}
|
||||
|
||||
private RevObject parseSimple(RevWalk rw, String revstr) throws IOException {
|
||||
ObjectId id = resolveSimple(revstr);
|
||||
return id != null ? rw.parseAny(id) : null;
|
||||
}
|
||||
|
||||
private ObjectId resolveSimple(final String revstr) throws IOException {
|
||||
if (ObjectId.isId(revstr))
|
||||
return ObjectId.fromString(revstr);
|
||||
final Ref r = refs.getRef(revstr);
|
||||
final Ref r = getRefDatabase().getRef(revstr);
|
||||
return r != null ? r.getObjectId() : null;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue