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()); } }