|
|
|
@ -15,11 +15,20 @@ |
|
|
|
*/ |
|
|
|
package org.thingsboard.server.service.sync.vc; |
|
|
|
|
|
|
|
import com.google.common.collect.Iterables; |
|
|
|
import com.google.common.collect.Streams; |
|
|
|
import lombok.Data; |
|
|
|
import lombok.Getter; |
|
|
|
import org.apache.commons.lang3.StringUtils; |
|
|
|
import org.apache.sshd.common.util.security.SecurityUtils; |
|
|
|
import org.eclipse.jgit.api.*; |
|
|
|
import org.eclipse.jgit.api.CloneCommand; |
|
|
|
import org.eclipse.jgit.api.Git; |
|
|
|
import org.eclipse.jgit.api.GitCommand; |
|
|
|
import org.eclipse.jgit.api.ListBranchCommand; |
|
|
|
import org.eclipse.jgit.api.LogCommand; |
|
|
|
import org.eclipse.jgit.api.LsRemoteCommand; |
|
|
|
import org.eclipse.jgit.api.ResetCommand; |
|
|
|
import org.eclipse.jgit.api.TransportCommand; |
|
|
|
import org.eclipse.jgit.api.errors.GitAPIException; |
|
|
|
import org.eclipse.jgit.lib.Constants; |
|
|
|
import org.eclipse.jgit.lib.ObjectId; |
|
|
|
@ -28,6 +37,7 @@ import org.eclipse.jgit.lib.ObjectReader; |
|
|
|
import org.eclipse.jgit.revwalk.RevCommit; |
|
|
|
import org.eclipse.jgit.revwalk.filter.RevFilter; |
|
|
|
import org.eclipse.jgit.transport.CredentialsProvider; |
|
|
|
import org.eclipse.jgit.transport.RefSpec; |
|
|
|
import org.eclipse.jgit.transport.SshTransport; |
|
|
|
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; |
|
|
|
import org.eclipse.jgit.transport.sshd.JGitKeyCache; |
|
|
|
@ -36,7 +46,8 @@ import org.eclipse.jgit.transport.sshd.SshdSessionFactory; |
|
|
|
import org.eclipse.jgit.transport.sshd.SshdSessionFactoryBuilder; |
|
|
|
import org.eclipse.jgit.treewalk.TreeWalk; |
|
|
|
import org.eclipse.jgit.treewalk.filter.PathFilter; |
|
|
|
import org.thingsboard.server.common.data.StringUtils; |
|
|
|
import org.thingsboard.server.common.data.page.PageData; |
|
|
|
import org.thingsboard.server.common.data.page.PageLink; |
|
|
|
import org.thingsboard.server.common.data.sync.vc.EntitiesVersionControlSettings; |
|
|
|
import org.thingsboard.server.common.data.sync.vc.VersionControlAuthMethod; |
|
|
|
|
|
|
|
@ -51,6 +62,7 @@ import java.util.ArrayList; |
|
|
|
import java.util.Collections; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Set; |
|
|
|
import java.util.function.Function; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
public class GitRepository { |
|
|
|
@ -119,15 +131,18 @@ public class GitRepository { |
|
|
|
.setRemoveDeletedRefs(true)); |
|
|
|
} |
|
|
|
|
|
|
|
public void checkout(String branch, boolean createBranch) throws GitAPIException { |
|
|
|
execute(git.checkout() |
|
|
|
.setCreateBranch(createBranch) |
|
|
|
.setName(branch)); |
|
|
|
public void deleteLocalBranchIfExists(String branch) throws GitAPIException { |
|
|
|
execute(git.branchDelete() |
|
|
|
.setBranchNames(branch) |
|
|
|
.setForce(true)); |
|
|
|
} |
|
|
|
|
|
|
|
public void reset() throws GitAPIException { |
|
|
|
public void resetAndClean() throws GitAPIException { |
|
|
|
execute(git.reset() |
|
|
|
.setMode(ResetCommand.ResetType.HARD)); |
|
|
|
execute(git.clean() |
|
|
|
.setForce(true) |
|
|
|
.setCleanDirectories(true)); |
|
|
|
} |
|
|
|
|
|
|
|
public void merge(String branch) throws IOException, GitAPIException { |
|
|
|
@ -140,36 +155,34 @@ public class GitRepository { |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public List<String> listBranches() throws GitAPIException { |
|
|
|
public List<String> listRemoteBranches() throws GitAPIException { |
|
|
|
return execute(git.branchList() |
|
|
|
.setListMode(ListBranchCommand.ListMode.ALL)).stream() |
|
|
|
.setListMode(ListBranchCommand.ListMode.REMOTE)).stream() |
|
|
|
.filter(ref -> !ref.getName().equals(Constants.HEAD)) |
|
|
|
.map(ref -> org.eclipse.jgit.lib.Repository.shortenRefName(ref.getName())) |
|
|
|
.map(name -> StringUtils.removeStart(name, "origin/")) |
|
|
|
.distinct().collect(Collectors.toList()); |
|
|
|
} |
|
|
|
|
|
|
|
public List<Commit> listCommits(String branch, int limit) throws IOException, GitAPIException { |
|
|
|
return listCommits(branch, null, limit); |
|
|
|
public PageData<Commit> listCommits(String branch, PageLink pageLink) throws IOException, GitAPIException { |
|
|
|
return listCommits(branch, null, pageLink); |
|
|
|
} |
|
|
|
|
|
|
|
public List<Commit> listCommits(String branch, String path, int limit) throws IOException, GitAPIException { |
|
|
|
public PageData<Commit> listCommits(String branch, String path, PageLink pageLink) throws IOException, GitAPIException { |
|
|
|
ObjectId branchId = resolve("origin/" + branch); |
|
|
|
if (branchId == null) { |
|
|
|
throw new IllegalArgumentException("Branch not found"); |
|
|
|
} |
|
|
|
LogCommand command = git.log() |
|
|
|
.add(branchId).setMaxCount(limit) |
|
|
|
.add(branchId) |
|
|
|
.setRevFilter(RevFilter.NO_MERGES); |
|
|
|
if (StringUtils.isNotEmpty(path)) { |
|
|
|
command.addPath(path); |
|
|
|
} |
|
|
|
return Streams.stream(execute(command)) |
|
|
|
.map(this::toCommit) |
|
|
|
.collect(Collectors.toList()); |
|
|
|
Iterable<RevCommit> commits = execute(command); |
|
|
|
return iterableToPageData(commits, this::toCommit, pageLink); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public List<String> listFilesAtCommit(String commitId) throws IOException { |
|
|
|
return listFilesAtCommit(commitId, null); |
|
|
|
} |
|
|
|
@ -212,16 +225,9 @@ public class GitRepository { |
|
|
|
.setOrphan(true) |
|
|
|
.setForced(true) |
|
|
|
.setName(name)); |
|
|
|
// Set<String> uncommittedChanges = git.status().call().getUncommittedChanges();
|
|
|
|
// if (!uncommittedChanges.isEmpty()) {
|
|
|
|
// RmCommand rm = git.rm();
|
|
|
|
// uncommittedChanges.forEach(rm::addFilepattern);
|
|
|
|
// execute(rm);
|
|
|
|
// }
|
|
|
|
// execute(git.clean());
|
|
|
|
} |
|
|
|
|
|
|
|
public void add(String filesPattern) throws GitAPIException { // FIXME [viacheslav]
|
|
|
|
public void add(String filesPattern) throws GitAPIException { |
|
|
|
execute(git.add().setUpdate(true).addFilepattern(filesPattern)); |
|
|
|
execute(git.add().addFilepattern(filesPattern)); |
|
|
|
} |
|
|
|
@ -233,13 +239,14 @@ public class GitRepository { |
|
|
|
|
|
|
|
public Commit commit(String message) throws GitAPIException { |
|
|
|
RevCommit revCommit = execute(git.commit() |
|
|
|
.setMessage(message)); // TODO [viacheslav]: set configurable author for commit
|
|
|
|
.setMessage(message)); |
|
|
|
return toCommit(revCommit); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void push() throws GitAPIException { |
|
|
|
execute(git.push()); |
|
|
|
public void push(String localBranch, String remoteBranch) throws GitAPIException { |
|
|
|
execute(git.push() |
|
|
|
.setRefSpecs(new RefSpec(localBranch + ":" + remoteBranch))); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -293,6 +300,23 @@ public class GitRepository { |
|
|
|
return command.call(); |
|
|
|
} |
|
|
|
|
|
|
|
private static <T,R> PageData<R> iterableToPageData (Iterable<T> iterable, Function<? super T, ? extends R> mapper, PageLink pageLink) { |
|
|
|
int totalElements = Iterables.size(iterable); |
|
|
|
int totalPages = pageLink.getPageSize() > 0 ? (int) Math.ceil((float) totalElements / pageLink.getPageSize()) : 1; |
|
|
|
int startIndex = pageLink.getPageSize() * pageLink.getPage(); |
|
|
|
int limit = startIndex + pageLink.getPageSize(); |
|
|
|
iterable = Iterables.limit(iterable, limit); |
|
|
|
if (startIndex < totalElements) { |
|
|
|
iterable = Iterables.skip(iterable, startIndex); |
|
|
|
} else { |
|
|
|
iterable = Collections.emptyList(); |
|
|
|
} |
|
|
|
List<R> data = Streams.stream(iterable).map(mapper) |
|
|
|
.collect(Collectors.toList()); |
|
|
|
boolean hasNext = pageLink.getPageSize() > 0 && totalElements > startIndex + data.size(); |
|
|
|
return new PageData<>(data, totalPages, totalElements, hasNext); |
|
|
|
} |
|
|
|
|
|
|
|
private static void configureTransportCommand(TransportCommand transportCommand, CredentialsProvider credentialsProvider, SshdSessionFactory sshSessionFactory) { |
|
|
|
if (credentialsProvider != null) { |
|
|
|
transportCommand.setCredentialsProvider(credentialsProvider); |
|
|
|
|