Switch jgit library to the EDL (3-clause BSD)
[egit/zawir.git] / org.spearce.jgit / src / org / spearce / jgit / transport / RemoteConfig.java
blobb0fd5b4b272974c463f4a5c01b58916304ae5352
1 /*
2 * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
3 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or
8 * without modification, are permitted provided that the following
9 * conditions are met:
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
14 * - Redistributions in binary form must reproduce the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer in the documentation and/or other materials provided
17 * with the distribution.
19 * - Neither the name of the Git Development Community nor the
20 * names of its contributors may be used to endorse or promote
21 * products derived from this software without specific prior
22 * written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
25 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
26 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
29 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
36 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 package org.spearce.jgit.transport;
41 import java.net.URISyntaxException;
42 import java.util.ArrayList;
43 import java.util.Collections;
44 import java.util.List;
46 import org.spearce.jgit.lib.RepositoryConfig;
48 /**
49 * A remembered remote repository, including URLs and RefSpecs.
50 * <p>
51 * A remote configuration remembers one or more URLs for a frequently accessed
52 * remote repository as well as zero or more fetch and push specifications
53 * describing how refs should be transferred between this repository and the
54 * remote repository.
56 public class RemoteConfig {
57 private static final String SECTION = "remote";
59 private static final String KEY_URL = "url";
61 private static final String KEY_FETCH = "fetch";
63 private static final String KEY_PUSH = "push";
65 private static final String KEY_UPLOADPACK = "uploadpack";
67 private static final String KEY_RECEIVEPACK = "receivepack";
69 private static final String KEY_TAGOPT = "tagopt";
71 /** Default value for {@link #getUploadPack()} if not specified. */
72 public static final String DEFAULT_UPLOAD_PACK = "git-upload-pack";
74 /** Default value for {@link #getReceivePack()} if not specified. */
75 public static final String DEFAULT_RECEIVE_PACK = "git-receive-pack";
77 private String name;
79 private List<URIish> uris;
81 private List<RefSpec> fetch;
83 private List<RefSpec> push;
85 private String uploadpack;
87 private String receivepack;
89 private TagOpt tagopt;
91 /**
92 * Parse a remote block from an existing configuration file.
93 * <p>
94 * This constructor succeeds even if the requested remote is not defined
95 * within the supplied configuration file. If that occurs then there will be
96 * no URIs and no ref specifications known to the new instance.
98 * @param rc
99 * the existing configuration to get the remote settings from.
100 * The configuration must already be loaded into memory.
101 * @param remoteName
102 * subsection key indicating the name of this remote.
103 * @throws URISyntaxException
104 * one of the URIs within the remote's configuration is invalid.
106 public RemoteConfig(final RepositoryConfig rc, final String remoteName)
107 throws URISyntaxException {
108 name = remoteName;
110 String[] vlst;
111 String val;
113 vlst = rc.getStringList(SECTION, name, KEY_URL);
114 uris = new ArrayList<URIish>(vlst.length);
115 for (final String s : vlst)
116 uris.add(new URIish(s));
118 vlst = rc.getStringList(SECTION, name, KEY_FETCH);
119 fetch = new ArrayList<RefSpec>(vlst.length);
120 for (final String s : vlst)
121 fetch.add(new RefSpec(s));
123 vlst = rc.getStringList(SECTION, name, KEY_PUSH);
124 push = new ArrayList<RefSpec>(vlst.length);
125 for (final String s : vlst)
126 push.add(new RefSpec(s));
128 val = rc.getString(SECTION, name, KEY_UPLOADPACK);
129 if (val == null)
130 val = DEFAULT_UPLOAD_PACK;
131 uploadpack = val;
133 val = rc.getString(SECTION, name, KEY_RECEIVEPACK);
134 if (val == null)
135 val = DEFAULT_RECEIVE_PACK;
136 receivepack = val;
138 val = rc.getString(SECTION, name, KEY_TAGOPT);
139 tagopt = TagOpt.fromOption(val);
143 * Update this remote's definition within the configuration.
145 * @param rc
146 * the configuration file to store ourselves into.
148 public void update(final RepositoryConfig rc) {
149 final List<String> vlst = new ArrayList<String>();
151 vlst.clear();
152 for (final URIish u : getURIs())
153 vlst.add(u.toString());
154 rc.setStringList(SECTION, getName(), KEY_URL, vlst);
156 vlst.clear();
157 for (final RefSpec u : getFetchRefSpecs())
158 vlst.add(u.toString());
159 rc.setStringList(SECTION, getName(), KEY_FETCH, vlst);
161 vlst.clear();
162 for (final RefSpec u : getPushRefSpecs())
163 vlst.add(u.toString());
164 rc.setStringList(SECTION, getName(), KEY_PUSH, vlst);
166 set(rc, KEY_UPLOADPACK, getUploadPack(), DEFAULT_UPLOAD_PACK);
167 set(rc, KEY_RECEIVEPACK, getReceivePack(), DEFAULT_RECEIVE_PACK);
168 set(rc, KEY_TAGOPT, getTagOpt().option(), TagOpt.AUTO_FOLLOW.option());
171 private void set(final RepositoryConfig rc, final String key,
172 final String currentValue, final String defaultValue) {
173 if (defaultValue.equals(currentValue))
174 rc.unsetString(SECTION, getName(), key);
175 else
176 rc.setString(SECTION, getName(), key, currentValue);
180 * Get the local name this remote configuration is recognized as.
182 * @return name assigned by the user to this configuration block.
184 public String getName() {
185 return name;
189 * Get all configured URIs under this remote.
191 * @return the set of URIs known to this remote.
193 public List<URIish> getURIs() {
194 return Collections.unmodifiableList(uris);
198 * Add a new URI to the end of the list of URIs.
200 * @param toAdd
201 * the new URI to add to this remote.
202 * @return true if the URI was added; false if it already exists.
204 public boolean addURI(final URIish toAdd) {
205 if (uris.contains(toAdd))
206 return false;
207 return uris.add(toAdd);
211 * Remove a URI from the list of URIs.
213 * @param toRemove
214 * the URI to remove from this remote.
215 * @return true if the URI was added; false if it already exists.
217 public boolean removeURI(final URIish toRemove) {
218 return uris.remove(toRemove);
222 * Remembered specifications for fetching from a repository.
224 * @return set of specs used by default when fetching.
226 public List<RefSpec> getFetchRefSpecs() {
227 return Collections.unmodifiableList(fetch);
231 * Add a new fetch RefSpec to this remote.
233 * @param s
234 * the new specification to add.
235 * @return true if the specification was added; false if it already exists.
237 public boolean addFetchRefSpec(final RefSpec s) {
238 if (fetch.contains(s))
239 return false;
240 return fetch.add(s);
244 * Remove a fetch RefSpec from this remote.
246 * @param s
247 * the specification to remove.
248 * @return true if the specification existed and was removed.
250 public boolean removeFetchRefSpec(final RefSpec s) {
251 return fetch.remove(s);
255 * Remembered specifications for pushing to a repository.
257 * @return set of specs used by default when pushing.
259 public List<RefSpec> getPushRefSpecs() {
260 return Collections.unmodifiableList(push);
264 * Add a new push RefSpec to this remote.
266 * @param s
267 * the new specification to add.
268 * @return true if the specification was added; false if it already exists.
270 public boolean addPushRefSpec(final RefSpec s) {
271 if (push.contains(s))
272 return false;
273 return push.add(s);
277 * Remove a push RefSpec from this remote.
279 * @param s
280 * the specification to remove.
281 * @return true if the specification existed and was removed.
283 public boolean removePushRefSpec(final RefSpec s) {
284 return push.remove(s);
288 * Override for the location of 'git-upload-pack' on the remote system.
289 * <p>
290 * This value is only useful for an SSH style connection, where Git is
291 * asking the remote system to execute a program that provides the necessary
292 * network protocol.
294 * @return location of 'git-upload-pack' on the remote system. If no
295 * location has been configured the default of 'git-upload-pack' is
296 * returned instead.
298 public String getUploadPack() {
299 return uploadpack;
303 * Override for the location of 'git-receive-pack' on the remote system.
304 * <p>
305 * This value is only useful for an SSH style connection, where Git is
306 * asking the remote system to execute a program that provides the necessary
307 * network protocol.
309 * @return location of 'git-receive-pack' on the remote system. If no
310 * location has been configured the default of 'git-receive-pack' is
311 * returned instead.
313 public String getReceivePack() {
314 return receivepack;
318 * Get the description of how annotated tags should be treated during fetch.
320 * @return option indicating the behavior of annotated tags in fetch.
322 public TagOpt getTagOpt() {
323 return tagopt;
327 * Set the description of how annotated tags should be treated on fetch.
329 * @param option
330 * method to use when handling annotated tags.
332 public void setTagOpt(final TagOpt option) {
333 tagopt = option != null ? option : TagOpt.AUTO_FOLLOW;