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.test/tst/org/eclipse/jgit/storage/file/PackWriterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/PackWriterTest.java
index 9e663d7b4..5685ccac6 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/PackWriterTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/PackWriterTest.java
@@ -66,6 +66,7 @@
import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.storage.file.PackIndex.MutableEntry;
+import org.eclipse.jgit.storage.pack.PackConfig;
import org.eclipse.jgit.storage.pack.PackWriter;
import org.eclipse.jgit.transport.IndexPack;
import org.eclipse.jgit.util.JGitTestUtil;
@@ -78,6 +79,8 @@ public class PackWriterTest extends SampleDataRepositoryTestCase {
private static final List
+ * Objects for packing are specified in {@link #preparePack(Iterator)} or + * {@link #preparePack(ProgressMonitor, Collection, Collection)}. + * + * @param config + * configuration for the pack writer. + * @param reader + * reader to read from the repository with. + */ + public PackWriter(final PackConfig config, final ObjectReader reader) { + this.config = config; this.reader = reader; if (reader instanceof ObjectReuseAsIs) reuseSupport = ((ObjectReuseAsIs) reader); else reuseSupport = null; - final PackConfig pc = configOf(repo).get(PackConfig.KEY); - deltaSearchWindowSize = pc.deltaWindow; - deltaSearchMemoryLimit = pc.deltaWindowMemory; - deltaCacheSize = pc.deltaCacheSize; - deltaCacheLimit = pc.deltaCacheLimit; - maxDeltaDepth = pc.deltaDepth; - compressionLevel = pc.compression; - indexVersion = pc.indexVersion; - bigFileThreshold = pc.bigFileThreshold; - threads = pc.threads; - } - - private static Config configOf(final Repository repo) { - if (repo == null) - return new Config(); - return repo.getConfig(); - } - - /** - * Check whether object is configured to reuse deltas existing in - * repository. - *
- * Default setting: {@link #DEFAULT_REUSE_DELTAS} - *
- * - * @return true if object is configured to reuse deltas; false otherwise. - */ - public boolean isReuseDeltas() { - return reuseDeltas; - } - - /** - * Set reuse deltas configuration option for this writer. When enabled, - * writer will search for delta representation of object in repository and - * use it if possible. Normally, only deltas with base to another object - * existing in set of objects to pack will be used. Exception is however - * thin-pack (see - * {@link #preparePack(ProgressMonitor, Collection, Collection)} and - * {@link #preparePack(Iterator)}) where base object must exist on other - * side machine. - *- * When raw delta data is directly copied from a pack file, checksum is - * computed to verify data. - *
- *- * Default setting: {@link #DEFAULT_REUSE_DELTAS} - *
- * - * @param reuseDeltas - * boolean indicating whether or not try to reuse deltas. - */ - public void setReuseDeltas(boolean reuseDeltas) { - this.reuseDeltas = reuseDeltas; - } - - /** - * Checks whether object is configured to reuse existing objects - * representation in repository. - *- * Default setting: {@link #DEFAULT_REUSE_OBJECTS} - *
- * - * @return true if writer is configured to reuse objects representation from - * pack; false otherwise. - */ - public boolean isReuseObjects() { - return reuseObjects; - } - - /** - * Set reuse objects configuration option for this writer. If enabled, - * writer searches for representation in a pack file. If possible, - * compressed data is directly copied from such a pack file. Data checksum - * is verified. - *- * Default setting: {@link #DEFAULT_REUSE_OBJECTS} - *
- * - * @param reuseObjects - * boolean indicating whether or not writer should reuse existing - * objects representation. - */ - public void setReuseObjects(boolean reuseObjects) { - this.reuseObjects = reuseObjects; + deltaBaseAsOffset = config.isDeltaBaseAsOffset(); + reuseDeltas = config.isReuseDeltas(); } /** * Check whether writer can store delta base as an offset (new style * reducing pack size) or should store it as an object id (legacy style, * compatible with old readers). - *- * Default setting: {@link #DEFAULT_DELTA_BASE_AS_OFFSET} - *
+ * + * Default setting: {@value PackConfig#DEFAULT_DELTA_BASE_AS_OFFSET} * * @return true if delta base is stored as an offset; false if it is stored * as an object id. @@ -371,9 +246,8 @@ public boolean isDeltaBaseAsOffset() { * Set writer delta base format. Delta base can be written as an offset in a * pack file (new approach reducing file size) or as an object id (legacy * approach, compatible with old readers). - *- * Default setting: {@link #DEFAULT_DELTA_BASE_AS_OFFSET} - *
+ * + * Default setting: {@value PackConfig#DEFAULT_DELTA_BASE_AS_OFFSET} * * @param deltaBaseAsOffset * boolean indicating whether delta base can be stored as an @@ -383,235 +257,6 @@ public void setDeltaBaseAsOffset(boolean deltaBaseAsOffset) { this.deltaBaseAsOffset = deltaBaseAsOffset; } - /** - * Check whether the writer will create new deltas on the fly. - *- * Default setting: true - *
- * - * @return true if the writer will create a new delta when either - * {@link #isReuseDeltas()} is false, or no suitable delta is - * available for reuse. - */ - public boolean isDeltaCompress() { - return deltaCompress; - } - - /** - * Set whether or not the writer will create new deltas on the fly. - * - * @param deltaCompress - * true to create deltas when {@link #isReuseDeltas()} is false, - * or when a suitable delta isn't available for reuse. Set to - * false to write whole objects instead. - */ - public void setDeltaCompress(boolean deltaCompress) { - this.deltaCompress = deltaCompress; - } - - /** - * Get maximum depth of delta chain set up for this writer. Generated chains - * are not longer than this value. - *- * Default setting: {@link #DEFAULT_MAX_DELTA_DEPTH} - *
- * - * @return maximum delta chain depth. - */ - public int getMaxDeltaDepth() { - return maxDeltaDepth; - } - - /** - * Set up maximum depth of delta chain for this writer. Generated chains are - * not longer than this value. Too low value causes low compression level, - * while too big makes unpacking (reading) longer. - *- * Default setting: {@link #DEFAULT_MAX_DELTA_DEPTH} - *
- * - * @param maxDeltaDepth - * maximum delta chain depth. - */ - public void setMaxDeltaDepth(int maxDeltaDepth) { - this.maxDeltaDepth = maxDeltaDepth; - } - - /** - * Get the number of objects to try when looking for a delta base. - *- * This limit is per thread, if 4 threads are used the actual memory - * used will be 4 times this value. - * - * @return the object count to be searched. - */ - public int getDeltaSearchWindowSize() { - return deltaSearchWindowSize; - } - - /** - * Set the number of objects considered when searching for a delta base. - *
- * Default setting: {@link #DEFAULT_DELTA_SEARCH_WINDOW_SIZE} - *
- * - * @param objectCount - * number of objects to search at once. Must be at least 2. - */ - public void setDeltaSearchWindowSize(int objectCount) { - if (objectCount <= 2) - setDeltaCompress(false); - else - deltaSearchWindowSize = objectCount; - } - - /** - * Get maximum number of bytes to put into the delta search window. - *- * Default setting is 0, for an unlimited amount of memory usage. Actual - * memory used is the lower limit of either this setting, or the sum of - * space used by at most {@link #getDeltaSearchWindowSize()} objects. - *
- * This limit is per thread, if 4 threads are used the actual memory - * limit will be 4 times this value. - * - * @return the memory limit. - */ - public long getDeltaSearchMemoryLimit() { - return deltaSearchMemoryLimit; - } - - /** - * Set the maximum number of bytes to put into the delta search window. - *
- * Default setting is 0, for an unlimited amount of memory usage. If the - * memory limit is reached before {@link #getDeltaSearchWindowSize()} the - * window size is temporarily lowered. - * - * @param memoryLimit - * Maximum number of bytes to load at once, 0 for unlimited. - */ - public void setDeltaSearchMemoryLimit(long memoryLimit) { - deltaSearchMemoryLimit = memoryLimit; - } - - /** - * Get the size of the in-memory delta cache. - *
- * This limit is for the entire writer, even if multiple threads are used. - * - * @return maximum number of bytes worth of delta data to cache in memory. - * If 0 the cache is infinite in size (up to the JVM heap limit - * anyway). A very tiny size such as 1 indicates the cache is - * effectively disabled. - */ - public long getDeltaCacheSize() { - return deltaCacheSize; - } - - /** - * Set the maximum number of bytes of delta data to cache. - *
- * During delta search, up to this many bytes worth of small or hard to - * compute deltas will be stored in memory. This cache speeds up writing by - * allowing the cached entry to simply be dumped to the output stream. - * - * @param size - * number of bytes to cache. Set to 0 to enable an infinite - * cache, set to 1 (an impossible size for any delta) to disable - * the cache. - */ - public void setDeltaCacheSize(long size) { - deltaCacheSize = size; - } - - /** - * Maximum size in bytes of a delta to cache. - * - * @return maximum size (in bytes) of a delta that should be cached. - */ - public int getDeltaCacheLimit() { - return deltaCacheLimit; - } - - /** - * Set the maximum size of a delta that should be cached. - *
- * During delta search, any delta smaller than this size will be cached, up - * to the {@link #getDeltaCacheSize()} maximum limit. This speeds up writing - * by allowing these cached deltas to be output as-is. - * - * @param size - * maximum size (in bytes) of a delta to be cached. - */ - public void setDeltaCacheLimit(int size) { - deltaCacheLimit = size; - } - - /** - * Get the maximum file size that will be delta compressed. - *
- * Files bigger than this setting will not be delta compressed, as they are - * more than likely already highly compressed binary data files that do not - * delta compress well, such as MPEG videos. - * - * @return the configured big file threshold. - */ - public long getBigFileThreshold() { - return bigFileThreshold; - } - - /** - * Set the maximum file size that should be considered for deltas. - * - * @param bigFileThreshold - * the limit, in bytes. - */ - public void setBigFileThreshold(long bigFileThreshold) { - this.bigFileThreshold = bigFileThreshold; - } - - /** - * Get the compression level applied to objects in the pack. - * - * @return current compression level, see {@link java.util.zip.Deflater}. - */ - public int getCompressionLevel() { - return compressionLevel; - } - - /** - * Set the compression level applied to objects in the pack. - * - * @param level - * compression level, must be a valid level recognized by the - * {@link java.util.zip.Deflater} class. Typically this setting - * is {@link java.util.zip.Deflater#BEST_SPEED}. - */ - public void setCompressionLevel(int level) { - compressionLevel = level; - } - - /** @return number of threads used for delta compression. */ - public int getThreads() { - return threads; - } - - /** - * Set the number of threads to use for delta compression. - *
- * During delta compression, if there are enough objects to be considered
- * the writer will start up concurrent threads and allow them to compress
- * different sections of the repository concurrently.
- *
- * @param threads
- * number of threads to use. If <= 0 the number of available
- * processors for this JVM is used.
- */
- public void setThread(int threads) {
- this.threads = threads;
- }
-
/** @return true if this writer is producing a thin pack. */
public boolean isThin() {
return thin;
@@ -651,18 +296,6 @@ public void setIgnoreMissingUninteresting(final boolean ignore) {
ignoreMissingUninteresting = ignore;
}
- /**
- * Set the pack index file format version this instance will create.
- *
- * @param version
- * the version to write. The special version 0 designates the
- * oldest (most compatible) format available for the objects.
- * @see PackIndexWriter
- */
- public void setIndexVersion(final int version) {
- indexVersion = version;
- }
-
/**
* Returns objects number in a pack file that was created by this writer.
*
@@ -791,6 +424,7 @@ public ObjectId computeName() {
public void writeIndex(final OutputStream indexStream) throws IOException {
final List
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 02ce251be..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.
*
@@ -548,8 +563,6 @@ private boolean wantSatisfied(final RevCommit want) throws IOException {
}
private void sendPack() throws IOException {
- final boolean thin = options.contains(OPTION_THIN_PACK);
- final boolean progress = !options.contains(OPTION_NO_PROGRESS);
final boolean sideband = options.contains(OPTION_SIDE_BAND)
|| options.contains(OPTION_SIDE_BAND_64K);
@@ -563,15 +576,18 @@ private void sendPack() throws IOException {
packOut = new SideBandOutputStream(SideBandOutputStream.CH_DATA,
bufsz, rawOut);
- if (progress)
+ if (!options.contains(OPTION_NO_PROGRESS))
pm = new SideBandProgressMonitor(new SideBandOutputStream(
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(thin);
+ pw.setThin(options.contains(OPTION_THIN_PACK));
pw.preparePack(pm, wantAll, commonBase);
if (options.contains(OPTION_INCLUDE_TAG)) {
for (final Ref r : refs.values()) {
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 Listgit://
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.
*