package com.beijunyi.parallelgit.utils;
import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import javax.annotation.Nonnull;
import com.beijunyi.parallelgit.utils.exceptions.RefUpdateValidator;
import org.eclipse.jgit.internal.storage.dfs.DfsGarbageCollector;
import org.eclipse.jgit.internal.storage.dfs.DfsRepository;
import org.eclipse.jgit.internal.storage.file.FileRepository;
import org.eclipse.jgit.internal.storage.file.GC;
import org.eclipse.jgit.lib.*;
import static com.beijunyi.parallelgit.utils.RefUtils.fullBranchName;
import static org.eclipse.jgit.lib.ConfigConstants.*;
import static org.eclipse.jgit.lib.Constants.*;
public final class RepositoryUtils {
@Nonnull
public static Repository createRepository(File dir, boolean bare) throws IOException {
Repository repo = new RepositoryBuilder()
.readEnvironment()
.setGitDir(bare ? dir : new File(dir, DOT_GIT))
.build();
repo.create(bare);
return repo;
}
@Nonnull
public static Repository createRepository(File dir) throws IOException {
return createRepository(dir, true);
}
@Nonnull
public static Repository openRepository(File dir, boolean bare) throws IOException {
if(!bare)
return openRepository(new File(dir, DOT_GIT), true);
return new FileRepository(dir);
}
@Nonnull
public static Repository openRepository(File dir) throws IOException {
return openRepository(dir, !new File(dir, DOT_GIT).exists());
}
public static void setDefaultCommitter(String name, String email, Repository repo) throws IOException {
StoredConfig config = repo.getConfig();
config.setString(CONFIG_USER_SECTION, null, CONFIG_KEY_NAME, name);
config.setString(CONFIG_USER_SECTION, null, CONFIG_KEY_EMAIL, email);
config.save();
}
public static boolean isRefLogEnabled(Repository repo) {
StoredConfig config = repo.getConfig();
return config.getBoolean(CONFIG_CORE_SECTION, null, CONFIG_KEY_LOGALLREFUPDATES, false);
}
public static void setRefLogEnabled(boolean enabled, Repository repo) {
StoredConfig config = repo.getConfig();
config.setBoolean(CONFIG_CORE_SECTION, null, CONFIG_KEY_LOGALLREFUPDATES, enabled);
}
@Nonnull
private static RefUpdate prepareUpdateHead(Repository repo, String name, boolean detach) throws IOException {
RefUpdate ret = repo.updateRef(Constants.HEAD, detach);
ret.setForceUpdate(true);
ret.setRefLogMessage("checkout: moving from HEAD to " + Repository.shortenRefName(name), false);
return ret;
}
public static void attachRepositoryHead(Repository repo, String refName) throws IOException {
RefUpdate update = prepareUpdateHead(repo, Repository.shortenRefName(refName), false);
RefUpdateValidator.validate(update.link(refName));
}
public static void attachRepositoryHead(Repository repo, Ref ref) throws IOException {
attachRepositoryHead(repo, ref.getName());
}
public static void detachRepositoryHead(Repository repo, AnyObjectId id) throws IOException {
id = CommitUtils.getCommit(id, repo);
RefUpdate update = prepareUpdateHead(repo, id.getName(), true);
update.setNewObjectId(id);
RefUpdateValidator.validate(update.forceUpdate());
}
public static void setRepositoryHead(Repository repo, String name) throws IOException {
Ref ref = repo.findRef(name);
if(ref != null) {
if(!ref.getName().startsWith(R_HEADS))
detachRepositoryHead(repo, repo.resolve(name));
else
attachRepositoryHead(repo, ref);
} else
attachRepositoryHead(repo, fullBranchName(name));
}
public static void garbageCollect(FileRepository repo) throws IOException {
try {
new GC(repo).gc();
} catch(ParseException e) {
throw new IllegalStateException(e);
}
}
public static void garbageCollect(DfsRepository repo) throws IOException {
new DfsGarbageCollector(repo).pack(NullProgressMonitor.INSTANCE);
}
public static void garbageCollect(Repository repo) throws IOException {
if(repo instanceof FileRepository)
garbageCollect((FileRepository) repo);
else if(repo instanceof DfsRepository)
garbageCollect((DfsRepository) repo);
else
throw new UnsupportedOperationException("Unsupported repository: " + repo.getClass().getName());
}
}