diff --git a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/CLIText.properties b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/CLIText.properties index e879d6b60..2fff6d463 100644 --- a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/CLIText.properties +++ b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/CLIText.properties @@ -14,6 +14,7 @@ branchCreatedFrom =branch: Created from {0} branchIsNotAnAncestorOfYourCurrentHEAD=The branch '{0}' is not an ancestor of your current HEAD.\nIf you are sure you want to delete it, run 'jgit branch -D {0}'. branchNotFound=branch '{0}' not found. cacheTreePathInfo="{0}": {1} entries, {2} children +configFileNotFound=configuration file {0} not found cannotBeRenamed={0} cannot be renamed cannotChekoutNoHeadsAdvertisedByRemote=cannot checkout; no HEAD advertised by remote cannotCreateCommand=Cannot create command {0} @@ -61,6 +62,7 @@ metaVar_bucket=BUCKET metaVar_command=command metaVar_commitOrTag=COMMIT|TAG metaVar_commitish=commit-ish +metaVar_configFile=FILE metaVar_connProp=conn.prop metaVar_directory=DIRECTORY metaVar_file=FILE @@ -138,6 +140,7 @@ usage_approveDestructionOfRepository=approve destruction of repository usage_beMoreVerbose=be more verbose usage_beVerbose=be verbose usage_cloneRepositoryIntoNewDir=Clone a repository into a new directory +usage_configFile=configuration file usage_configureTheServiceInDaemonServicename=configure the service in daemon.servicename usage_deleteBranchEvenIfNotMerged=delete branch (even if not merged) usage_deleteFullyMergedBranch=delete fully merged branch diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CLIText.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CLIText.java index bae895cc7..14dcb1f50 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CLIText.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CLIText.java @@ -67,6 +67,7 @@ public static CLIText get() { /***/ public String branchIsNotAnAncestorOfYourCurrentHEAD; /***/ public String branchNotFound; /***/ public String cacheTreePathInfo; + /***/ public String configFileNotFound; /***/ public String cannotBeRenamed; /***/ public String cannotChekoutNoHeadsAdvertisedByRemote; /***/ public String cannotCreateCommand; diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java index f015a9e7b..3cca87abe 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java @@ -48,13 +48,22 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.Executors; +import org.eclipse.jgit.storage.file.FileBasedConfig; +import org.eclipse.jgit.storage.file.WindowCache; +import org.eclipse.jgit.storage.file.WindowCacheConfig; +import org.eclipse.jgit.storage.pack.PackConfig; +import org.eclipse.jgit.transport.DaemonService; +import org.eclipse.jgit.util.FS; import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.Option; -import org.eclipse.jgit.transport.DaemonService; @Command(common = true, usage = "usage_exportRepositoriesOverGit") class Daemon extends TextBuiltin { + @Option(name = "--config-file", metaVar = "metaVar_configFile", usage = "usage_configFile") + File configFile; + @Option(name = "--port", metaVar = "metaVar_port", usage = "usage_portNumberToListenOn") int port = org.eclipse.jgit.transport.Daemon.DEFAULT_PORT; @@ -89,12 +98,38 @@ protected boolean requiresRepository() { @Override protected void run() throws Exception { + PackConfig packConfig = new PackConfig(); + + if (configFile != null) { + if (!configFile.exists()) { + throw die(MessageFormat.format( + CLIText.get().configFileNotFound, // + configFile.getAbsolutePath())); + } + + FileBasedConfig cfg = new FileBasedConfig(configFile, FS.DETECTED); + cfg.load(); + + WindowCacheConfig wcc = new WindowCacheConfig(); + wcc.fromConfig(cfg); + WindowCache.reconfigure(wcc); + + packConfig.fromConfig(cfg); + } + + int threads = packConfig.getThreads(); + if (threads <= 0) + threads = Runtime.getRuntime().availableProcessors(); + if (1 < threads) + packConfig.setExecutor(Executors.newFixedThreadPool(threads)); + final org.eclipse.jgit.transport.Daemon d; d = new org.eclipse.jgit.transport.Daemon( host != null ? new InetSocketAddress(host, port) : new InetSocketAddress(port)); d.setExportAll(exportAll); + d.setPackConfig(packConfig); if (0 <= timeout) d.setTimeout(timeout); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java index 297105d46..0838f29c1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java @@ -231,7 +231,8 @@ private void writePack(final Map refUpdates, List newObjects = new ArrayList(refUpdates.size()); final long start; - final PackWriter writer = new PackWriter(local); + final PackWriter writer = new PackWriter(transport.getPackConfig(), + local.newObjectReader()); try { for (final Ref r : getRefs()) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleWriter.java index 79fa58c36..b513412da 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleWriter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleWriter.java @@ -61,6 +61,7 @@ import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.storage.pack.PackConfig; import org.eclipse.jgit.storage.pack.PackWriter; /** @@ -81,12 +82,14 @@ * overall bundle size. */ public class BundleWriter { - private final PackWriter packWriter; + private final Repository db; private final Map include; private final Set assume; + private PackConfig packConfig; + /** * Create a writer for a bundle. * @@ -94,11 +97,22 @@ public class BundleWriter { * repository where objects are stored. */ public BundleWriter(final Repository repo) { - packWriter = new PackWriter(repo); + db = repo; include = new TreeMap(); assume = new HashSet(); } + /** + * Set the configuration used by the pack generator. + * + * @param pc + * configuration controlling packing parameters. If null the + * source repository's settings will be used. + */ + public void setPackConfig(PackConfig pc) { + this.packConfig = pc; + } + /** * Include an object (and everything reachable from it) in the bundle. * @@ -166,6 +180,10 @@ public void assume(final RevCommit c) { */ public void writeBundle(ProgressMonitor monitor, OutputStream os) throws IOException { + PackConfig pc = packConfig; + if (pc == null) + pc = new PackConfig(db); + PackWriter packWriter = new PackWriter(pc, db.newObjectReader()); try { final HashSet inc = new HashSet(); final HashSet exc = new HashSet(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java index aa2e2521c..0bc5fb3a2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java @@ -63,6 +63,7 @@ import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.RepositoryCache; import org.eclipse.jgit.lib.RepositoryCache.FileKey; +import org.eclipse.jgit.storage.pack.PackConfig; import org.eclipse.jgit.util.FS; /** Basic daemon for the anonymous git:// transport protocol. */ @@ -90,6 +91,8 @@ public class Daemon { private int timeout; + private PackConfig packConfig; + /** Configure a daemon to listen on any available network port. */ public Daemon() { this(null); @@ -120,6 +123,7 @@ protected void execute(final DaemonClient dc, final UploadPack rp = new UploadPack(db); final InputStream in = dc.getInputStream(); rp.setTimeout(Daemon.this.getTimeout()); + rp.setPackConfig(Daemon.this.packConfig); rp.upload(in, dc.getOutputStream(), null); } }, new DaemonService("receive-pack", "receivepack") { @@ -242,6 +246,17 @@ public void setTimeout(final int seconds) { timeout = seconds; } + /** + * Set the configuration used by the pack generator. + * + * @param pc + * configuration controlling packing parameters. If null the + * source repository's settings will be used. + */ + public void setPackConfig(PackConfig pc) { + this.packConfig = pc; + } + /** * Start this daemon on a background thread. * diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java index a8e47afd3..500cf0cff 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java @@ -66,6 +66,7 @@ import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.TransferConfig; +import org.eclipse.jgit.storage.pack.PackConfig; import org.eclipse.jgit.util.FS; /** @@ -554,6 +555,9 @@ private static String findTrackingRefName(final String remoteName, /** Timeout in seconds to wait before aborting an IO read or write. */ private int timeout; + /** Pack configuration used by this transport to make pack file. */ + private PackConfig packConfig; + /** * Create a new transport instance. * @@ -791,6 +795,32 @@ public void setTimeout(final int seconds) { timeout = seconds; } + /** + * Get the configuration used by the pack generator to make packs. + * + * If {@link #setPackConfig(PackConfig)} was previously given null a new + * PackConfig is created on demand by this method using the source + * repository's settings. + * + * @return the pack configuration. Never null. + */ + public PackConfig getPackConfig() { + if (packConfig == null) + packConfig = new PackConfig(local); + return packConfig; + } + + /** + * Set the configuration used by the pack generator. + * + * @param pc + * configuration controlling packing parameters. If null the + * source repository's settings will be used. + */ + public void setPackConfig(PackConfig pc) { + packConfig = pc; + } + /** * Fetch objects and refs from the remote repository to the local one. *

diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java index e7338598c..16d56df66 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java @@ -69,6 +69,7 @@ import org.eclipse.jgit.revwalk.RevObject; import org.eclipse.jgit.revwalk.RevTag; import org.eclipse.jgit.revwalk.RevWalk; +import org.eclipse.jgit.storage.pack.PackConfig; import org.eclipse.jgit.storage.pack.PackWriter; import org.eclipse.jgit.transport.BasePackFetchConnection.MultiAck; import org.eclipse.jgit.transport.RefAdvertiser.PacketLineOutRefAdvertiser; @@ -102,6 +103,9 @@ public class UploadPack { /** Revision traversal support over {@link #db}. */ private final RevWalk walk; + /** Configuration to pass into the PackWriter. */ + private PackConfig packConfig; + /** Timeout in seconds to wait for client interaction. */ private int timeout; @@ -258,6 +262,17 @@ public void setRefFilter(final RefFilter refFilter) { this.refFilter = refFilter != null ? refFilter : RefFilter.DEFAULT; } + /** + * Set the configuration used by the pack generator. + * + * @param pc + * configuration controlling packing parameters. If null the + * source repository's settings will be used. + */ + public void setPackConfig(PackConfig pc) { + this.packConfig = pc; + } + /** * Execute the upload task on the socket. * @@ -566,7 +581,10 @@ private void sendPack() throws IOException { SideBandOutputStream.CH_PROGRESS, bufsz, rawOut)); } - final PackWriter pw = new PackWriter(db, walk.getObjectReader()); + PackConfig cfg = packConfig; + if (cfg == null) + cfg = new PackConfig(db); + final PackWriter pw = new PackWriter(cfg, walk.getObjectReader()); try { pw.setDeltaBaseAsOffset(options.contains(OPTION_OFS_DELTA)); pw.setThin(options.contains(OPTION_THIN_PACK)); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java index bbc918f25..9ce0ec1b3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java @@ -103,6 +103,9 @@ class WalkPushConnection extends BaseConnection implements PushConnection { /** Database connection to the remote repository. */ private final WalkRemoteObjectDatabase dest; + /** The configured transport we were constructed by. */ + private final Transport transport; + /** * Packs already known to reside in the remote repository. *

@@ -123,9 +126,9 @@ class WalkPushConnection extends BaseConnection implements PushConnection { WalkPushConnection(final WalkTransport walkTransport, final WalkRemoteObjectDatabase w) { - Transport t = (Transport)walkTransport; - local = t.local; - uri = t.getURI(); + transport = (Transport) walkTransport; + local = transport.local; + uri = transport.getURI(); dest = w; } @@ -209,7 +212,8 @@ private void sendpack(final List updates, String pathPack = null; String pathIdx = null; - final PackWriter pw = new PackWriter(local); + final PackWriter writer = new PackWriter(transport.getPackConfig(), + local.newObjectReader()); try { final List need = new ArrayList(); final List have = new ArrayList(); @@ -220,20 +224,20 @@ private void sendpack(final List updates, if (r.getPeeledObjectId() != null) have.add(r.getPeeledObjectId()); } - pw.preparePack(monitor, need, have); + writer.preparePack(monitor, need, have); // We don't have to continue further if the pack will // be an empty pack, as the remote has all objects it // needs to complete this change. // - if (pw.getObjectsNumber() == 0) + if (writer.getObjectsNumber() == 0) return; packNames = new LinkedHashMap(); for (final String n : dest.getPackNames()) packNames.put(n, n); - final String base = "pack-" + pw.computeName().name(); + final String base = "pack-" + writer.computeName().name(); final String packName = base + ".pack"; pathPack = "pack/" + packName; pathIdx = "pack/" + base + ".idx"; @@ -254,7 +258,7 @@ private void sendpack(final List updates, OutputStream os = dest.writeFile(pathPack, monitor, wt + "..pack"); try { os = new BufferedOutputStream(os); - pw.writePack(monitor, monitor, os); + writer.writePack(monitor, monitor, os); } finally { os.close(); } @@ -262,7 +266,7 @@ private void sendpack(final List updates, os = dest.writeFile(pathIdx, monitor, wt + "..idx"); try { os = new BufferedOutputStream(os); - pw.writeIndex(os); + writer.writeIndex(os); } finally { os.close(); } @@ -282,7 +286,7 @@ private void sendpack(final List updates, throw new TransportException(uri, JGitText.get().cannotStoreObjects, err); } finally { - pw.release(); + writer.release(); } }