View Javadoc
1   /*
2    * Copyright (C) 2008-2010, Google Inc. and others
3    *
4    * This program and the accompanying materials are made available under the
5    * terms of the Eclipse Distribution License v. 1.0 which is available at
6    * https://www.eclipse.org/org/documents/edl-v10.php.
7    *
8    * SPDX-License-Identifier: BSD-3-Clause
9    */
10  
11  package org.eclipse.jgit.pgm;
12  
13  import java.io.File;
14  import java.io.IOException;
15  import java.text.MessageFormat;
16  import java.util.Collection;
17  
18  import org.eclipse.jgit.api.CloneCommand;
19  import org.eclipse.jgit.api.Git;
20  import org.eclipse.jgit.api.errors.InvalidRemoteException;
21  import org.eclipse.jgit.api.errors.TransportException;
22  import org.eclipse.jgit.lib.AnyObjectId;
23  import org.eclipse.jgit.lib.Constants;
24  import org.eclipse.jgit.lib.TextProgressMonitor;
25  import org.eclipse.jgit.pgm.internal.CLIText;
26  import org.eclipse.jgit.transport.URIish;
27  import org.eclipse.jgit.util.SystemReader;
28  import org.kohsuke.args4j.Argument;
29  import org.kohsuke.args4j.Option;
30  
31  @Command(common = true, usage = "usage_cloneRepositoryIntoNewDir")
32  class Clone extends AbstractFetchCommand implements CloneCommand.Callback {
33  	@Option(name = "--origin", aliases = { "-o" }, metaVar = "metaVar_remoteName", usage = "usage_useNameInsteadOfOriginToTrackUpstream")
34  	private String remoteName = Constants.DEFAULT_REMOTE_NAME;
35  
36  	@Option(name = "--branch", aliases = { "-b" }, metaVar = "metaVar_branchName", usage = "usage_checkoutBranchAfterClone")
37  	private String branch;
38  
39  	@Option(name = "--no-checkout", aliases = { "-n" }, usage = "usage_noCheckoutAfterClone")
40  	private boolean noCheckout;
41  
42  	@Option(name = "--bare", usage = "usage_bareClone")
43  	private boolean isBare;
44  
45  	@Option(name = "--mirror", usage = "usage_mirrorClone")
46  	private boolean isMirror;
47  
48  	@Option(name = "--quiet", usage = "usage_quiet")
49  	private Boolean quiet;
50  
51  	@Option(name = "--recurse-submodules", usage = "usage_recurseSubmodules")
52  	private boolean cloneSubmodules;
53  
54  	@Option(name = "--timeout", metaVar = "metaVar_seconds", usage = "usage_abortConnectionIfNoActivity")
55  	int timeout = -1;
56  
57  	@Argument(index = 0, required = true, metaVar = "metaVar_uriish")
58  	private String sourceUri;
59  
60  	@Argument(index = 1, metaVar = "metaVar_directory")
61  	private String localName;
62  
63  	/** {@inheritDoc} */
64  	@Override
65  	protected final boolean requiresRepository() {
66  		return false;
67  	}
68  
69  	/** {@inheritDoc} */
70  	@Override
71  	protected void run() throws Exception {
72  		if (localName != null && gitdir != null)
73  			throw die(CLIText.get().conflictingUsageOf_git_dir_andArguments);
74  
75  		final URIisht/URIish.html#URIish">URIish uri = new URIish(sourceUri);
76  		File localNameF;
77  		if (localName == null) {
78  			try {
79  				localName = uri.getHumanishName();
80  				if (isBare || isMirror) {
81  					localName = localName + Constants.DOT_GIT_EXT;
82  				}
83  				localNameF = new File(SystemReader.getInstance().getProperty(
84  						Constants.OS_USER_DIR), localName);
85  			} catch (IllegalArgumentException e) {
86  				throw die(MessageFormat.format(
87  						CLIText.get().cannotGuessLocalNameFrom, sourceUri), e);
88  			}
89  		} else
90  			localNameF = new File(localName);
91  
92  		if (branch == null)
93  			branch = Constants.HEAD;
94  
95  		CloneCommand command = Git.cloneRepository();
96  		command.setURI(sourceUri).setRemote(remoteName).setBare(isBare)
97  				.setMirror(isMirror).setNoCheckout(noCheckout).setBranch(branch)
98  				.setCloneSubmodules(cloneSubmodules).setTimeout(timeout);
99  
100 		command.setGitDir(gitdir == null ? null : new File(gitdir));
101 		command.setDirectory(localNameF);
102 		boolean msgs = quiet == null || !quiet.booleanValue();
103 		if (msgs) {
104 			command.setProgressMonitor(new TextProgressMonitor(errw))
105 					.setCallback(this);
106 			outw.println(MessageFormat.format(
107 					CLIText.get().cloningInto, localName));
108 			outw.flush();
109 		}
110 		try {
111 			db = command.call().getRepository();
112 			if (msgs && db.resolve(Constants.HEAD) == null)
113 				outw.println(CLIText.get().clonedEmptyRepository);
114 		} catch (TransportException e) {
115 			throw die(e.getMessage(), e);
116 		} catch (InvalidRemoteException e) {
117 			throw die(MessageFormat.format(CLIText.get().doesNotExist,
118 					sourceUri), e);
119 		} finally {
120 			if (db != null)
121 				db.close();
122 		}
123 		if (msgs) {
124 			outw.println();
125 			outw.flush();
126 		}
127 	}
128 
129 	/** {@inheritDoc} */
130 	@Override
131 	public void initializedSubmodules(Collection<String> submodules) {
132 		try {
133 			for (String submodule : submodules) {
134 				outw.println(MessageFormat
135 						.format(CLIText.get().submoduleRegistered, submodule));
136 			}
137 			outw.flush();
138 		} catch (IOException e) {
139 			// ignore
140 		}
141 	}
142 
143 	/** {@inheritDoc} */
144 	@Override
145 	public void cloningSubmodule(String path) {
146 		try {
147 			outw.println(MessageFormat.format(
148 					CLIText.get().cloningInto, path));
149 			outw.flush();
150 		} catch (IOException e) {
151 			// ignore
152 		}
153 	}
154 
155 	/** {@inheritDoc} */
156 	@Override
157 	public void checkingOut(AnyObjectId commit, String path) {
158 		try {
159 			outw.println(MessageFormat.format(CLIText.get().checkingOut,
160 					path, commit.getName()));
161 			outw.flush();
162 		} catch (IOException e) {
163 			// ignore
164 		}
165 	}
166 }