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 org.eclipse.jgit.lib.ObjectId} it currently
51 * has.
52 * <p>
53 * A ref in Git is (more or less) a variable that holds a single object
54 * identifier. The object identifier can be any valid Git object (blob, tree,
55 * commit, annotated tag, ...).
56 * <p>
57 * The ref name has the attributes of the ref that was asked for as well as the
58 * ref it was resolved to for symbolic refs plus the object id it points to and
59 * (for tags) the peeled target object id, i.e. the tag resolved recursively
60 * until a non-tag object is referenced.
61 */
62 public interface Ref {
63 /** Location where a {@link Ref} is stored. */
64 enum Storage {
65 /**
66 * The ref does not exist yet, updating it may create it.
67 * <p>
68 * Creation is likely to choose {@link #LOOSE} storage.
69 */
70 NEW(true, false),
71
72 /**
73 * The ref is stored in a file by itself.
74 * <p>
75 * Updating this ref affects only this ref.
76 */
77 LOOSE(true, false),
78
79 /**
80 * The ref is stored in the <code>packed-refs</code> file, with others.
81 * <p>
82 * Updating this ref requires rewriting the file, with perhaps many
83 * other refs being included at the same time.
84 */
85 PACKED(false, true),
86
87 /**
88 * The ref is both {@link #LOOSE} and {@link #PACKED}.
89 * <p>
90 * Updating this ref requires only updating the loose file, but deletion
91 * requires updating both the loose file and the packed refs file.
92 */
93 LOOSE_PACKED(true, true),
94
95 /**
96 * The ref came from a network advertisement and storage is unknown.
97 * <p>
98 * This ref cannot be updated without Git-aware support on the remote
99 * side, as Git-aware code consolidate the remote refs and reported them
100 * to this process.
101 */
102 NETWORK(false, false);
103
104 private final boolean loose;
105
106 private final boolean packed;
107
108 private Storage(boolean l, boolean p) {
109 loose = l;
110 packed = p;
111 }
112
113 /**
114 * @return true if this storage has a loose file.
115 */
116 public boolean isLoose() {
117 return loose;
118 }
119
120 /**
121 * @return true if this storage is inside the packed file.
122 */
123 public boolean isPacked() {
124 return packed;
125 }
126 }
127
128 /**
129 * Update index value when a reference doesn't have one
130 *
131 * @since 5.4
132 */
133 long UNDEFINED_UPDATE_INDEX = -1L;
134
135 /**
136 * What this ref is called within the repository.
137 *
138 * @return name of this ref.
139 */
140 @NonNull
141 String getName();
142
143 /**
144 * Test if this reference is a symbolic reference.
145 * <p>
146 * A symbolic reference does not have its own
147 * {@link org.eclipse.jgit.lib.ObjectId} value, but instead points to
148 * another {@code Ref} in the same database and always uses that other
149 * reference's value as its own.
150 *
151 * @return true if this is a symbolic reference; false if this reference
152 * contains its own ObjectId.
153 */
154 boolean isSymbolic();
155
156 /**
157 * Traverse target references until {@link #isSymbolic()} is false.
158 * <p>
159 * If {@link #isSymbolic()} is false, returns {@code this}.
160 * <p>
161 * If {@link #isSymbolic()} is true, this method recursively traverses
162 * {@link #getTarget()} until {@link #isSymbolic()} returns false.
163 * <p>
164 * This method is effectively
165 *
166 * <pre>
167 * return isSymbolic() ? getTarget().getLeaf() : this;
168 * </pre>
169 *
170 * @return the reference that actually stores the ObjectId value.
171 */
172 @NonNull
173 Ref getLeaf();
174
175 /**
176 * Get the reference this reference points to, or {@code this}.
177 * <p>
178 * If {@link #isSymbolic()} is true this method returns the reference it
179 * directly names, which might not be the leaf reference, but could be
180 * another symbolic reference.
181 * <p>
182 * If this is a leaf level reference that contains its own ObjectId,this
183 * method returns {@code this}.
184 *
185 * @return the target reference, or {@code this}.
186 */
187 @NonNull
188 Ref getTarget();
189
190 /**
191 * Cached value of this ref.
192 *
193 * @return the value of this ref at the last time we read it. May be
194 * {@code null} to indicate a ref that does not exist yet or a
195 * symbolic ref pointing to an unborn branch.
196 */
197 @Nullable
198 ObjectId getObjectId();
199
200 /**
201 * Cached value of <code>ref^{}</code> (the ref peeled to commit).
202 *
203 * @return if this ref is an annotated tag the id of the commit (or tree or
204 * blob) that the annotated tag refers to; {@code null} if this ref
205 * does not refer to an annotated tag.
206 */
207 @Nullable
208 ObjectId getPeeledObjectId();
209
210 /**
211 * Whether the Ref represents a peeled tag.
212 *
213 * @return whether the Ref represents a peeled tag.
214 */
215 boolean isPeeled();
216
217 /**
218 * How was this ref obtained?
219 * <p>
220 * The current storage model of a Ref may influence how the ref must be
221 * updated or deleted from the repository.
222 *
223 * @return type of ref.
224 */
225 @NonNull
226 Storage getStorage();
227
228 /**
229 * Indicator of the relative order between updates of a specific reference
230 * name. A number that increases when a reference is updated.
231 * <p>
232 * With symbolic references, the update index refers to updates of the
233 * symbolic reference itself. For example, if HEAD points to
234 * refs/heads/master, then the update index for exactRef("HEAD") will only
235 * increase when HEAD changes to point to another ref, regardless of how
236 * many times refs/heads/master is updated.
237 * <p>
238 * Should not be used unless the {@code RefDatabase} that instantiated the
239 * ref supports versioning (see {@link RefDatabase#hasVersioning()})
240 *
241 * @return the update index (i.e. version) of this reference.
242 * @throws UnsupportedOperationException
243 * if the creator of the instance (e.g. {@link RefDatabase})
244 * doesn't support versioning and doesn't override this method
245 * @since 5.3
246 */
247 default long getUpdateIndex() {
248 throw new UnsupportedOperationException();
249 }
250 }