1 /*
2 * Copyright (C) 2006-2008, Shawn O. Pearce <spearce@spearce.org> and others
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Distribution License v. 1.0 which is available at
6 * https://www.eclipse.org/org/documents/edl-v10.php.
7 *
8 * SPDX-License-Identifier: BSD-3-Clause
9 */
10
11 package org.eclipse.jgit.lib;
12
13 import org.eclipse.jgit.annotations.NonNull;
14 import org.eclipse.jgit.annotations.Nullable;
15
16 /**
17 * Pairing of a name and the {@link org.eclipse.jgit.lib.ObjectId} it currently
18 * has.
19 * <p>
20 * A ref in Git is (more or less) a variable that holds a single object
21 * identifier. The object identifier can be any valid Git object (blob, tree,
22 * commit, annotated tag, ...).
23 * <p>
24 * The ref name has the attributes of the ref that was asked for as well as the
25 * ref it was resolved to for symbolic refs plus the object id it points to and
26 * (for tags) the peeled target object id, i.e. the tag resolved recursively
27 * until a non-tag object is referenced.
28 */
29 public interface Ref {
30 /** Location where a {@link Ref} is stored. */
31 enum Storage {
32 /**
33 * The ref does not exist yet, updating it may create it.
34 * <p>
35 * Creation is likely to choose {@link #LOOSE} storage.
36 */
37 NEW(true, false),
38
39 /**
40 * The ref is stored in a file by itself.
41 * <p>
42 * Updating this ref affects only this ref.
43 */
44 LOOSE(true, false),
45
46 /**
47 * The ref is stored in the <code>packed-refs</code> file, with others.
48 * <p>
49 * Updating this ref requires rewriting the file, with perhaps many
50 * other refs being included at the same time.
51 */
52 PACKED(false, true),
53
54 /**
55 * The ref is both {@link #LOOSE} and {@link #PACKED}.
56 * <p>
57 * Updating this ref requires only updating the loose file, but deletion
58 * requires updating both the loose file and the packed refs file.
59 */
60 LOOSE_PACKED(true, true),
61
62 /**
63 * The ref came from a network advertisement and storage is unknown.
64 * <p>
65 * This ref cannot be updated without Git-aware support on the remote
66 * side, as Git-aware code consolidate the remote refs and reported them
67 * to this process.
68 */
69 NETWORK(false, false);
70
71 private final boolean loose;
72
73 private final boolean packed;
74
75 private Storage(boolean l, boolean p) {
76 loose = l;
77 packed = p;
78 }
79
80 /**
81 * @return true if this storage has a loose file.
82 */
83 public boolean isLoose() {
84 return loose;
85 }
86
87 /**
88 * @return true if this storage is inside the packed file.
89 */
90 public boolean isPacked() {
91 return packed;
92 }
93 }
94
95 /**
96 * Update index value when a reference doesn't have one
97 *
98 * @since 5.4
99 */
100 long UNDEFINED_UPDATE_INDEX = -1L;
101
102 /**
103 * What this ref is called within the repository.
104 *
105 * @return name of this ref.
106 */
107 @NonNull
108 String getName();
109
110 /**
111 * Test if this reference is a symbolic reference.
112 * <p>
113 * A symbolic reference does not have its own
114 * {@link org.eclipse.jgit.lib.ObjectId} value, but instead points to
115 * another {@code Ref} in the same database and always uses that other
116 * reference's value as its own.
117 *
118 * @return true if this is a symbolic reference; false if this reference
119 * contains its own ObjectId.
120 */
121 boolean isSymbolic();
122
123 /**
124 * Traverse target references until {@link #isSymbolic()} is false.
125 * <p>
126 * If {@link #isSymbolic()} is false, returns {@code this}.
127 * <p>
128 * If {@link #isSymbolic()} is true, this method recursively traverses
129 * {@link #getTarget()} until {@link #isSymbolic()} returns false.
130 * <p>
131 * This method is effectively
132 *
133 * <pre>
134 * return isSymbolic() ? getTarget().getLeaf() : this;
135 * </pre>
136 *
137 * @return the reference that actually stores the ObjectId value.
138 */
139 @NonNull
140 Ref getLeaf();
141
142 /**
143 * Get the reference this reference points to, or {@code this}.
144 * <p>
145 * If {@link #isSymbolic()} is true this method returns the reference it
146 * directly names, which might not be the leaf reference, but could be
147 * another symbolic reference.
148 * <p>
149 * If this is a leaf level reference that contains its own ObjectId,this
150 * method returns {@code this}.
151 *
152 * @return the target reference, or {@code this}.
153 */
154 @NonNull
155 Ref getTarget();
156
157 /**
158 * Cached value of this ref.
159 *
160 * @return the value of this ref at the last time we read it. May be
161 * {@code null} to indicate a ref that does not exist yet or a
162 * symbolic ref pointing to an unborn branch.
163 */
164 @Nullable
165 ObjectId getObjectId();
166
167 /**
168 * Cached value of <code>ref^{}</code> (the ref peeled to commit).
169 *
170 * @return if this ref is an annotated tag the id of the commit (or tree or
171 * blob) that the annotated tag refers to; {@code null} if this ref
172 * does not refer to an annotated tag.
173 */
174 @Nullable
175 ObjectId getPeeledObjectId();
176
177 /**
178 * Whether the Ref represents a peeled tag.
179 *
180 * @return whether the Ref represents a peeled tag.
181 */
182 boolean isPeeled();
183
184 /**
185 * How was this ref obtained?
186 * <p>
187 * The current storage model of a Ref may influence how the ref must be
188 * updated or deleted from the repository.
189 *
190 * @return type of ref.
191 */
192 @NonNull
193 Storage getStorage();
194
195 /**
196 * Indicator of the relative order between updates of a specific reference
197 * name. A number that increases when a reference is updated.
198 * <p>
199 * With symbolic references, the update index refers to updates of the
200 * symbolic reference itself. For example, if HEAD points to
201 * refs/heads/master, then the update index for exactRef("HEAD") will only
202 * increase when HEAD changes to point to another ref, regardless of how
203 * many times refs/heads/master is updated.
204 * <p>
205 * Should not be used unless the {@code RefDatabase} that instantiated the
206 * ref supports versioning (see {@link RefDatabase#hasVersioning()})
207 *
208 * @return the update index (i.e. version) of this reference.
209 * @throws UnsupportedOperationException
210 * if the creator of the instance (e.g. {@link RefDatabase})
211 * doesn't support versioning and doesn't override this method
212 * @since 5.3
213 */
214 default long getUpdateIndex() {
215 throw new UnsupportedOperationException();
216 }
217 }