1
2
3
4
5
6
7
8
9
10 package org.eclipse.jgit.api;
11
12 import java.io.File;
13 import java.io.IOException;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.LinkedList;
17 import java.util.List;
18
19 import org.eclipse.jgit.api.errors.GitAPIException;
20 import org.eclipse.jgit.api.errors.JGitInternalException;
21 import org.eclipse.jgit.api.errors.NoFilepatternException;
22 import org.eclipse.jgit.dircache.DirCache;
23 import org.eclipse.jgit.dircache.DirCacheBuildIterator;
24 import org.eclipse.jgit.dircache.DirCacheBuilder;
25 import org.eclipse.jgit.events.WorkingTreeModifiedEvent;
26 import org.eclipse.jgit.internal.JGitText;
27 import org.eclipse.jgit.lib.Constants;
28 import org.eclipse.jgit.lib.FileMode;
29 import org.eclipse.jgit.lib.Repository;
30 import org.eclipse.jgit.treewalk.TreeWalk;
31 import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 public class RmCommand extends GitCommand<DirCache> {
60
61 private Collection<String> filepatterns;
62
63
64 private boolean cached = false;
65
66
67
68
69
70
71
72 public RmCommand(Repository repo) {
73 super(repo);
74 filepatterns = new LinkedList<>();
75 }
76
77
78
79
80
81
82
83
84
85 public RmCommand addFilepattern(String filepattern) {
86 checkCallable();
87 filepatterns.add(filepattern);
88 return this;
89 }
90
91
92
93
94
95
96
97
98
99
100
101 public RmCommand setCached(boolean cached) {
102 checkCallable();
103 this.cached = cached;
104 return this;
105 }
106
107
108
109
110
111
112
113
114 @Override
115 public DirCache call() throws GitAPIException,
116 NoFilepatternException {
117
118 if (filepatterns.isEmpty())
119 throw new NoFilepatternException(JGitText.get().atLeastOnePatternIsRequired);
120 checkCallable();
121 DirCache dc = null;
122
123 List<String> actuallyDeletedFiles = new ArrayList<>();
124 try (TreeWalk tw = new TreeWalk(repo)) {
125 dc = repo.lockDirCache();
126 DirCacheBuilder builder = dc.builder();
127 tw.reset();
128 tw.setRecursive(true);
129 tw.setFilter(PathFilterGroup.createFromStrings(filepatterns));
130 tw.addTree(new DirCacheBuildIterator(builder));
131
132 while (tw.next()) {
133 if (!cached) {
134 final FileMode mode = tw.getFileMode(0);
135 if (mode.getObjectType() == Constants.OBJ_BLOB) {
136 String relativePath = tw.getPathString();
137 final File path = new File(repo.getWorkTree(),
138 relativePath);
139
140
141 if (delete(path)) {
142 actuallyDeletedFiles.add(relativePath);
143 }
144 }
145 }
146 }
147 builder.commit();
148 setCallable(false);
149 } catch (IOException e) {
150 throw new JGitInternalException(
151 JGitText.get().exceptionCaughtDuringExecutionOfRmCommand, e);
152 } finally {
153 try {
154 if (dc != null) {
155 dc.unlock();
156 }
157 } finally {
158 if (!actuallyDeletedFiles.isEmpty()) {
159 repo.fireEvent(new WorkingTreeModifiedEvent(null,
160 actuallyDeletedFiles));
161 }
162 }
163 }
164
165 return dc;
166 }
167
168 private boolean delete(File p) {
169 boolean deleted = false;
170 while (p != null && !p.equals(repo.getWorkTree()) && p.delete()) {
171 deleted = true;
172 p = p.getParentFile();
173 }
174 return deleted;
175 }
176
177 }