You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

GarbageCollectCommand.java 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /*
  2. * Copyright (C) 2012, Matthias Sohn <matthias.sohn@sap.com> and others
  3. *
  4. * This program and the accompanying materials are made available under the
  5. * terms of the Eclipse Distribution License v. 1.0 which is available at
  6. * https://www.eclipse.org/org/documents/edl-v10.php.
  7. *
  8. * SPDX-License-Identifier: BSD-3-Clause
  9. */
  10. package org.eclipse.jgit.api;
  11. import java.io.IOException;
  12. import java.text.MessageFormat;
  13. import java.text.ParseException;
  14. import java.util.Date;
  15. import java.util.Properties;
  16. import org.eclipse.jgit.api.errors.GitAPIException;
  17. import org.eclipse.jgit.api.errors.JGitInternalException;
  18. import org.eclipse.jgit.internal.JGitText;
  19. import org.eclipse.jgit.internal.storage.dfs.DfsGarbageCollector;
  20. import org.eclipse.jgit.internal.storage.dfs.DfsRepository;
  21. import org.eclipse.jgit.internal.storage.file.FileRepository;
  22. import org.eclipse.jgit.internal.storage.file.GC;
  23. import org.eclipse.jgit.internal.storage.file.GC.RepoStatistics;
  24. import org.eclipse.jgit.lib.ConfigConstants;
  25. import org.eclipse.jgit.lib.ProgressMonitor;
  26. import org.eclipse.jgit.lib.Repository;
  27. import org.eclipse.jgit.lib.StoredConfig;
  28. import org.eclipse.jgit.storage.pack.PackConfig;
  29. /**
  30. * A class used to execute a {@code gc} command. It has setters for all
  31. * supported options and arguments of this command and a {@link #call()} method
  32. * to finally execute the command. Each instance of this class should only be
  33. * used for one invocation of the command (means: one call to {@link #call()})
  34. *
  35. * @since 2.2
  36. * @see <a href="http://www.kernel.org/pub/software/scm/git/docs/git-gc.html"
  37. * >Git documentation about gc</a>
  38. */
  39. public class GarbageCollectCommand extends GitCommand<Properties> {
  40. /**
  41. * Default value of maximum delta chain depth during aggressive garbage
  42. * collection: {@value}
  43. *
  44. * @since 3.6
  45. */
  46. public static final int DEFAULT_GC_AGGRESSIVE_DEPTH = 250;
  47. /**
  48. * Default window size during packing during aggressive garbage collection:
  49. * * {@value}
  50. *
  51. * @since 3.6
  52. */
  53. public static final int DEFAULT_GC_AGGRESSIVE_WINDOW = 250;
  54. private ProgressMonitor monitor;
  55. private Date expire;
  56. private PackConfig pconfig;
  57. /**
  58. * Constructor for GarbageCollectCommand.
  59. *
  60. * @param repo
  61. * a {@link org.eclipse.jgit.lib.Repository} object.
  62. */
  63. protected GarbageCollectCommand(Repository repo) {
  64. super(repo);
  65. pconfig = new PackConfig(repo);
  66. }
  67. /**
  68. * Set progress monitor
  69. *
  70. * @param monitor
  71. * a progress monitor
  72. * @return this instance
  73. */
  74. public GarbageCollectCommand setProgressMonitor(ProgressMonitor monitor) {
  75. this.monitor = monitor;
  76. return this;
  77. }
  78. /**
  79. * During gc() or prune() each unreferenced, loose object which has been
  80. * created or modified after <code>expire</code> will not be pruned. Only
  81. * older objects may be pruned. If set to null then every object is a
  82. * candidate for pruning. Use {@link org.eclipse.jgit.util.GitDateParser} to
  83. * parse time formats used by git gc.
  84. *
  85. * @param expire
  86. * minimal age of objects to be pruned.
  87. * @return this instance
  88. */
  89. public GarbageCollectCommand setExpire(Date expire) {
  90. this.expire = expire;
  91. return this;
  92. }
  93. /**
  94. * Whether to use aggressive mode or not. If set to true JGit behaves more
  95. * similar to native git's "git gc --aggressive". If set to
  96. * <code>true</code> compressed objects found in old packs are not reused
  97. * but every object is compressed again. Configuration variables
  98. * pack.window and pack.depth are set to 250 for this GC.
  99. *
  100. * @since 3.6
  101. * @param aggressive
  102. * whether to turn on or off aggressive mode
  103. * @return this instance
  104. */
  105. public GarbageCollectCommand setAggressive(boolean aggressive) {
  106. if (aggressive) {
  107. StoredConfig repoConfig = repo.getConfig();
  108. pconfig.setDeltaSearchWindowSize(repoConfig.getInt(
  109. ConfigConstants.CONFIG_GC_SECTION,
  110. ConfigConstants.CONFIG_KEY_AGGRESSIVE_WINDOW,
  111. DEFAULT_GC_AGGRESSIVE_WINDOW));
  112. pconfig.setMaxDeltaDepth(repoConfig.getInt(
  113. ConfigConstants.CONFIG_GC_SECTION,
  114. ConfigConstants.CONFIG_KEY_AGGRESSIVE_DEPTH,
  115. DEFAULT_GC_AGGRESSIVE_DEPTH));
  116. pconfig.setReuseObjects(false);
  117. } else
  118. pconfig = new PackConfig(repo);
  119. return this;
  120. }
  121. /**
  122. * Whether to preserve old pack files instead of deleting them.
  123. *
  124. * @since 4.7
  125. * @param preserveOldPacks
  126. * whether to preserve old pack files
  127. * @return this instance
  128. */
  129. public GarbageCollectCommand setPreserveOldPacks(boolean preserveOldPacks) {
  130. if (pconfig == null)
  131. pconfig = new PackConfig(repo);
  132. pconfig.setPreserveOldPacks(preserveOldPacks);
  133. return this;
  134. }
  135. /**
  136. * Whether to prune preserved pack files in the preserved directory.
  137. *
  138. * @since 4.7
  139. * @param prunePreserved
  140. * whether to prune preserved pack files
  141. * @return this instance
  142. */
  143. public GarbageCollectCommand setPrunePreserved(boolean prunePreserved) {
  144. if (pconfig == null)
  145. pconfig = new PackConfig(repo);
  146. pconfig.setPrunePreserved(prunePreserved);
  147. return this;
  148. }
  149. /** {@inheritDoc} */
  150. @Override
  151. public Properties call() throws GitAPIException {
  152. checkCallable();
  153. try {
  154. if (repo instanceof FileRepository) {
  155. GC gc = new GC((FileRepository) repo);
  156. gc.setPackConfig(pconfig);
  157. gc.setProgressMonitor(monitor);
  158. if (this.expire != null)
  159. gc.setExpire(expire);
  160. try {
  161. gc.gc();
  162. return toProperties(gc.getStatistics());
  163. } catch (ParseException e) {
  164. throw new JGitInternalException(JGitText.get().gcFailed, e);
  165. }
  166. } else if (repo instanceof DfsRepository) {
  167. DfsGarbageCollector gc =
  168. new DfsGarbageCollector((DfsRepository) repo);
  169. gc.setPackConfig(pconfig);
  170. gc.pack(monitor);
  171. return new Properties();
  172. } else {
  173. throw new UnsupportedOperationException(MessageFormat.format(
  174. JGitText.get().unsupportedGC,
  175. repo.getClass().toString()));
  176. }
  177. } catch (IOException e) {
  178. throw new JGitInternalException(JGitText.get().gcFailed, e);
  179. }
  180. }
  181. /**
  182. * Computes and returns the repository statistics.
  183. *
  184. * @return the repository statistics
  185. * @throws org.eclipse.jgit.api.errors.GitAPIException
  186. * thrown if the repository statistics cannot be computed
  187. * @since 3.0
  188. */
  189. public Properties getStatistics() throws GitAPIException {
  190. try {
  191. if (repo instanceof FileRepository) {
  192. GC gc = new GC((FileRepository) repo);
  193. return toProperties(gc.getStatistics());
  194. }
  195. return new Properties();
  196. } catch (IOException e) {
  197. throw new JGitInternalException(
  198. JGitText.get().couldNotGetRepoStatistics, e);
  199. }
  200. }
  201. @SuppressWarnings("boxing")
  202. private static Properties toProperties(RepoStatistics stats) {
  203. Properties p = new Properties();
  204. p.put("numberOfLooseObjects", stats.numberOfLooseObjects); //$NON-NLS-1$
  205. p.put("numberOfLooseRefs", stats.numberOfLooseRefs); //$NON-NLS-1$
  206. p.put("numberOfPackedObjects", stats.numberOfPackedObjects); //$NON-NLS-1$
  207. p.put("numberOfPackedRefs", stats.numberOfPackedRefs); //$NON-NLS-1$
  208. p.put("numberOfPackFiles", stats.numberOfPackFiles); //$NON-NLS-1$
  209. p.put("sizeOfLooseObjects", stats.sizeOfLooseObjects); //$NON-NLS-1$
  210. p.put("sizeOfPackedObjects", stats.sizeOfPackedObjects); //$NON-NLS-1$
  211. return p;
  212. }
  213. }