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