|
|
@@ -1,295 +0,0 @@
|
|
|
-package cn.reghao.devops.common.build.tool.repo;
|
|
|
-
|
|
|
-import cn.reghao.devops.common.build.model.RepoAuth;
|
|
|
-import cn.reghao.devops.common.build.model.constant.RepoAuthType;
|
|
|
-import org.eclipse.jgit.api.*;
|
|
|
-import org.eclipse.jgit.diff.DiffEntry;
|
|
|
-import org.eclipse.jgit.internal.storage.file.FileRepository;
|
|
|
-import org.eclipse.jgit.lib.ObjectId;
|
|
|
-import org.eclipse.jgit.lib.ObjectReader;
|
|
|
-import org.eclipse.jgit.lib.Ref;
|
|
|
-import org.eclipse.jgit.lib.Repository;
|
|
|
-import org.eclipse.jgit.revwalk.RevCommit;
|
|
|
-import org.eclipse.jgit.revwalk.RevWalk;
|
|
|
-import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
|
|
|
-import org.eclipse.jgit.transport.*;
|
|
|
-import org.eclipse.jgit.treewalk.CanonicalTreeParser;
|
|
|
-
|
|
|
-import java.io.File;
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.Collection;
|
|
|
-import java.util.Collections;
|
|
|
-import java.util.List;
|
|
|
-
|
|
|
-/**
|
|
|
- * Git 实现
|
|
|
- *
|
|
|
- * @author reghao
|
|
|
- * @date 2019-10-12 22:22:00
|
|
|
- */
|
|
|
-public class GitImpl implements CodeUpdater {
|
|
|
- private UsernamePasswordCredentialsProvider credentials;
|
|
|
- private SshSessionFactory sshSessionFactory;
|
|
|
-
|
|
|
- public GitImpl(RepoAuth repoAuth) {
|
|
|
- switch (RepoAuthType.valueOf(repoAuth.getAuthType())) {
|
|
|
- case http:
|
|
|
- httpAuth(repoAuth.getUsername(), repoAuth.getPassword());
|
|
|
- break;
|
|
|
- case ssh:
|
|
|
- sshAuth(repoAuth.getRsaPrikey());
|
|
|
- break;
|
|
|
- default:
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private void httpAuth(String username, String password) {
|
|
|
- this.credentials = new UsernamePasswordCredentialsProvider(username, password);
|
|
|
- }
|
|
|
-
|
|
|
- private void sshAuth(String privateKey) {
|
|
|
- this.sshSessionFactory = new CustomSshSessionFactory(privateKey);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 不存在则 clone,存在则 pull
|
|
|
- *
|
|
|
- * @param
|
|
|
- * @return
|
|
|
- * @date 2020-05-13 下午9:22
|
|
|
- */
|
|
|
- @Override
|
|
|
- public CommitInfo pull(String remote, String branch, String local) throws Exception {
|
|
|
- String localRepoDir = local + dirname(remote);
|
|
|
- File file = new File(localRepoDir);
|
|
|
- if (!file.exists() && !file.mkdirs()) {
|
|
|
- throw new Exception("创建 " + localRepoDir + " 目录失败");
|
|
|
- }
|
|
|
-
|
|
|
- File localRepo = new File(localRepoDir + "/.git");
|
|
|
- CommitInfo commitInfo;
|
|
|
- if (!localRepo.exists()) {
|
|
|
- commitInfo = clone(remote, branch, localRepoDir);
|
|
|
- } else {
|
|
|
- try (Repository repo = new FileRepository(localRepo.getAbsolutePath())) {
|
|
|
- PullCommand gitPull = new Git(repo)
|
|
|
- .pull()
|
|
|
- .setTimeout(600)
|
|
|
- .setFastForward(MergeCommand.FastForwardMode.FF);
|
|
|
- if (sshSessionFactory != null) {
|
|
|
- gitPull.setTransportConfigCallback(transport -> {
|
|
|
- if (transport instanceof SshTransport) {
|
|
|
- setSshTransport((SshTransport) transport);
|
|
|
- }
|
|
|
- });
|
|
|
- gitPull.call();
|
|
|
- } else if (credentials != null) {
|
|
|
- gitPull.setCredentialsProvider(credentials);
|
|
|
- gitPull.call();
|
|
|
- } else {
|
|
|
- gitPull.call();
|
|
|
- }
|
|
|
-
|
|
|
- commitInfo = commitInfo(repo, branch);
|
|
|
- commitInfo.setChangedFiles(changedFileList(repo, branch));
|
|
|
- }
|
|
|
- }
|
|
|
- commitInfo.setRemote(remote);
|
|
|
- commitInfo.setBranch(branch);
|
|
|
- return commitInfo;
|
|
|
- }
|
|
|
-
|
|
|
- private CommitInfo clone(String remote, String branch, String local) throws Exception {
|
|
|
- CloneCommand gitClone;
|
|
|
- if (sshSessionFactory != null) {
|
|
|
- gitClone = Git.cloneRepository()
|
|
|
- .setTimeout(600)
|
|
|
- .setURI(remote)
|
|
|
- .setBranch(branch)
|
|
|
- .setDirectory(new File(local))
|
|
|
- .setTransportConfigCallback(transport -> {
|
|
|
- if (transport instanceof SshTransport) {
|
|
|
- setSshTransport((SshTransport) transport);
|
|
|
- }
|
|
|
- });
|
|
|
- } else if (credentials != null) {
|
|
|
- gitClone = Git.cloneRepository()
|
|
|
- .setURI(remote)
|
|
|
- .setBranch(branch)
|
|
|
- .setDirectory(new File(local))
|
|
|
- .setCredentialsProvider(credentials);
|
|
|
- } else {
|
|
|
- gitClone = Git.cloneRepository()
|
|
|
- .setURI(remote)
|
|
|
- .setBranch(branch)
|
|
|
- .setDirectory(new File(local));
|
|
|
- }
|
|
|
-
|
|
|
- try (Git git = gitClone.setDepth(1).call()) {
|
|
|
- Repository repo = git.getRepository();
|
|
|
- CommitInfo commitInfo = commitInfo(repo, branch);
|
|
|
- commitInfo.setChangedFiles(changedFileList(repo, branch));
|
|
|
- return commitInfo;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private void setSshTransport(SshTransport sshTransport) {
|
|
|
- // Set passphrase using a CustomCredentialsProvider
|
|
|
- sshTransport.setCredentialsProvider(new CustomCredentialProvider(null));
|
|
|
- sshTransport.setSshSessionFactory(sshSessionFactory);
|
|
|
- }
|
|
|
-
|
|
|
- private CommitInfo commitInfo(Repository repo, String branch) throws Exception {
|
|
|
- Ref head = repo.findRef("refs/heads/" + branch);
|
|
|
- if (head == null) {
|
|
|
- String msg = String.format("%s 分支不存在", branch);
|
|
|
- throw new Exception(msg);
|
|
|
- }
|
|
|
-
|
|
|
- ObjectId objectId = head.getObjectId();
|
|
|
- try (RevWalk walk = new RevWalk(repo)) {
|
|
|
- // 最近一次提交的信息
|
|
|
- RevCommit lastCommit = walk.parseCommit(objectId);
|
|
|
- long commitTime = lastCommit.getCommitTime()*1000L;
|
|
|
- String commitAuthor = lastCommit.getAuthorIdent().getName();
|
|
|
- String commitMsg = lastCommit.getFullMessage();
|
|
|
-
|
|
|
- CommitInfo commitInfo = new CommitInfo();
|
|
|
- commitInfo.setCommitId(objectId.name().substring(0, 8));
|
|
|
- commitInfo.setMsCommitTime(commitTime);
|
|
|
- commitInfo.setCommitAuthor(commitAuthor);
|
|
|
- if (commitMsg.length() > 1000) {
|
|
|
- commitInfo.setCommitMsg(commitMsg.substring(0, 1000));
|
|
|
- } else {
|
|
|
- commitInfo.setCommitMsg(commitMsg);
|
|
|
- }
|
|
|
- return commitInfo;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private List<ChangedFile> changedFileList(Repository repo, String branch) throws Exception {
|
|
|
- Ref headMaster = repo.findRef("refs/heads/" + branch);
|
|
|
- ObjectId objectId = headMaster.getObjectId();
|
|
|
- try (RevWalk walk = new RevWalk(repo)) {
|
|
|
- // 最近一次提交
|
|
|
- RevCommit newCommit = walk.parseCommit(objectId);
|
|
|
- walk.markStart(newCommit);
|
|
|
- // 遍历两次找到 newCommit 的前一次提交,newCommit 不是第一次提交
|
|
|
- walk.next();
|
|
|
- RevCommit oldCommit = walk.next();
|
|
|
- if (oldCommit == null) {
|
|
|
- // TODO 仓库中只有一个 commit 时(第一次提交)的处理
|
|
|
- return Collections.emptyList();
|
|
|
- }
|
|
|
-
|
|
|
- ObjectId newHead = newCommit.getTree().getId();
|
|
|
- ObjectId oldHead = oldCommit.getTree().getId();
|
|
|
-
|
|
|
- try (ObjectReader reader = repo.newObjectReader()) {
|
|
|
- CanonicalTreeParser newTreeIter = new CanonicalTreeParser();
|
|
|
- newTreeIter.reset(reader, newHead);
|
|
|
- CanonicalTreeParser oldTreeIter = new CanonicalTreeParser();
|
|
|
- oldTreeIter.reset(reader, oldHead);
|
|
|
- try (Git git = new Git(repo)) {
|
|
|
- List<DiffEntry> diffs= git.diff()
|
|
|
- .setNewTree(newTreeIter)
|
|
|
- .setOldTree(oldTreeIter)
|
|
|
- .call();
|
|
|
-
|
|
|
- List<ChangedFile> changedFiles = new ArrayList<>();
|
|
|
- for (DiffEntry entry : diffs) {
|
|
|
- ChangedFile changedFile = new ChangedFile();
|
|
|
- changedFile.setChangeType(entry.getChangeType().name());
|
|
|
- changedFile.setOldFilePath(entry.getOldPath());
|
|
|
- changedFile.setNewFilePath(entry.getNewPath());
|
|
|
- changedFiles.add(changedFile);
|
|
|
- }
|
|
|
-
|
|
|
- return changedFiles;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public CommitInfo update(String remote, String branch, String local, String commitId) throws Exception {
|
|
|
- // TODO 待实现
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public CommitInfo latestCommitInfo(String local, String branch) throws Exception {
|
|
|
- File localRepo = new File(local + "/.git");
|
|
|
- if (!localRepo.exists()) {
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- try (Repository repo = new FileRepository(localRepo.getAbsolutePath())) {
|
|
|
- return commitInfo(repo, branch);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private String dirname(String gitUrl) {
|
|
|
- int lastIndex = gitUrl.lastIndexOf("/");
|
|
|
- return gitUrl.substring(lastIndex).split(".git")[0];
|
|
|
- }
|
|
|
-
|
|
|
- public List<String> remoteBranches(String remote) {
|
|
|
- List<String> branches = new ArrayList<>();
|
|
|
- try {
|
|
|
- Collection<Ref> refList = Git.lsRemoteRepository().setRemote(remote)
|
|
|
- .setCredentialsProvider(credentials).call();
|
|
|
- for (Ref ref : refList) {
|
|
|
- String refName = ref.getName();
|
|
|
- if (refName.startsWith("refs/heads/")) {
|
|
|
- // 需要进行筛选
|
|
|
- String branchName = refName.replace("refs/heads/", "");
|
|
|
- branches.add(branchName);
|
|
|
- }
|
|
|
- }
|
|
|
- return branches;
|
|
|
- } catch (Exception e) {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
- return branches;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 提交代码并 push 到远程仓库
|
|
|
- *
|
|
|
- * @param
|
|
|
- * @return
|
|
|
- * @date 2022-08-03 下午2:56
|
|
|
- */
|
|
|
- public void commitAndPush(String local, String commitMsg) throws Exception {
|
|
|
- Repository repository = new FileRepositoryBuilder().setGitDir(new File(local + "/.git")).build();
|
|
|
- Git git = new Git(repository);
|
|
|
- RemoteListCommand remoteListCommand = git.remoteList();
|
|
|
- List<RemoteConfig> list = remoteListCommand.call();
|
|
|
- if (list.isEmpty()) {
|
|
|
- throw new Exception("RemoteConfig 不存在");
|
|
|
- }
|
|
|
-
|
|
|
- RemoteConfig remoteConfig = list.get(0);
|
|
|
- List<URIish> urIishList = remoteConfig.getURIs();
|
|
|
- if (urIishList.isEmpty()) {
|
|
|
- throw new Exception("远程仓库 URL 不存在");
|
|
|
- }
|
|
|
-
|
|
|
- URIish urIish = urIishList.get(0);
|
|
|
- String pushUrl = urIish.toString();
|
|
|
-
|
|
|
- AddCommand addCommand = git.add();
|
|
|
- addCommand.addFilepattern(".").call();
|
|
|
-
|
|
|
- CommitCommand commitCommand = git.commit();
|
|
|
- commitCommand.setCommitter("reghao", "reghaodev@gmail.com");
|
|
|
- commitCommand.setAuthor("reghao", "reghaodev@gmail.com");
|
|
|
- commitCommand.setAll(true);
|
|
|
-
|
|
|
- // git commit -m "commit message"
|
|
|
- RevCommit revCommit = commitCommand.setMessage(commitMsg).call();
|
|
|
- PushCommand pushCommand = git.push();
|
|
|
- pushCommand.setRemote(pushUrl).setCredentialsProvider(credentials).call();
|
|
|
- }
|
|
|
-}
|