View Javadoc
1   /*
2    * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
3    * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
4    * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
5    * and other copyright owners as documented in the project's IP log.
6    *
7    * This program and the accompanying materials are made available
8    * under the terms of the Eclipse Distribution License v1.0 which
9    * accompanies this distribution, is reproduced below, and is
10   * available at http://www.eclipse.org/org/documents/edl-v10.php
11   *
12   * All rights reserved.
13   *
14   * Redistribution and use in source and binary forms, with or
15   * without modification, are permitted provided that the following
16   * conditions are met:
17   *
18   * - Redistributions of source code must retain the above copyright
19   *   notice, this list of conditions and the following disclaimer.
20   *
21   * - Redistributions in binary form must reproduce the above
22   *   copyright notice, this list of conditions and the following
23   *   disclaimer in the documentation and/or other materials provided
24   *   with the distribution.
25   *
26   * - Neither the name of the Eclipse Foundation, Inc. nor the
27   *   names of its contributors may be used to endorse or promote
28   *   products derived from this software without specific prior
29   *   written permission.
30   *
31   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
32   * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
33   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
34   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
36   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
37   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
38   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
39   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
40   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
43   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44   */
45  
46  package org.eclipse.jgit.transport;
47  
48  import org.eclipse.jgit.lib.AnyObjectId;
49  import org.eclipse.jgit.lib.ObjectId;
50  import org.eclipse.jgit.lib.RefUpdate;
51  
52  /** Update of a locally stored tracking branch. */
53  public class TrackingRefUpdate {
54  	private final String remoteName;
55  	final String localName;
56  	boolean forceUpdate;
57  	ObjectId oldObjectId;
58  	ObjectId newObjectId;
59  
60  	private RefUpdate.Result result;
61  	private ReceiveCommand cmd;
62  
63  	TrackingRefUpdate(
64  			boolean canForceUpdate,
65  			String remoteName,
66  			String localName,
67  			AnyObjectId oldValue,
68  			AnyObjectId newValue) {
69  		this.remoteName = remoteName;
70  		this.localName = localName;
71  		this.forceUpdate = canForceUpdate;
72  		this.oldObjectId = oldValue.copy();
73  		this.newObjectId = newValue.copy();
74  	}
75  
76  	/**
77  	 * Get the name of the remote ref.
78  	 * <p>
79  	 * Usually this is of the form "refs/heads/master".
80  	 *
81  	 * @return the name used within the remote repository.
82  	 */
83  	public String getRemoteName() {
84  		return remoteName;
85  	}
86  
87  	/**
88  	 * Get the name of the local tracking ref.
89  	 * <p>
90  	 * Usually this is of the form "refs/remotes/origin/master".
91  	 *
92  	 * @return the name used within this local repository.
93  	 */
94  	public String getLocalName() {
95  		return localName;
96  	}
97  
98  	/**
99  	 * Get the new value the ref will be (or was) updated to.
100 	 *
101 	 * @return new value. Null if the caller has not configured it.
102 	 */
103 	public ObjectId getNewObjectId() {
104 		return newObjectId;
105 	}
106 
107 	/**
108 	 * The old value of the ref, prior to the update being attempted.
109 	 * <p>
110 	 * This value may differ before and after the update method. Initially it is
111 	 * populated with the value of the ref before the lock is taken, but the old
112 	 * value may change if someone else modified the ref between the time we
113 	 * last read it and when the ref was locked for update.
114 	 *
115 	 * @return the value of the ref prior to the update being attempted.
116 	 */
117 	public ObjectId getOldObjectId() {
118 		return oldObjectId;
119 	}
120 
121 	/**
122 	 * Get the status of this update.
123 	 *
124 	 * @return the status of the update.
125 	 */
126 	public RefUpdate.Result getResult() {
127 		return result;
128 	}
129 
130 	void setResult(RefUpdate.Result result) {
131 		this.result = result;
132 	}
133 
134 	/**
135 	 * @return this update wrapped by a ReceiveCommand.
136 	 * @since 3.4
137 	 */
138 	public ReceiveCommand asReceiveCommand() {
139 		if (cmd == null)
140 			cmd = new Command();
141 		return cmd;
142 	}
143 
144 	final class Command extends ReceiveCommand {
145 		Command() {
146 			super(oldObjectId, newObjectId, localName);
147 		}
148 
149 		boolean canForceUpdate() {
150 			return forceUpdate;
151 		}
152 
153 		@Override
154 		public void setResult(RefUpdate.Result status) {
155 			result = status;
156 			super.setResult(status);
157 		}
158 
159 		@Override
160 		public void setResult(ReceiveCommand.Result status) {
161 			result = decode(status);
162 			super.setResult(status);
163 		}
164 
165 		@Override
166 		public void setResult(ReceiveCommand.Result status, String msg) {
167 			result = decode(status);
168 			super.setResult(status, msg);
169 		}
170 
171 		private RefUpdate.Result decode(ReceiveCommand.Result status) {
172 			switch (status) {
173 			case OK:
174 				if (AnyObjectId.equals(oldObjectId, newObjectId))
175 					return RefUpdate.Result.NO_CHANGE;
176 				switch (getType()) {
177 				case CREATE:
178 					return RefUpdate.Result.NEW;
179 				case UPDATE:
180 					return RefUpdate.Result.FAST_FORWARD;
181 				case DELETE:
182 				case UPDATE_NONFASTFORWARD:
183 				default:
184 					return RefUpdate.Result.FORCED;
185 				}
186 
187 			case REJECTED_NOCREATE:
188 			case REJECTED_NODELETE:
189 			case REJECTED_NONFASTFORWARD:
190 				return RefUpdate.Result.REJECTED;
191 			case REJECTED_CURRENT_BRANCH:
192 				return RefUpdate.Result.REJECTED_CURRENT_BRANCH;
193 			case REJECTED_MISSING_OBJECT:
194 				return RefUpdate.Result.IO_FAILURE;
195 			case LOCK_FAILURE:
196 			case NOT_ATTEMPTED:
197 			case REJECTED_OTHER_REASON:
198 			default:
199 				return RefUpdate.Result.LOCK_FAILURE;
200 			}
201 		}
202 	}
203 
204 	@SuppressWarnings("nls")
205 	@Override
206 	public String toString() {
207 		StringBuilder sb = new StringBuilder();
208 		sb.append("TrackingRefUpdate[");
209 		sb.append(remoteName);
210 		sb.append(" -> ");
211 		sb.append(localName);
212 		if (forceUpdate)
213 			sb.append(" (forced)");
214 		sb.append(" ");
215 		sb.append(oldObjectId == null ? "" : oldObjectId.abbreviate(7).name());
216 		sb.append("..");
217 		sb.append(newObjectId == null ? "" : newObjectId.abbreviate(7).name());
218 		sb.append("]");
219 		return sb.toString();
220 	}
221 }