Line data Source code
1 : // Copyright (C) 2016 The Android Open Source Project 2 : // 3 : // Licensed under the Apache License, Version 2.0 (the "License"); 4 : // you may not use this file except in compliance with the License. 5 : // You may obtain a copy of the License at 6 : // 7 : // http://www.apache.org/licenses/LICENSE-2.0 8 : // 9 : // Unless required by applicable law or agreed to in writing, software 10 : // distributed under the License is distributed on an "AS IS" BASIS, 11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : // See the License for the specific language governing permissions and 13 : // limitations under the License. 14 : 15 : package com.google.gerrit.server.project; 16 : 17 : import static org.eclipse.jgit.lib.Constants.R_REFS; 18 : import static org.eclipse.jgit.lib.Constants.R_TAGS; 19 : 20 : import com.google.common.collect.Iterables; 21 : import com.google.gerrit.entities.RefNames; 22 : import com.google.gerrit.extensions.restapi.BadRequestException; 23 : import com.google.gerrit.extensions.restapi.UnprocessableEntityException; 24 : import java.io.IOException; 25 : import java.util.Collections; 26 : import org.eclipse.jgit.errors.IncorrectObjectTypeException; 27 : import org.eclipse.jgit.errors.MissingObjectException; 28 : import org.eclipse.jgit.errors.RevisionSyntaxException; 29 : import org.eclipse.jgit.lib.Constants; 30 : import org.eclipse.jgit.lib.ObjectId; 31 : import org.eclipse.jgit.lib.Ref; 32 : import org.eclipse.jgit.lib.RefDatabase; 33 : import org.eclipse.jgit.lib.Repository; 34 : import org.eclipse.jgit.revwalk.ObjectWalk; 35 : import org.eclipse.jgit.revwalk.RevWalk; 36 : 37 : public class RefUtil { 38 : private RefUtil() {} 39 : 40 : public static ObjectId parseBaseRevision(Repository repo, String baseRevision) 41 : throws UnprocessableEntityException, IOException { 42 : try { 43 32 : ObjectId revid = repo.resolve(baseRevision); 44 32 : if (revid == null) { 45 1 : throw new UnprocessableEntityException( 46 1 : String.format("base revision \"%s\" not found", baseRevision)); 47 : } 48 32 : return revid; 49 2 : } catch (RevisionSyntaxException e) { 50 2 : throw new UnprocessableEntityException( 51 2 : String.format("base revision \"%s\" is invalid", baseRevision), e); 52 : } 53 : } 54 : 55 : public static RevWalk verifyConnected(Repository repo, ObjectId baseRevision) 56 : throws BadRequestException, UnprocessableEntityException, IOException { 57 : try { 58 32 : ObjectWalk rw = new ObjectWalk(repo); 59 32 : rw.markStart(rw.parseCommit(baseRevision)); 60 32 : RefDatabase refDb = repo.getRefDatabase(); 61 32 : Iterable<Ref> refs = 62 32 : Iterables.concat( 63 32 : refDb.getRefsByPrefix(Constants.R_HEADS), refDb.getRefsByPrefix(Constants.R_TAGS)); 64 32 : Ref rc = refDb.exactRef(RefNames.REFS_CONFIG); 65 32 : if (rc != null) { 66 32 : refs = Iterables.concat(refs, Collections.singleton(rc)); 67 : } 68 32 : for (Ref r : refs) { 69 : try { 70 32 : rw.markUninteresting(rw.parseAny(r.getObjectId())); 71 0 : } catch (MissingObjectException err) { 72 0 : continue; 73 32 : } 74 32 : } 75 32 : rw.checkConnectivity(); 76 32 : return rw; 77 2 : } catch (IncorrectObjectTypeException e) { 78 2 : throw new BadRequestException( 79 2 : String.format("base revision \"%s\" is not a commit", baseRevision.name()), e); 80 2 : } catch (MissingObjectException e) { 81 2 : throw new UnprocessableEntityException( 82 2 : String.format("base revision \"%s\" not found", baseRevision.name()), e); 83 : } 84 : } 85 : 86 : public static String getRefPrefix(String refName) { 87 1 : int i = refName.lastIndexOf('/'); 88 1 : if (i > Constants.R_HEADS.length() - 1) { 89 1 : return refName.substring(0, i); 90 : } 91 0 : return Constants.R_HEADS; 92 : } 93 : 94 : /** Fully qualifies a tag name to refs/tags/TAG-NAME */ 95 : public static String normalizeTagRef(String tag) throws BadRequestException { 96 7 : String result = tag; 97 7 : while (result.startsWith("/")) { 98 1 : result = result.substring(1); 99 : } 100 7 : if (result.startsWith(R_REFS) && !result.startsWith(R_TAGS)) { 101 1 : throw new BadRequestException("invalid tag name \"" + result + "\""); 102 : } 103 7 : if (!result.startsWith(R_TAGS)) { 104 6 : result = R_TAGS + result; 105 : } 106 7 : if (!Repository.isValidRefName(result)) { 107 1 : throw new BadRequestException("invalid tag name \"" + result + "\""); 108 : } 109 7 : return result; 110 : } 111 : }