View Javadoc
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 }