View Javadoc
1   /*
2    * Copyright (C) 2010, Chris Aniszczyk <caniszczyk@gmail.com> 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  package org.eclipse.jgit.api;
11  
12  import java.io.File;
13  import java.io.IOException;
14  import java.text.MessageFormat;
15  import java.util.concurrent.Callable;
16  
17  import org.eclipse.jgit.api.errors.GitAPIException;
18  import org.eclipse.jgit.api.errors.InvalidRefNameException;
19  import org.eclipse.jgit.api.errors.JGitInternalException;
20  import org.eclipse.jgit.errors.ConfigInvalidException;
21  import org.eclipse.jgit.internal.JGitText;
22  import org.eclipse.jgit.lib.ConfigConstants;
23  import org.eclipse.jgit.lib.Constants;
24  import org.eclipse.jgit.lib.Repository;
25  import org.eclipse.jgit.lib.RepositoryBuilder;
26  import org.eclipse.jgit.util.FS;
27  import org.eclipse.jgit.util.StringUtils;
28  import org.eclipse.jgit.util.SystemReader;
29  
30  /**
31   * Create an empty git repository or reinitalize an existing one
32   *
33   * @see <a href="http://www.kernel.org/pub/software/scm/git/docs/git-init.html"
34   *      >Git documentation about init</a>
35   */
36  public class InitCommand implements Callable<Git> {
37  	private File directory;
38  
39  	private File gitDir;
40  
41  	private boolean bare;
42  
43  	private FS fs;
44  
45  	private String initialBranch;
46  
47  	/**
48  	 * {@inheritDoc}
49  	 * <p>
50  	 * Executes the {@code Init} command.
51  	 *
52  	 * @return a {@code Git} instance that owns the {@code Repository} that it
53  	 *         wraps.
54  	 */
55  	@Override
56  	public Git call() throws GitAPIException {
57  		try {
58  			RepositoryBuilder builder = new RepositoryBuilder();
59  			if (bare)
60  				builder.setBare();
61  			if (fs != null) {
62  				builder.setFS(fs);
63  			}
64  			builder.readEnvironment();
65  			if (gitDir != null)
66  				builder.setGitDir(gitDir);
67  			else
68  				gitDir = builder.getGitDir();
69  			if (directory != null) {
70  				if (bare)
71  					builder.setGitDir(directory);
72  				else {
73  					builder.setWorkTree(directory);
74  					if (gitDir == null)
75  						builder.setGitDir(new File(directory, Constants.DOT_GIT));
76  				}
77  			} else if (builder.getGitDir() == null) {
78  				String dStr = SystemReader.getInstance()
79  						.getProperty("user.dir"); //$NON-NLS-1$
80  				if (dStr == null)
81  					dStr = "."; //$NON-NLS-1$
82  				File d = new File(dStr);
83  				if (!bare)
84  					d = new File(d, Constants.DOT_GIT);
85  				builder.setGitDir(d);
86  			} else {
87  				// directory was not set but gitDir was set
88  				if (!bare) {
89  					String dStr = SystemReader.getInstance().getProperty(
90  							"user.dir"); //$NON-NLS-1$
91  					if (dStr == null)
92  						dStr = "."; //$NON-NLS-1$
93  					builder.setWorkTree(new File(dStr));
94  				}
95  			}
96  			builder.setInitialBranch(StringUtils.isEmptyOrNull(initialBranch)
97  					? SystemReader.getInstance().getUserConfig().getString(
98  							ConfigConstants.CONFIG_INIT_SECTION, null,
99  							ConfigConstants.CONFIG_KEY_DEFAULT_BRANCH)
100 					: initialBranch);
101 			Repository repository = builder.build();
102 			if (!repository.getObjectDatabase().exists())
103 				repository.create(bare);
104 			return new Git(repository, true);
105 		} catch (IOException | ConfigInvalidException e) {
106 			throw new JGitInternalException(e.getMessage(), e);
107 		}
108 	}
109 
110 	/**
111 	 * The optional directory associated with the init operation. If no
112 	 * directory is set, we'll use the current directory
113 	 *
114 	 * @param directory
115 	 *            the directory to init to
116 	 * @return this instance
117 	 * @throws java.lang.IllegalStateException
118 	 *             if the combination of directory, gitDir and bare is illegal.
119 	 *             E.g. if for a non-bare repository directory and gitDir point
120 	 *             to the same directory of if for a bare repository both
121 	 *             directory and gitDir are specified
122 	 */
123 	public InitCommand setDirectory(File directory)
124 			throws IllegalStateException {
125 		validateDirs(directory, gitDir, bare);
126 		this.directory = directory;
127 		return this;
128 	}
129 
130 	/**
131 	 * Set the repository meta directory (.git)
132 	 *
133 	 * @param gitDir
134 	 *            the repository meta directory
135 	 * @return this instance
136 	 * @throws java.lang.IllegalStateException
137 	 *             if the combination of directory, gitDir and bare is illegal.
138 	 *             E.g. if for a non-bare repository directory and gitDir point
139 	 *             to the same directory of if for a bare repository both
140 	 *             directory and gitDir are specified
141 	 * @since 3.6
142 	 */
143 	public InitCommand setGitDir(File gitDir)
144 			throws IllegalStateException {
145 		validateDirs(directory, gitDir, bare);
146 		this.gitDir = gitDir;
147 		return this;
148 	}
149 
150 	private static void validateDirs(File directory, File gitDir, boolean bare)
151 			throws IllegalStateException {
152 		if (directory != null) {
153 			if (bare) {
154 				if (gitDir != null && !gitDir.equals(directory))
155 					throw new IllegalStateException(MessageFormat.format(
156 							JGitText.get().initFailedBareRepoDifferentDirs,
157 							gitDir, directory));
158 			} else {
159 				if (gitDir != null && gitDir.equals(directory))
160 					throw new IllegalStateException(MessageFormat.format(
161 							JGitText.get().initFailedNonBareRepoSameDirs,
162 							gitDir, directory));
163 			}
164 		}
165 	}
166 
167 	/**
168 	 * Set whether the repository is bare or not
169 	 *
170 	 * @param bare
171 	 *            whether the repository is bare or not
172 	 * @throws java.lang.IllegalStateException
173 	 *             if the combination of directory, gitDir and bare is illegal.
174 	 *             E.g. if for a non-bare repository directory and gitDir point
175 	 *             to the same directory of if for a bare repository both
176 	 *             directory and gitDir are specified
177 	 * @return this instance
178 	 */
179 	public InitCommand setBare(boolean bare) {
180 		validateDirs(directory, gitDir, bare);
181 		this.bare = bare;
182 		return this;
183 	}
184 
185 	/**
186 	 * Set the file system abstraction to be used for repositories created by
187 	 * this command.
188 	 *
189 	 * @param fs
190 	 *            the abstraction.
191 	 * @return {@code this} (for chaining calls).
192 	 * @since 4.10
193 	 */
194 	public InitCommand setFs(FS fs) {
195 		this.fs = fs;
196 		return this;
197 	}
198 
199 	/**
200 	 * Set the initial branch of the new repository. If not specified
201 	 * ({@code null} or empty), fall back to the default name (currently
202 	 * master).
203 	 *
204 	 * @param branch
205 	 *            initial branch name of the new repository
206 	 * @return {@code this}
207 	 * @throws InvalidRefNameException
208 	 *             if the branch name is not valid
209 	 *
210 	 * @since 5.11
211 	 */
212 	public InitCommand setInitialBranch(String branch)
213 			throws InvalidRefNameException {
214 		this.initialBranch = branch;
215 		return this;
216 	}
217 }