aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.lfs
diff options
context:
space:
mode:
authorMatthias Sohn <matthias.sohn@sap.com>2022-03-08 17:23:57 +0100
committerMatthias Sohn <matthias.sohn@sap.com>2022-03-09 21:45:35 +0100
commit338f2adf160fdd72ee137e416174526d5c35eb18 (patch)
tree2d55def305066a654c46e335ed840bda6fef1bea /org.eclipse.jgit.lfs
parent600e96dfdc6769b7da6e2b2daea74cf69791da7a (diff)
parent8f7ef245f0c156730ef74ff3fe838c330728fc7f (diff)
downloadjgit-338f2adf160fdd72ee137e416174526d5c35eb18.tar.gz
jgit-338f2adf160fdd72ee137e416174526d5c35eb18.zip
Merge branch 'stable-6.1'
* stable-6.1: Prepare 6.1.1-SNAPSHOT builds JGit v6.1.0.202203080745-r [checkout] Use .gitattributes from the commit to be checked out Don't use final for method parameters [push] support the "matching" RefSpecs ":" and "+:" [push] Call the pre-push hook later in the push process IndexDiff: use tree filter also for SubmoduleWalk Run license check with option -Ddash.projectId=technology.jgit Exclude transitive dependencies of sshd-sftp Update DEPENDENCIES for 6.1.0 release Add dependency to dash-licenses Fix typos of some keys in LfsText Sort LfsText entries alphabetically Support for "lfs.url" from ".lfsconfig" Change-Id: I1b9f0c0ed647837e00b9640d235dbfab2329c5a6
Diffstat (limited to 'org.eclipse.jgit.lfs')
-rw-r--r--org.eclipse.jgit.lfs/resources/org/eclipse/jgit/lfs/internal/LfsText.properties18
-rw-r--r--org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/SmudgeFilter.java2
-rw-r--r--org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/LfsUnauthorized.java2
-rw-r--r--org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsConfig.java200
-rw-r--r--org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsConnectionFactory.java16
-rw-r--r--org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsText.java15
-rw-r--r--org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/Constants.java7
7 files changed, 234 insertions, 26 deletions
diff --git a/org.eclipse.jgit.lfs/resources/org/eclipse/jgit/lfs/internal/LfsText.properties b/org.eclipse.jgit.lfs/resources/org/eclipse/jgit/lfs/internal/LfsText.properties
index 0e00f146ae..642b83db44 100644
--- a/org.eclipse.jgit.lfs/resources/org/eclipse/jgit/lfs/internal/LfsText.properties
+++ b/org.eclipse.jgit.lfs/resources/org/eclipse/jgit/lfs/internal/LfsText.properties
@@ -1,19 +1,19 @@
corruptLongObject=The content hash ''{0}'' of the long object ''{1}'' doesn''t match its id, the corrupt object will be deleted.
-incorrectLONG_OBJECT_ID_LENGTH=Incorrect LONG_OBJECT_ID_LENGTH.
-inconsistentMediafileLength=Mediafile {0} has unexpected length; expected {1} but found {2}.
+dotLfsConfigReadFailed=Reading .lfsconfig failed
inconsistentContentLength=Unexpected content length reported by LFS server ({0}), expected {1} but reported was {2}
+inconsistentMediafileLength=Mediafile {0} has unexpected length; expected {1} but found {2}.
+incorrectLONG_OBJECT_ID_LENGTH=Incorrect LONG_OBJECT_ID_LENGTH.
invalidLongId=Invalid id: {0}
invalidLongIdLength=Invalid id length {0}; should be {1}
+lfsFailedToGetRepository=failed to get repository {0}
+lfsNoDownloadUrl="Need to download object from LFS server but couldn't determine LFS server URL"
+lfsUnauthorized=Not authorized to perform operation {0} on repository {1}
lfsUnavailable=LFS is not available for repository {0}
+missingLocalObject="Local Object {0} is missing"
protocolError=LFS Protocol Error {0}: {1}
-requiredHashFunctionNotAvailable=Required hash function {0} not available.
repositoryNotFound=Repository {0} not found
repositoryReadOnly=Repository {0} is read-only
-lfsUnavailable=LFS is not available for repository {0}
-lfsUnathorized=Not authorized to perform operation {0} on repository {1}
-lfsFailedToGetRepository=failed to get repository {0}
-lfsNoDownloadUrl="Need to download object from LFS server but couldn't determine LFS server URL"
+requiredHashFunctionNotAvailable=Required hash function {0} not available.
serverFailure=When trying to open a connection to {0} the server responded with an error code. rc={1}
-wrongAmoutOfDataReceived=While downloading data from the content server {0} {1} bytes have been received while {2} have been expected
userConfigInvalid="User config file {0} invalid {1}"
-missingLocalObject="Local Object {0} is missing" \ No newline at end of file
+wrongAmountOfDataReceived=While downloading data from the content server {0} {1} bytes have been received while {2} have been expected \ No newline at end of file
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/SmudgeFilter.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/SmudgeFilter.java
index 3411887567..c26a1bfbb3 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/SmudgeFilter.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/SmudgeFilter.java
@@ -205,7 +205,7 @@ public class SmudgeFilter extends FilterCommand {
long bytesCopied = Files.copy(contentIn, path);
if (bytesCopied != o.size) {
throw new IOException(MessageFormat.format(
- LfsText.get().wrongAmoutOfDataReceived,
+ LfsText.get().wrongAmountOfDataReceived,
contentServerConn.getURL(),
Long.valueOf(bytesCopied),
Long.valueOf(o.size)));
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/LfsUnauthorized.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/LfsUnauthorized.java
index 36889db8a6..0dc6aeab29 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/LfsUnauthorized.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/LfsUnauthorized.java
@@ -31,7 +31,7 @@ public class LfsUnauthorized extends LfsException {
* the repository name.
*/
public LfsUnauthorized(String operation, String name) {
- super(MessageFormat.format(LfsText.get().lfsUnathorized, operation,
+ super(MessageFormat.format(LfsText.get().lfsUnauthorized, operation,
name));
}
}
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsConfig.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsConfig.java
new file mode 100644
index 0000000000..71d395ca84
--- /dev/null
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsConfig.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2022, Matthias Fromme <mfromme@dspace.de>
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.lfs.internal;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.jgit.annotations.Nullable;
+import org.eclipse.jgit.dircache.DirCacheEntry;
+import org.eclipse.jgit.errors.ConfigInvalidException;
+import org.eclipse.jgit.lfs.errors.LfsConfigInvalidException;
+import org.eclipse.jgit.lfs.lib.Constants;
+import org.eclipse.jgit.lib.BlobBasedConfig;
+import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevTree;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.storage.file.FileBasedConfig;
+import org.eclipse.jgit.treewalk.TreeWalk;
+
+import static org.eclipse.jgit.lib.Constants.HEAD;
+
+/**
+ * Encapsulate access to the .lfsconfig.
+ *
+ * According to the document
+ * https://github.com/git-lfs/git-lfs/blob/main/docs/man/git-lfs-config.5.ronn
+ * the order to find the .lfsconfig file is:
+ *
+ * <pre>
+ * 1. in the root of the working tree
+ * 2. in the index
+ * 3. in the HEAD, for bare repositories this is the only place
+ * that is searched
+ * </pre>
+ *
+ * Values from the .lfsconfig are used only if not specified in another git
+ * config file to allow local override without modifiction of a committed file.
+ */
+public class LfsConfig {
+ private Repository db;
+ private Config delegate;
+
+ /**
+ * Create a new instance of the LfsConfig.
+ *
+ * @param db
+ * the associated repo
+ * @throws IOException
+ */
+ public LfsConfig(Repository db) throws IOException {
+ this.db = db;
+ delegate = this.load();
+ }
+
+ /**
+ * Read the .lfsconfig file from the repository
+ *
+ * @return The loaded lfs config or null if it does not exist
+ *
+ * @throws IOException
+ */
+ private Config load() throws IOException {
+ Config result = null;
+
+ if (!db.isBare()) {
+ result = loadFromWorkingTree();
+ if (result == null) {
+ result = loadFromIndex();
+ }
+ }
+
+ if (result == null) {
+ result = loadFromHead();
+ }
+
+ if (result == null) {
+ result = emptyConfig();
+ }
+
+ return result;
+ }
+
+ /**
+ * Try to read the lfs config from a file called .lfsconfig at the top level
+ * of the working tree.
+ *
+ * @return the config, or <code>null</code>
+ * @throws IOException
+ */
+ @Nullable
+ private Config loadFromWorkingTree()
+ throws IOException {
+ File lfsConfig = db.getFS().resolve(db.getWorkTree(),
+ Constants.DOT_LFS_CONFIG);
+ if (lfsConfig.exists() && lfsConfig.isFile()) {
+ FileBasedConfig config = new FileBasedConfig(lfsConfig, db.getFS());
+ try {
+ config.load();
+ return config;
+ } catch (ConfigInvalidException e) {
+ throw new LfsConfigInvalidException(
+ LfsText.get().dotLfsConfigReadFailed, e);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Try to read the lfs config from an entry called .lfsconfig contained in
+ * the index.
+ *
+ * @return the config, or <code>null</code> if the entry does not exist
+ * @throws IOException
+ */
+ @Nullable
+ private Config loadFromIndex()
+ throws IOException {
+ try {
+ DirCacheEntry entry = db.readDirCache()
+ .getEntry(Constants.DOT_LFS_CONFIG);
+ if (entry != null) {
+ return new BlobBasedConfig(null, db, entry.getObjectId());
+ }
+ } catch (ConfigInvalidException e) {
+ throw new LfsConfigInvalidException(
+ LfsText.get().dotLfsConfigReadFailed, e);
+ }
+ return null;
+ }
+
+ /**
+ * Try to read the lfs config from an entry called .lfsconfig contained in
+ * the head revision.
+ *
+ * @return the config, or <code>null</code> if the file does not exist
+ * @throws IOException
+ */
+ @Nullable
+ private Config loadFromHead() throws IOException {
+ try (RevWalk revWalk = new RevWalk(db)) {
+ ObjectId headCommitId = db.resolve(HEAD);
+ if (headCommitId == null) {
+ return null;
+ }
+ RevCommit commit = revWalk.parseCommit(headCommitId);
+ RevTree tree = commit.getTree();
+ TreeWalk treewalk = TreeWalk.forPath(db, Constants.DOT_LFS_CONFIG,
+ tree);
+ if (treewalk != null) {
+ return new BlobBasedConfig(null, db, treewalk.getObjectId(0));
+ }
+ } catch (ConfigInvalidException e) {
+ throw new LfsConfigInvalidException(
+ LfsText.get().dotLfsConfigReadFailed, e);
+ }
+ return null;
+ }
+
+ /**
+ * Create an empty config as fallback to avoid null pointer checks.
+ *
+ * @return an empty config
+ */
+ private Config emptyConfig() {
+ return new Config();
+ }
+
+ /**
+ * Get string value or null if not found.
+ *
+ * First tries to find the value in the git config files. If not found tries
+ * to find data in .lfsconfig.
+ *
+ * @param section
+ * the section
+ * @param subsection
+ * the subsection for the value
+ * @param name
+ * the key name
+ * @return a String value from the config, <code>null</code> if not found
+ */
+ public String getString(final String section, final String subsection,
+ final String name) {
+ String result = db.getConfig().getString(section, subsection, name);
+ if (result == null) {
+ result = delegate.getString(section, subsection, name);
+ }
+ return result;
+ }
+}
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsConnectionFactory.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsConnectionFactory.java
index 5a17d411c7..12b688d157 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsConnectionFactory.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsConnectionFactory.java
@@ -45,7 +45,6 @@ import org.eclipse.jgit.util.StringUtils;
* Provides means to get a valid LFS connection for a given repository.
*/
public class LfsConnectionFactory {
-
private static final int SSH_AUTH_TIMEOUT_SECONDS = 30;
private static final String SCHEME_HTTPS = "https"; //$NON-NLS-1$
private static final String SCHEME_SSH = "ssh"; //$NON-NLS-1$
@@ -104,19 +103,19 @@ public class LfsConnectionFactory {
* additional headers that can be used to connect to LFS server
* @return the URL for the LFS server. e.g.
* "https://github.com/github/git-lfs.git/info/lfs"
- * @throws LfsConfigInvalidException
- * if the LFS config is invalid
+ * @throws IOException
+ * if the LFS config is invalid or cannot be accessed
* @see <a href=
* "https://github.com/git-lfs/git-lfs/blob/main/docs/api/server-discovery.md">
* Server Discovery documentation</a>
*/
- static String getLfsUrl(Repository db, String purpose,
+ private static String getLfsUrl(Repository db, String purpose,
Map<String, String> additionalHeaders)
- throws LfsConfigInvalidException {
- StoredConfig config = db.getConfig();
+ throws IOException {
+ LfsConfig config = new LfsConfig(db);
String lfsUrl = config.getString(ConfigConstants.CONFIG_SECTION_LFS,
- null,
- ConfigConstants.CONFIG_KEY_URL);
+ null, ConfigConstants.CONFIG_KEY_URL);
+
Exception ex = null;
if (lfsUrl == null) {
String remoteUrl = null;
@@ -124,6 +123,7 @@ public class LfsConnectionFactory {
lfsUrl = config.getString(ConfigConstants.CONFIG_SECTION_LFS,
remote,
ConfigConstants.CONFIG_KEY_URL);
+
// This could be done better (more precise logic), but according
// to https://github.com/git-lfs/git-lfs/issues/1759 git-lfs
// generally only supports 'origin' in an integrated workflow.
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsText.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsText.java
index 1ca37a9f66..06234c1d90 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsText.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsText.java
@@ -28,21 +28,22 @@ public class LfsText extends TranslationBundle {
// @formatter:off
/***/ public String corruptLongObject;
- /***/ public String inconsistentMediafileLength;
+ /***/ public String dotLfsConfigReadFailed;
/***/ public String inconsistentContentLength;
+ /***/ public String inconsistentMediafileLength;
/***/ public String incorrectLONG_OBJECT_ID_LENGTH;
/***/ public String invalidLongId;
/***/ public String invalidLongIdLength;
+ /***/ public String lfsFailedToGetRepository;
+ /***/ public String lfsNoDownloadUrl;
+ /***/ public String lfsUnauthorized;
/***/ public String lfsUnavailable;
+ /***/ public String missingLocalObject;
/***/ public String protocolError;
- /***/ public String requiredHashFunctionNotAvailable;
/***/ public String repositoryNotFound;
/***/ public String repositoryReadOnly;
- /***/ public String lfsUnathorized;
- /***/ public String lfsFailedToGetRepository;
- /***/ public String lfsNoDownloadUrl;
+ /***/ public String requiredHashFunctionNotAvailable;
/***/ public String serverFailure;
- /***/ public String wrongAmoutOfDataReceived;
/***/ public String userConfigInvalid;
- /***/ public String missingLocalObject;
+ /***/ public String wrongAmountOfDataReceived;
}
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/Constants.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/Constants.java
index 3212a63504..9b41ec31f1 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/Constants.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/Constants.java
@@ -82,6 +82,13 @@ public final class Constants {
public static final String ATTR_FILTER_DRIVER_PREFIX = "lfs/";
/**
+ * Config file name for lfs specific configuration
+ *
+ * @since 6.1
+ */
+ public static final String DOT_LFS_CONFIG = ".lfsconfig";
+
+ /**
* Create a new digest function for objects.
*
* @return a new digest object.