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> and others
5    *
6    * This program and the accompanying materials are made available under the
7    * terms of the Eclipse Distribution License v. 1.0 which is available at
8    * https://www.eclipse.org/org/documents/edl-v10.php.
9    *
10   * SPDX-License-Identifier: BSD-3-Clause
11   */
12  
13  package org.eclipse.jgit.transport;
14  
15  import org.eclipse.jgit.lib.AnyObjectId;
16  import org.eclipse.jgit.lib.ObjectId;
17  import org.eclipse.jgit.lib.RefUpdate;
18  
19  /**
20   * Update of a locally stored tracking branch.
21   */
22  public class TrackingRefUpdate {
23  	private final String remoteName;
24  	final String localName;
25  	boolean forceUpdate;
26  	ObjectId oldObjectId;
27  	ObjectId newObjectId;
28  
29  	private RefUpdate.Result result;
30  	private ReceiveCommand cmd;
31  
32  	TrackingRefUpdate(
33  			boolean canForceUpdate,
34  			String remoteName,
35  			String localName,
36  			AnyObjectId oldValue,
37  			AnyObjectId newValue) {
38  		this.remoteName = remoteName;
39  		this.localName = localName;
40  		this.forceUpdate = canForceUpdate;
41  		this.oldObjectId = oldValue.copy();
42  		this.newObjectId = newValue.copy();
43  	}
44  
45  	/**
46  	 * Get the name of the remote ref.
47  	 * <p>
48  	 * Usually this is of the form "refs/heads/master".
49  	 *
50  	 * @return the name used within the remote repository.
51  	 */
52  	public String getRemoteName() {
53  		return remoteName;
54  	}
55  
56  	/**
57  	 * Get the name of the local tracking ref.
58  	 * <p>
59  	 * Usually this is of the form "refs/remotes/origin/master".
60  	 *
61  	 * @return the name used within this local repository.
62  	 */
63  	public String getLocalName() {
64  		return localName;
65  	}
66  
67  	/**
68  	 * Get the new value the ref will be (or was) updated to.
69  	 *
70  	 * @return new value. Null if the caller has not configured it.
71  	 */
72  	public ObjectId getNewObjectId() {
73  		return newObjectId;
74  	}
75  
76  	/**
77  	 * The old value of the ref, prior to the update being attempted.
78  	 * <p>
79  	 * This value may differ before and after the update method. Initially it is
80  	 * populated with the value of the ref before the lock is taken, but the old
81  	 * value may change if someone else modified the ref between the time we
82  	 * last read it and when the ref was locked for update.
83  	 *
84  	 * @return the value of the ref prior to the update being attempted.
85  	 */
86  	public ObjectId getOldObjectId() {
87  		return oldObjectId;
88  	}
89  
90  	/**
91  	 * Get the status of this update.
92  	 *
93  	 * @return the status of the update.
94  	 */
95  	public RefUpdate.Result getResult() {
96  		return result;
97  	}
98  
99  	void setResult(RefUpdate.Result result) {
100 		this.result = result;
101 	}
102 
103 	/**
104 	 * Get this update wrapped by a ReceiveCommand.
105 	 *
106 	 * @return this update wrapped by a ReceiveCommand.
107 	 * @since 3.4
108 	 */
109 	public ReceiveCommand asReceiveCommand() {
110 		if (cmd == null)
111 			cmd = new Command();
112 		return cmd;
113 	}
114 
115 	final class Command extends ReceiveCommand {
116 		Command() {
117 			super(oldObjectId, newObjectId, localName);
118 		}
119 
120 		boolean canForceUpdate() {
121 			return forceUpdate;
122 		}
123 
124 		@Override
125 		public void setResult(RefUpdate.Result status) {
126 			result = status;
127 			super.setResult(status);
128 		}
129 
130 		@Override
131 		public void setResult(ReceiveCommand.Result status) {
132 			result = decode(status);
133 			super.setResult(status);
134 		}
135 
136 		@Override
137 		public void setResult(ReceiveCommand.Result status, String msg) {
138 			result = decode(status);
139 			super.setResult(status, msg);
140 		}
141 
142 		private RefUpdate.Result decode(ReceiveCommand.Result status) {
143 			switch (status) {
144 			case OK:
145 				if (AnyObjectId.isEqual(oldObjectId, newObjectId))
146 					return RefUpdate.Result.NO_CHANGE;
147 				switch (getType()) {
148 				case CREATE:
149 					return RefUpdate.Result.NEW;
150 				case UPDATE:
151 					return RefUpdate.Result.FAST_FORWARD;
152 				case DELETE:
153 				case UPDATE_NONFASTFORWARD:
154 				default:
155 					return RefUpdate.Result.FORCED;
156 				}
157 
158 			case REJECTED_NOCREATE:
159 			case REJECTED_NODELETE:
160 			case REJECTED_NONFASTFORWARD:
161 				return RefUpdate.Result.REJECTED;
162 			case REJECTED_CURRENT_BRANCH:
163 				return RefUpdate.Result.REJECTED_CURRENT_BRANCH;
164 			case REJECTED_MISSING_OBJECT:
165 				return RefUpdate.Result.IO_FAILURE;
166 			case LOCK_FAILURE:
167 			case NOT_ATTEMPTED:
168 			case REJECTED_OTHER_REASON:
169 			default:
170 				return RefUpdate.Result.LOCK_FAILURE;
171 			}
172 		}
173 	}
174 
175 	/** {@inheritDoc} */
176 	@SuppressWarnings("nls")
177 	@Override
178 	public String toString() {
179 		StringBuilder sb = new StringBuilder();
180 		sb.append("TrackingRefUpdate[");
181 		sb.append(remoteName);
182 		sb.append(" -> ");
183 		sb.append(localName);
184 		if (forceUpdate)
185 			sb.append(" (forced)");
186 		sb.append(" ");
187 		sb.append(oldObjectId == null ? "" : oldObjectId.abbreviate(7).name());
188 		sb.append("..");
189 		sb.append(newObjectId == null ? "" : newObjectId.abbreviate(7).name());
190 		sb.append("]");
191 		return sb.toString();
192 	}
193 }