| | |
| | | import java.io.IOException;
|
| | | import java.io.InputStream;
|
| | | import java.io.OutputStream;
|
| | | import java.nio.charset.Charset;
|
| | | import java.text.MessageFormat;
|
| | | import java.util.ArrayList;
|
| | | import java.util.Arrays;
|
| | |
| | | import org.eclipse.jgit.api.CloneCommand;
|
| | | import org.eclipse.jgit.api.FetchCommand;
|
| | | import org.eclipse.jgit.api.Git;
|
| | | import org.eclipse.jgit.api.ResetCommand;
|
| | | import org.eclipse.jgit.api.ResetCommand.ResetType;
|
| | | import org.eclipse.jgit.diff.DiffEntry;
|
| | | import org.eclipse.jgit.diff.DiffEntry.ChangeType;
|
| | | import org.eclipse.jgit.diff.DiffFormatter;
|
| | |
| | | }
|
| | |
|
| | | /**
|
| | | * Reset HEAD to the latest remote tracking commit.
|
| | | * |
| | | * @param repository
|
| | | * @param remoteRef
|
| | | * the remote tracking reference (e.g. origin/master)
|
| | | * @return Ref
|
| | | * @throws Exception
|
| | | */
|
| | | public static Ref resetHEAD(Repository repository, String remoteRef) throws Exception {
|
| | | if (!remoteRef.startsWith(Constants.R_REMOTES)) {
|
| | | remoteRef = Constants.R_REMOTES + remoteRef;
|
| | | }
|
| | | Git git = new Git(repository);
|
| | | ResetCommand reset = git.reset();
|
| | | reset.setMode(ResetType.SOFT);
|
| | | reset.setRef(remoteRef);
|
| | | Ref result = reset.call();
|
| | | return result;
|
| | | }
|
| | |
|
| | | /**
|
| | | * Creates a bare repository.
|
| | | *
|
| | | * @param repositoriesFolder
|
| | |
| | | */
|
| | | private static List<String> getRepositoryList(String basePath, File searchFolder,
|
| | | boolean onlyBare, boolean searchSubfolders) {
|
| | | File baseFile = new File(basePath);
|
| | | List<String> list = new ArrayList<String>();
|
| | | for (File file : searchFolder.listFiles()) {
|
| | | if (file.isDirectory()) {
|
| | |
| | | continue;
|
| | | }
|
| | | // determine repository name relative to base path
|
| | | String repository = StringUtils.getRelativePath(basePath,
|
| | | file.getAbsolutePath());
|
| | | String repository = FileUtils.getRelativePath(baseFile, file);
|
| | | list.add(repository);
|
| | | } else if (searchSubfolders && file.canRead()) {
|
| | | // look for repositories in subfolders
|
| | |
| | | * last modified date of the repository folder is returned.
|
| | | *
|
| | | * @param repository
|
| | | * @param branch
|
| | | * if unspecified, all branches are checked.
|
| | | * @return
|
| | | */
|
| | | public static Date getLastChange(Repository repository, String branch) {
|
| | | public static Date getLastChange(Repository repository) {
|
| | | if (!hasCommits(repository)) {
|
| | | // null repository
|
| | | if (repository == null) {
|
| | |
| | | // fresh repository
|
| | | return new Date(repository.getDirectory().lastModified());
|
| | | }
|
| | | if (StringUtils.isEmpty(branch)) {
|
| | | List<RefModel> branchModels = getLocalBranches(repository, true, -1);
|
| | | if (branchModels.size() > 0) {
|
| | | // find most recent branch update
|
| | | Date lastChange = new Date(0);
|
| | | for (RefModel branchModel : branchModels) {
|
| | | if (branchModel.getDate().after(lastChange)) {
|
| | | lastChange = branchModel.getDate();
|
| | | }
|
| | | }
|
| | | return lastChange;
|
| | | } else {
|
| | | // try to find head
|
| | | branch = Constants.HEAD;
|
| | | }
|
| | | }
|
| | |
|
| | | // lookup specified branch
|
| | | RevCommit commit = getCommit(repository, branch);
|
| | | return getCommitDate(commit);
|
| | | List<RefModel> branchModels = getLocalBranches(repository, true, -1);
|
| | | if (branchModels.size() > 0) {
|
| | | // find most recent branch update
|
| | | Date lastChange = new Date(0);
|
| | | for (RefModel branchModel : branchModels) {
|
| | | if (branchModel.getDate().after(lastChange)) {
|
| | | lastChange = branchModel.getDate();
|
| | | }
|
| | | }
|
| | | return lastChange;
|
| | | }
|
| | | |
| | | // default to the repository folder modification date
|
| | | return new Date(repository.getDirectory().lastModified());
|
| | | }
|
| | |
|
| | | /**
|
| | |
| | | * @param tree
|
| | | * if null, the RevTree from HEAD is assumed.
|
| | | * @param blobPath
|
| | | * @param charsets optional
|
| | | * @return UTF-8 string content
|
| | | */
|
| | | public static String getStringContent(Repository repository, RevTree tree, String blobPath) {
|
| | | public static String getStringContent(Repository repository, RevTree tree, String blobPath, String... charsets) {
|
| | | byte[] content = getByteContent(repository, tree, blobPath);
|
| | | if (content == null) {
|
| | | return null;
|
| | | }
|
| | | return new String(content, Charset.forName(Constants.CHARACTER_ENCODING));
|
| | | return StringUtils.decodeString(content, charsets);
|
| | | }
|
| | |
|
| | | /**
|
| | |
| | | *
|
| | | * @param repository
|
| | | * @param objectId
|
| | | * @param charsets optional
|
| | | * @return UTF-8 string content
|
| | | */
|
| | | public static String getStringContent(Repository repository, String objectId) {
|
| | | public static String getStringContent(Repository repository, String objectId, String... charsets) {
|
| | | byte[] content = getByteContent(repository, objectId);
|
| | | if (content == null) {
|
| | | return null;
|
| | | }
|
| | | return new String(content, Charset.forName(Constants.CHARACTER_ENCODING));
|
| | | return StringUtils.decodeString(content, charsets);
|
| | | }
|
| | |
|
| | | /**
|
| | |
| | | for (DiffEntry diff : diffs) {
|
| | | if (diff.getChangeType().equals(ChangeType.DELETE)) {
|
| | | list.add(new PathChangeModel(diff.getOldPath(), diff.getOldPath(), 0, diff
|
| | | .getNewMode().getBits(), commit.getId().getName(), diff
|
| | | .getChangeType()));
|
| | | } else if (diff.getChangeType().equals(ChangeType.RENAME)) {
|
| | | list.add(new PathChangeModel(diff.getOldPath(), diff.getNewPath(), 0, diff
|
| | | .getNewMode().getBits(), commit.getId().getName(), diff
|
| | | .getChangeType()));
|
| | | } else {
|
| | |
| | | branchObject = getDefaultBranch(repository);
|
| | | } else {
|
| | | branchObject = repository.resolve(objectId);
|
| | | }
|
| | | if (branchObject == null) {
|
| | | return list;
|
| | | }
|
| | |
|
| | | RevWalk rw = new RevWalk(repository);
|
| | |
| | | }
|
| | |
|
| | | /**
|
| | | * Sets the local branch ref to point to the specified commit id.
|
| | | *
|
| | | * @param repository
|
| | | * @param branch
|
| | | * @param commitId
|
| | | * @return true if successful
|
| | | */
|
| | | public static boolean setBranchRef(Repository repository, String branch, String commitId) {
|
| | | String branchName = branch;
|
| | | if (!branchName.startsWith(Constants.R_HEADS)) {
|
| | | branchName = Constants.R_HEADS + branch;
|
| | | }
|
| | |
|
| | | try {
|
| | | RefUpdate refUpdate = repository.updateRef(branchName, false);
|
| | | refUpdate.setNewObjectId(ObjectId.fromString(commitId));
|
| | | RefUpdate.Result result = refUpdate.forceUpdate();
|
| | |
|
| | | switch (result) {
|
| | | case NEW:
|
| | | case FORCED:
|
| | | case NO_CHANGE:
|
| | | case FAST_FORWARD:
|
| | | return true; |
| | | default:
|
| | | LOGGER.error(MessageFormat.format("{0} {1} update to {2} returned result {3}",
|
| | | repository.getDirectory().getAbsolutePath(), branchName, commitId, result));
|
| | | }
|
| | | } catch (Throwable t) {
|
| | | error(t, repository, "{0} failed to set {1} to {2}", branchName, commitId);
|
| | | }
|
| | | return false;
|
| | | }
|
| | | |
| | | /**
|
| | | * Deletes the specified branch ref.
|
| | | * |
| | | * @param repository
|
| | | * @param branch
|
| | | * @return true if successful
|
| | | */
|
| | | public static boolean deleteBranchRef(Repository repository, String branch) {
|
| | | String branchName = branch;
|
| | | if (!branchName.startsWith(Constants.R_HEADS)) {
|
| | | branchName = Constants.R_HEADS + branch;
|
| | | }
|
| | |
|
| | | try {
|
| | | RefUpdate refUpdate = repository.updateRef(branchName, false);
|
| | | refUpdate.setForceUpdate(true);
|
| | | RefUpdate.Result result = refUpdate.delete();
|
| | | switch (result) {
|
| | | case NEW:
|
| | | case FORCED:
|
| | | case NO_CHANGE:
|
| | | case FAST_FORWARD:
|
| | | return true; |
| | | default:
|
| | | LOGGER.error(MessageFormat.format("{0} failed to delete to {1} returned result {2}",
|
| | | repository.getDirectory().getAbsolutePath(), branchName, result));
|
| | | }
|
| | | } catch (Throwable t) {
|
| | | error(t, repository, "{0} failed to delete {1}", branchName);
|
| | | }
|
| | | return false;
|
| | | }
|
| | | |
| | | /**
|
| | | * Get the full branch and tag ref names for any potential HEAD targets.
|
| | | *
|
| | | * @param repository
|
| | |
| | | List<RefModel> noteBranches = getNoteBranches(repository, true, -1);
|
| | | for (RefModel notesRef : noteBranches) {
|
| | | RevTree notesTree = JGitUtils.getCommit(repository, notesRef.getName()).getTree();
|
| | | // flat notes list
|
| | | String notePath = commit.getName();
|
| | | String text = getStringContent(repository, notesTree, notePath);
|
| | | if (!StringUtils.isEmpty(text)) {
|
| | | List<RevCommit> history = getRevLog(repository, notesRef.getName(), notePath, 0, -1);
|
| | | RefModel noteRef = new RefModel(notesRef.displayName, null, history.get(history
|
| | | .size() - 1));
|
| | | GitNote gitNote = new GitNote(noteRef, text);
|
| | | list.add(gitNote);
|
| | | continue;
|
| | | }
|
| | | |
| | | // folder structure
|
| | | StringBuilder sb = new StringBuilder(commit.getName());
|
| | | sb.insert(2, '/');
|
| | | String notePath = sb.toString();
|
| | | String text = getStringContent(repository, notesTree, notePath);
|
| | | notePath = sb.toString();
|
| | | text = getStringContent(repository, notesTree, notePath);
|
| | | if (!StringUtils.isEmpty(text)) {
|
| | | List<RevCommit> history = getRevLog(repository, notesRef.getName(), notePath, 0, -1);
|
| | | RefModel noteRef = new RefModel(notesRef.displayName, null, history.get(history
|