1 /*
2 * Copyright (C) 2006-2008, Shawn O. Pearce <spearce@spearce.org>
3 * and other copyright owners as documented in the project's IP log.
4 *
5 * This program and the accompanying materials are made available
6 * under the terms of the Eclipse Distribution License v1.0 which
7 * accompanies this distribution, is reproduced below, and is
8 * available at http://www.eclipse.org/org/documents/edl-v10.php
9 *
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 *
16 * - Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials provided
22 * with the distribution.
23 *
24 * - Neither the name of the Eclipse Foundation, Inc. nor the
25 * names of its contributors may be used to endorse or promote
26 * products derived from this software without specific prior
27 * written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
30 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
31 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
34 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 */
43
44 package org.eclipse.jgit.lib;
45
46 import org.eclipse.jgit.annotations.NonNull;
47 import org.eclipse.jgit.annotations.Nullable;
48
49 /**
50 * Pairing of a name and the {@link ObjectId} it currently has.
51 * <p>
52 * A ref in Git is (more or less) a variable that holds a single object
53 * identifier. The object identifier can be any valid Git object (blob, tree,
54 * commit, annotated tag, ...).
55 * <p>
56 * The ref name has the attributes of the ref that was asked for as well as the
57 * ref it was resolved to for symbolic refs plus the object id it points to and
58 * (for tags) the peeled target object id, i.e. the tag resolved recursively
59 * until a non-tag object is referenced.
60 */
61 public interface Ref {
62 /** Location where a {@link Ref} is stored. */
63 public static enum Storage {
64 /**
65 * The ref does not exist yet, updating it may create it.
66 * <p>
67 * Creation is likely to choose {@link #LOOSE} storage.
68 */
69 NEW(true, false),
70
71 /**
72 * The ref is stored in a file by itself.
73 * <p>
74 * Updating this ref affects only this ref.
75 */
76 LOOSE(true, false),
77
78 /**
79 * The ref is stored in the <code>packed-refs</code> file, with others.
80 * <p>
81 * Updating this ref requires rewriting the file, with perhaps many
82 * other refs being included at the same time.
83 */
84 PACKED(false, true),
85
86 /**
87 * The ref is both {@link #LOOSE} and {@link #PACKED}.
88 * <p>
89 * Updating this ref requires only updating the loose file, but deletion
90 * requires updating both the loose file and the packed refs file.
91 */
92 LOOSE_PACKED(true, true),
93
94 /**
95 * The ref came from a network advertisement and storage is unknown.
96 * <p>
97 * This ref cannot be updated without Git-aware support on the remote
98 * side, as Git-aware code consolidate the remote refs and reported them
99 * to this process.
100 */
101 NETWORK(false, false);
102
103 private final boolean loose;
104
105 private final boolean packed;
106
107 private Storage(final boolean l, final boolean p) {
108 loose = l;
109 packed = p;
110 }
111
112 /**
113 * @return true if this storage has a loose file.
114 */
115 public boolean isLoose() {
116 return loose;
117 }
118
119 /**
120 * @return true if this storage is inside the packed file.
121 */
122 public boolean isPacked() {
123 return packed;
124 }
125 }
126
127 /**
128 * What this ref is called within the repository.
129 *
130 * @return name of this ref.
131 */
132 @NonNull
133 public String getName();
134
135 /**
136 * Test if this reference is a symbolic reference.
137 * <p>
138 * A symbolic reference does not have its own {@link ObjectId} value, but
139 * instead points to another {@code Ref} in the same database and always
140 * uses that other reference's value as its own.
141 *
142 * @return true if this is a symbolic reference; false if this reference
143 * contains its own ObjectId.
144 */
145 public abstract boolean isSymbolic();
146
147 /**
148 * Traverse target references until {@link #isSymbolic()} is false.
149 * <p>
150 * If {@link #isSymbolic()} is false, returns {@code this}.
151 * <p>
152 * If {@link #isSymbolic()} is true, this method recursively traverses
153 * {@link #getTarget()} until {@link #isSymbolic()} returns false.
154 * <p>
155 * This method is effectively
156 *
157 * <pre>
158 * return isSymbolic() ? getTarget().getLeaf() : this;
159 * </pre>
160 *
161 * @return the reference that actually stores the ObjectId value.
162 */
163 @NonNull
164 public abstract Ref getLeaf();
165
166 /**
167 * Get the reference this reference points to, or {@code this}.
168 * <p>
169 * If {@link #isSymbolic()} is true this method returns the reference it
170 * directly names, which might not be the leaf reference, but could be
171 * another symbolic reference.
172 * <p>
173 * If this is a leaf level reference that contains its own ObjectId,this
174 * method returns {@code this}.
175 *
176 * @return the target reference, or {@code this}.
177 */
178 @NonNull
179 public abstract Ref getTarget();
180
181 /**
182 * Cached value of this ref.
183 *
184 * @return the value of this ref at the last time we read it. May be
185 * {@code null} to indicate a ref that does not exist yet or a
186 * symbolic ref pointing to an unborn branch.
187 */
188 @Nullable
189 public abstract ObjectId getObjectId();
190
191 /**
192 * Cached value of <code>ref^{}</code> (the ref peeled to commit).
193 *
194 * @return if this ref is an annotated tag the id of the commit (or tree or
195 * blob) that the annotated tag refers to; {@code null} if this ref
196 * does not refer to an annotated tag.
197 */
198 @Nullable
199 public abstract ObjectId getPeeledObjectId();
200
201 /**
202 * @return whether the Ref represents a peeled tag
203 */
204 public abstract boolean isPeeled();
205
206 /**
207 * How was this ref obtained?
208 * <p>
209 * The current storage model of a Ref may influence how the ref must be
210 * updated or deleted from the repository.
211 *
212 * @return type of ref.
213 */
214 @NonNull
215 public abstract Storage getStorage();
216 }