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 public static 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 * What this ref is called within the repository.
130 *
131 * @return name of this ref.
132 */
133 @NonNull
134 public String getName();
135
136 /**
137 * Test if this reference is a symbolic reference.
138 * <p>
139 * A symbolic reference does not have its own
140 * {@link org.eclipse.jgit.lib.ObjectId} value, but instead points to
141 * another {@code Ref} in the same database and always uses that other
142 * reference's value as its own.
143 *
144 * @return true if this is a symbolic reference; false if this reference
145 * contains its own ObjectId.
146 */
147 public abstract boolean isSymbolic();
148
149 /**
150 * Traverse target references until {@link #isSymbolic()} is false.
151 * <p>
152 * If {@link #isSymbolic()} is false, returns {@code this}.
153 * <p>
154 * If {@link #isSymbolic()} is true, this method recursively traverses
155 * {@link #getTarget()} until {@link #isSymbolic()} returns false.
156 * <p>
157 * This method is effectively
158 *
159 * <pre>
160 * return isSymbolic() ? getTarget().getLeaf() : this;
161 * </pre>
162 *
163 * @return the reference that actually stores the ObjectId value.
164 */
165 @NonNull
166 public abstract Ref getLeaf();
167
168 /**
169 * Get the reference this reference points to, or {@code this}.
170 * <p>
171 * If {@link #isSymbolic()} is true this method returns the reference it
172 * directly names, which might not be the leaf reference, but could be
173 * another symbolic reference.
174 * <p>
175 * If this is a leaf level reference that contains its own ObjectId,this
176 * method returns {@code this}.
177 *
178 * @return the target reference, or {@code this}.
179 */
180 @NonNull
181 public abstract Ref getTarget();
182
183 /**
184 * Cached value of this ref.
185 *
186 * @return the value of this ref at the last time we read it. May be
187 * {@code null} to indicate a ref that does not exist yet or a
188 * symbolic ref pointing to an unborn branch.
189 */
190 @Nullable
191 public abstract ObjectId getObjectId();
192
193 /**
194 * Cached value of <code>ref^{}</code> (the ref peeled to commit).
195 *
196 * @return if this ref is an annotated tag the id of the commit (or tree or
197 * blob) that the annotated tag refers to; {@code null} if this ref
198 * does not refer to an annotated tag.
199 */
200 @Nullable
201 public abstract ObjectId getPeeledObjectId();
202
203 /**
204 * Whether the Ref represents a peeled tag.
205 *
206 * @return whether the Ref represents a peeled tag.
207 */
208 public abstract boolean isPeeled();
209
210 /**
211 * How was this ref obtained?
212 * <p>
213 * The current storage model of a Ref may influence how the ref must be
214 * updated or deleted from the repository.
215 *
216 * @return type of ref.
217 */
218 @NonNull
219 public abstract Storage getStorage();
220 }