Add pack options to preserve and prune old pack files

Add the options
- pack.preserveOldPacks
- pack.prunePreserved

This allows to configure in git config if old packs should be preserved
during gc and pruned during the next gc.

The original implementation in 91132bb0 only allows to set these options
using the API.

Change-Id: I5b23ab4f317d12f5ccd234401419913e8263cc9a
This commit is contained in:
Matthias Sohn 2023-02-10 21:05:47 +01:00
parent ed2cbd9e8a
commit 9424052f27
4 changed files with 34 additions and 8 deletions

View File

@ -100,8 +100,8 @@ Proxy configuration uses the standard Java mechanisms via class `java.net.ProxyS
| `pack.depth` | `50` | ✅ | Maximum depth of delta chain set up for the pack writer. |
| `pack.indexVersion` | `2` | ✅ | Pack index file format version. |
| `pack.minSizePreventRacyPack` | `100 MiB` | ⃞ | Minimum packfile size for which we wait before opening a newly written pack to prevent its lastModified timestamp could be racy if `pack.waitPreventRacyPack` is `true`. |
| `pack.preserveOldPacks` | `false` | ⃞ | Whether to preserve old packs in a preserved directory. |
| `prunePreserved`, only via API of PackConfig | `false` | ⃞ | Whether to remove preserved pack files in a preserved directory. |
| `pack.preserveOldPacks` | `false` | ⃞ | Whether to preserve old packs during gc in the `objects/pack/preserved` directory. This can avoid rare races between gc removing pack files and other concurrent operations. If this option is false data loss can occur in rare cases when an object is believed to be unreferenced when object repacking is running, and then garbage collection deletes it while another concurrent operation references this object shortly before garbage collection deletes it. When this happens, a new reference is created which points to a now missing object. |
| `pack.prunePreserved` | `false` | ⃞ | Whether to prune preserved pack files from the previous run of gc from the `objects/pack/preserved` directory. This helps to limit the additional storage space needed to preserve old packs when `pack.preserveOldPacks = true`. |
| `pack.reuseDeltas` | `true` |⃞ | Whether to reuse deltas existing in repository. |
| `pack.reuseObjects` | `true` | ⃞ | Whether to reuse existing objects representation in repository. |
| `pack.searchForReuseTimeout` | | ⃞ | Search for reuse phase timeout. Expressed as a `Duration`, i.e.: `50sec`. |

View File

@ -10,6 +10,7 @@
package org.eclipse.jgit.pgm;
import org.eclipse.jgit.api.GarbageCollectCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.TextProgressMonitor;
@ -21,20 +22,25 @@ class Gc extends TextBuiltin {
private boolean aggressive;
@Option(name = "--preserve-oldpacks", usage = "usage_PreserveOldPacks")
private boolean preserveOldPacks;
private Boolean preserveOldPacks;
@Option(name = "--prune-preserved", usage = "usage_PrunePreserved")
private boolean prunePreserved;
private Boolean prunePreserved;
/** {@inheritDoc} */
@Override
protected void run() {
Git git = Git.wrap(db);
try {
git.gc().setAggressive(aggressive)
.setPreserveOldPacks(preserveOldPacks)
.setPrunePreserved(prunePreserved)
.setProgressMonitor(new TextProgressMonitor(errw)).call();
GarbageCollectCommand command = git.gc().setAggressive(aggressive)
.setProgressMonitor(new TextProgressMonitor(errw));
if (preserveOldPacks != null) {
command.setPreserveOldPacks(preserveOldPacks.booleanValue());
}
if (prunePreserved != null) {
command.setPrunePreserved(prunePreserved.booleanValue());
}
command.call();
} catch (GitAPIException e) {
throw die(e.getMessage(), e);
}

View File

@ -771,4 +771,18 @@ public final class ConfigConstants {
*/
public static final String CONFIG_KEY_SEARCH_FOR_REUSE_TIMEOUT = "searchforreusetimeout";
/**
* The "pack.preserveOldPacks" key
*
* @since 5.13.2
*/
public static final String CONFIG_KEY_PRESERVE_OLD_PACKS = "preserveoldpacks";
/**
* The "pack.prunePreserved" key
*
* @since 5.13.2
*/
public static final String CONFIG_KEY_PRUNE_PRESERVED = "prunepreserved";
}

View File

@ -37,6 +37,8 @@
import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_WINDOW;
import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_WINDOW_MEMORY;
import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_PACK_SECTION;
import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_PRESERVE_OLD_PACKS;
import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_PRUNE_PRESERVED;
import java.time.Duration;
import java.util.concurrent.Executor;
@ -1267,6 +1269,10 @@ public void fromConfig(Config rc) {
setMinSizePreventRacyPack(rc.getLong(CONFIG_PACK_SECTION,
CONFIG_KEY_MIN_SIZE_PREVENT_RACYPACK,
getMinSizePreventRacyPack()));
setPreserveOldPacks(rc.getBoolean(CONFIG_PACK_SECTION,
CONFIG_KEY_PRESERVE_OLD_PACKS, DEFAULT_PRESERVE_OLD_PACKS));
setPrunePreserved(rc.getBoolean(CONFIG_PACK_SECTION,
CONFIG_KEY_PRUNE_PRESERVED, DEFAULT_PRUNE_PRESERVED));
}
/** {@inheritDoc} */