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