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