1
2
3
4
5
6
7
8
9
10
11 package org.eclipse.jgit.api;
12
13 import java.io.IOException;
14 import java.text.MessageFormat;
15 import java.util.ArrayList;
16 import java.util.Arrays;
17 import java.util.HashSet;
18 import java.util.List;
19 import java.util.Set;
20
21 import org.eclipse.jgit.api.errors.CannotDeleteCurrentBranchException;
22 import org.eclipse.jgit.api.errors.GitAPIException;
23 import org.eclipse.jgit.api.errors.JGitInternalException;
24 import org.eclipse.jgit.api.errors.NotMergedException;
25 import org.eclipse.jgit.internal.JGitText;
26 import org.eclipse.jgit.lib.ConfigConstants;
27 import org.eclipse.jgit.lib.Constants;
28 import org.eclipse.jgit.lib.Ref;
29 import org.eclipse.jgit.lib.RefUpdate;
30 import org.eclipse.jgit.lib.RefUpdate.Result;
31 import org.eclipse.jgit.lib.Repository;
32 import org.eclipse.jgit.lib.StoredConfig;
33 import org.eclipse.jgit.revwalk.RevCommit;
34 import org.eclipse.jgit.revwalk.RevWalk;
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 public class DeleteBranchCommand extends GitCommand<List<String>> {
50 private final Set<String> branchNames = new HashSet<>();
51
52 private boolean force;
53
54
55
56
57
58
59
60 protected DeleteBranchCommand(Repository repo) {
61 super(repo);
62 }
63
64
65 @Override
66 public List<String> call() throws GitAPIException,
67 NotMergedException, CannotDeleteCurrentBranchException {
68 checkCallable();
69 List<String> result = new ArrayList<>();
70 if (branchNames.isEmpty())
71 return result;
72 try {
73 String currentBranch = repo.getFullBranch();
74 if (!force) {
75
76
77 try (RevWalk walk = new RevWalk(repo)) {
78 RevCommit tip = walk
79 .parseCommit(repo.resolve(Constants.HEAD));
80 for (String branchName : branchNames) {
81 if (branchName == null)
82 continue;
83 Ref currentRef = repo.findRef(branchName);
84 if (currentRef == null)
85 continue;
86
87 RevCommit base = walk
88 .parseCommit(repo.resolve(branchName));
89 if (!walk.isMergedInto(base, tip)) {
90 throw new NotMergedException();
91 }
92 }
93 }
94 }
95 setCallable(false);
96 for (String branchName : branchNames) {
97 if (branchName == null)
98 continue;
99 Ref currentRef = repo.findRef(branchName);
100 if (currentRef == null)
101 continue;
102 String fullName = currentRef.getName();
103 if (fullName.equals(currentBranch))
104 throw new CannotDeleteCurrentBranchException(
105 MessageFormat
106 .format(
107 JGitText.get().cannotDeleteCheckedOutBranch,
108 branchName));
109 RefUpdate update = repo.updateRef(fullName);
110 update.setRefLogMessage("branch deleted", false);
111 update.setForceUpdate(true);
112 Result deleteResult = update.delete();
113
114 boolean ok = true;
115 switch (deleteResult) {
116 case IO_FAILURE:
117 case LOCK_FAILURE:
118 case REJECTED:
119 ok = false;
120 break;
121 default:
122 break;
123 }
124
125 if (ok) {
126 result.add(fullName);
127 if (fullName.startsWith(Constants.R_HEADS)) {
128 String shortenedName = fullName
129 .substring(Constants.R_HEADS.length());
130
131 final StoredConfig cfg = repo.getConfig();
132 cfg.unsetSection(
133 ConfigConstants.CONFIG_BRANCH_SECTION,
134 shortenedName);
135 cfg.save();
136 }
137 } else
138 throw new JGitInternalException(MessageFormat.format(
139 JGitText.get().deleteBranchUnexpectedResult,
140 deleteResult.name()));
141 }
142 return result;
143 } catch (IOException ioe) {
144 throw new JGitInternalException(ioe.getMessage(), ioe);
145 }
146 }
147
148
149
150
151
152
153
154
155
156 public DeleteBranchCommand setBranchNames(String... branchnames) {
157 checkCallable();
158 this.branchNames.clear();
159 this.branchNames.addAll(Arrays.asList(branchnames));
160 return this;
161 }
162
163
164
165
166
167
168
169
170
171
172
173
174 public DeleteBranchCommand setForce(boolean force) {
175 checkCallable();
176 this.force = force;
177 return this;
178 }
179 }