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 /**
53 * Update of a locally stored tracking branch.
54 */
55 public class TrackingRefUpdate {
56 private final String remoteName;
57 final String localName;
58 boolean forceUpdate;
59 ObjectId oldObjectId;
60 ObjectId newObjectId;
61
62 private RefUpdate.Result result;
63 private ReceiveCommand cmd;
64
65 TrackingRefUpdate(
66 boolean canForceUpdate,
67 String remoteName,
68 String localName,
69 AnyObjectId oldValue,
70 AnyObjectId newValue) {
71 this.remoteName = remoteName;
72 this.localName = localName;
73 this.forceUpdate = canForceUpdate;
74 this.oldObjectId = oldValue.copy();
75 this.newObjectId = newValue.copy();
76 }
77
78 /**
79 * Get the name of the remote ref.
80 * <p>
81 * Usually this is of the form "refs/heads/master".
82 *
83 * @return the name used within the remote repository.
84 */
85 public String getRemoteName() {
86 return remoteName;
87 }
88
89 /**
90 * Get the name of the local tracking ref.
91 * <p>
92 * Usually this is of the form "refs/remotes/origin/master".
93 *
94 * @return the name used within this local repository.
95 */
96 public String getLocalName() {
97 return localName;
98 }
99
100 /**
101 * Get the new value the ref will be (or was) updated to.
102 *
103 * @return new value. Null if the caller has not configured it.
104 */
105 public ObjectId getNewObjectId() {
106 return newObjectId;
107 }
108
109 /**
110 * The old value of the ref, prior to the update being attempted.
111 * <p>
112 * This value may differ before and after the update method. Initially it is
113 * populated with the value of the ref before the lock is taken, but the old
114 * value may change if someone else modified the ref between the time we
115 * last read it and when the ref was locked for update.
116 *
117 * @return the value of the ref prior to the update being attempted.
118 */
119 public ObjectId getOldObjectId() {
120 return oldObjectId;
121 }
122
123 /**
124 * Get the status of this update.
125 *
126 * @return the status of the update.
127 */
128 public RefUpdate.Result getResult() {
129 return result;
130 }
131
132 void setResult(RefUpdate.Result result) {
133 this.result = result;
134 }
135
136 /**
137 * Get this update wrapped by a ReceiveCommand.
138 *
139 * @return this update wrapped by a ReceiveCommand.
140 * @since 3.4
141 */
142 public ReceiveCommand asReceiveCommand() {
143 if (cmd == null)
144 cmd = new Command();
145 return cmd;
146 }
147
148 final class Command extends ReceiveCommand {
149 Command() {
150 super(oldObjectId, newObjectId, localName);
151 }
152
153 boolean canForceUpdate() {
154 return forceUpdate;
155 }
156
157 @Override
158 public void setResult(RefUpdate.Result status) {
159 result = status;
160 super.setResult(status);
161 }
162
163 @Override
164 public void setResult(ReceiveCommand.Result status) {
165 result = decode(status);
166 super.setResult(status);
167 }
168
169 @Override
170 public void setResult(ReceiveCommand.Result status, String msg) {
171 result = decode(status);
172 super.setResult(status, msg);
173 }
174
175 private RefUpdate.Result decode(ReceiveCommand.Result status) {
176 switch (status) {
177 case OK:
178 if (AnyObjectId.isEqual(oldObjectId, newObjectId))
179 return RefUpdate.Result.NO_CHANGE;
180 switch (getType()) {
181 case CREATE:
182 return RefUpdate.Result.NEW;
183 case UPDATE:
184 return RefUpdate.Result.FAST_FORWARD;
185 case DELETE:
186 case UPDATE_NONFASTFORWARD:
187 default:
188 return RefUpdate.Result.FORCED;
189 }
190
191 case REJECTED_NOCREATE:
192 case REJECTED_NODELETE:
193 case REJECTED_NONFASTFORWARD:
194 return RefUpdate.Result.REJECTED;
195 case REJECTED_CURRENT_BRANCH:
196 return RefUpdate.Result.REJECTED_CURRENT_BRANCH;
197 case REJECTED_MISSING_OBJECT:
198 return RefUpdate.Result.IO_FAILURE;
199 case LOCK_FAILURE:
200 case NOT_ATTEMPTED:
201 case REJECTED_OTHER_REASON:
202 default:
203 return RefUpdate.Result.LOCK_FAILURE;
204 }
205 }
206 }
207
208 /** {@inheritDoc} */
209 @SuppressWarnings("nls")
210 @Override
211 public String toString() {
212 StringBuilder sb = new StringBuilder();
213 sb.append("TrackingRefUpdate[");
214 sb.append(remoteName);
215 sb.append(" -> ");
216 sb.append(localName);
217 if (forceUpdate)
218 sb.append(" (forced)");
219 sb.append(" ");
220 sb.append(oldObjectId == null ? "" : oldObjectId.abbreviate(7).name());
221 sb.append("..");
222 sb.append(newObjectId == null ? "" : newObjectId.abbreviate(7).name());
223 sb.append("]");
224 return sb.toString();
225 }
226 }