View Javadoc
1   /*
2    * Copyright (C) 2008-2009, Google Inc.
3    * Copyright (C) 2009, Mykola Nikishov <mn@mn.com.ua>
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.pgm;
14  
15  import java.io.IOException;
16  import java.text.MessageFormat;
17  import java.util.List;
18  
19  import org.eclipse.jgit.api.FetchCommand;
20  import org.eclipse.jgit.api.Git;
21  import org.eclipse.jgit.api.errors.GitAPIException;
22  import org.eclipse.jgit.lib.Constants;
23  import org.eclipse.jgit.lib.SubmoduleConfig.FetchRecurseSubmodulesMode;
24  import org.eclipse.jgit.lib.TextProgressMonitor;
25  import org.eclipse.jgit.pgm.internal.CLIText;
26  import org.eclipse.jgit.transport.FetchResult;
27  import org.eclipse.jgit.transport.RefSpec;
28  import org.eclipse.jgit.transport.TagOpt;
29  import org.kohsuke.args4j.Argument;
30  import org.kohsuke.args4j.Option;
31  
32  @Command(common = true, usage = "usage_updateRemoteRefsFromAnotherRepository")
33  class Fetch extends AbstractFetchCommand implements FetchCommand.Callback {
34  	@Option(name = "--timeout", metaVar = "metaVar_seconds", usage = "usage_abortConnectionIfNoActivity")
35  	int timeout = -1;
36  
37  	@Option(name = "--fsck", usage = "usage_performFsckStyleChecksOnReceive")
38  	private Boolean fsck;
39  
40  	@Option(name = "--no-fsck")
41  	void nofsck(@SuppressWarnings("unused") final boolean ignored) {
42  		fsck = Boolean.FALSE;
43  	}
44  
45  	@Option(name = "--prune", usage = "usage_pruneStaleTrackingRefs")
46  	private Boolean prune;
47  
48  	@Option(name = "--dry-run")
49  	private boolean dryRun;
50  
51  	@Option(name = "--thin", usage = "usage_fetchThinPack")
52  	private Boolean thin;
53  
54  	@Option(name = "--no-thin")
55  	void nothin(@SuppressWarnings("unused") final boolean ignored) {
56  		thin = Boolean.FALSE;
57  	}
58  
59  	@Option(name = "--quiet", usage = "usage_quiet")
60  	private Boolean quiet;
61  
62  	@Option(name = "--tags", usage="usage_tags", aliases = { "-t" })
63  	private Boolean tags;
64  
65  	@Option(name = "--no-tags", usage = "usage_notags", aliases = { "-n" })
66  	void notags(@SuppressWarnings("unused")
67  	final boolean ignored) {
68  		tags = Boolean.FALSE;
69  	}
70  
71  	@Option(name = "--force", usage = "usage_forcedFetch", aliases = { "-f" })
72  	private Boolean force;
73  
74  	private FetchRecurseSubmodulesMode recurseSubmodules;
75  
76  	@Option(name = "--recurse-submodules", usage = "usage_recurseSubmodules")
77  	void recurseSubmodules(String mode) {
78  		if (mode == null || mode.isEmpty()) {
79  			recurseSubmodules = FetchRecurseSubmodulesMode.YES;
80  		} else {
81  			for (FetchRecurseSubmodulesMode m : FetchRecurseSubmodulesMode
82  					.values()) {
83  				if (m.matchConfigValue(mode)) {
84  					recurseSubmodules = m;
85  					return;
86  				}
87  			}
88  			throw die(MessageFormat
89  					.format(CLIText.get().invalidRecurseSubmodulesMode, mode));
90  		}
91  	}
92  
93  	@Option(name = "--no-recurse-submodules", usage = "usage_noRecurseSubmodules")
94  	void noRecurseSubmodules(@SuppressWarnings("unused")
95  	final boolean ignored) {
96  		recurseSubmodules = FetchRecurseSubmodulesMode.NO;
97  	}
98  
99  	@Argument(index = 0, metaVar = "metaVar_uriish")
100 	private String remote = Constants.DEFAULT_REMOTE_NAME;
101 
102 	@Argument(index = 1, metaVar = "metaVar_refspec")
103 	private List<RefSpec> toget;
104 
105 	/** {@inheritDoc} */
106 	@Override
107 	protected void run() {
108 		try (Gitit.html#Git">Git git = new Git(db)) {
109 			FetchCommand fetch = git.fetch();
110 			if (fsck != null) {
111 				fetch.setCheckFetchedObjects(fsck.booleanValue());
112 			}
113 			if (prune != null) {
114 				fetch.setRemoveDeletedRefs(prune.booleanValue());
115 			}
116 			if (toget != null) {
117 				fetch.setRefSpecs(toget);
118 			}
119 			if (tags != null) {
120 				fetch.setTagOpt(tags.booleanValue() ? TagOpt.FETCH_TAGS
121 						: TagOpt.NO_TAGS);
122 			}
123 			if (0 <= timeout) {
124 				fetch.setTimeout(timeout);
125 			}
126 			fetch.setDryRun(dryRun);
127 			fetch.setRemote(remote);
128 			if (thin != null) {
129 				fetch.setThin(thin.booleanValue());
130 			}
131 			if (quiet == null || !quiet.booleanValue()) {
132 				fetch.setProgressMonitor(new TextProgressMonitor(errw));
133 			}
134 			fetch.setRecurseSubmodules(recurseSubmodules).setCallback(this);
135 			if (force != null) {
136 				fetch.setForceUpdate(force.booleanValue());
137 			}
138 
139 			FetchResult result = fetch.call();
140 			if (result.getTrackingRefUpdates().isEmpty()
141 					&& result.submoduleResults().isEmpty()) {
142 				return;
143 			}
144 			showFetchResult(result);
145 		} catch (GitAPIException | IOException e) {
146 			throw die(e.getMessage(), e);
147 		}
148 	}
149 
150 	/** {@inheritDoc} */
151 	@Override
152 	public void fetchingSubmodule(String name) {
153 		try {
154 			outw.println(MessageFormat.format(CLIText.get().fetchingSubmodule,
155 					name));
156 			outw.flush();
157 		} catch (IOException e) {
158 			// ignore
159 		}
160 	}
161 }