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