1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.scm.provider.git.jgit.command.branch;
20
21 import java.util.ArrayList;
22 import java.util.HashSet;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.Set;
26
27 import org.apache.commons.lang3.StringUtils;
28 import org.apache.maven.scm.ScmException;
29 import org.apache.maven.scm.ScmFile;
30 import org.apache.maven.scm.ScmFileSet;
31 import org.apache.maven.scm.ScmFileStatus;
32 import org.apache.maven.scm.ScmResult;
33 import org.apache.maven.scm.command.branch.AbstractBranchCommand;
34 import org.apache.maven.scm.command.branch.BranchScmResult;
35 import org.apache.maven.scm.provider.ScmProviderRepository;
36 import org.apache.maven.scm.provider.git.command.GitCommand;
37 import org.apache.maven.scm.provider.git.jgit.command.JGitUtils;
38 import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
39 import org.eclipse.jgit.api.Git;
40 import org.eclipse.jgit.api.errors.GitAPIException;
41 import org.eclipse.jgit.lib.Constants;
42 import org.eclipse.jgit.lib.Ref;
43 import org.eclipse.jgit.lib.Repository;
44 import org.eclipse.jgit.revwalk.RevCommit;
45 import org.eclipse.jgit.revwalk.RevWalk;
46 import org.eclipse.jgit.transport.RefSpec;
47 import org.eclipse.jgit.treewalk.TreeWalk;
48
49
50
51
52
53 public class JGitBranchCommand extends AbstractBranchCommand implements GitCommand {
54
55
56
57
58 @Override
59 protected ScmResult executeBranchCommand(
60 ScmProviderRepository repo, ScmFileSet fileSet, String branch, String message) throws ScmException {
61 if (branch == null || StringUtils.isEmpty(branch.trim())) {
62 throw new ScmException("branch name must be specified");
63 }
64
65 if (!fileSet.getFileList().isEmpty()) {
66 throw new ScmException("This provider doesn't support branching subsets of a directory");
67 }
68
69 Git git = null;
70 try {
71 git = JGitUtils.openRepo(fileSet.getBasedir());
72 Ref branchResult = git.branchCreate().setName(branch).call();
73 logger.info("created [" + branchResult.getName() + "]");
74
75 if (logger.isDebugEnabled()) {
76 for (String branchName : getShortLocalBranchNames(git)) {
77 logger.debug("local branch available: " + branchName);
78 }
79 }
80
81 if (repo.isPushChanges()) {
82 logger.info("push branch [" + branch + "] to remote...");
83 JGitUtils.push(git, (GitScmProviderRepository) repo, new RefSpec(Constants.R_HEADS + branch));
84 }
85
86
87 final RevWalk revWalk = new RevWalk(git.getRepository());
88 RevCommit commit = revWalk.parseCommit(branchResult.getObjectId());
89 revWalk.close();
90
91 final TreeWalk walk = new TreeWalk(git.getRepository());
92 walk.reset();
93 walk.setRecursive(true);
94 walk.addTree(commit.getTree());
95
96 List<ScmFile> files = new ArrayList<>();
97 while (walk.next()) {
98 files.add(new ScmFile(walk.getPathString(), ScmFileStatus.CHECKED_OUT));
99 }
100 walk.close();
101
102 return new BranchScmResult("JGit branch", files);
103
104 } catch (Exception e) {
105 throw new ScmException("JGit branch failed!", e);
106 } finally {
107 JGitUtils.closeRepo(git);
108 }
109 }
110
111
112
113
114
115
116
117
118 public static Set<String> getShortLocalBranchNames(Git git) throws GitAPIException {
119 Set<String> branches = new HashSet<>();
120 Iterator<Ref> iter = git.branchList().call().iterator();
121 while (iter.hasNext()) {
122 branches.add(Repository.shortenRefName(iter.next().getName()));
123 }
124 return branches;
125 }
126 }