diff options
author | Matthias Sohn <matthias.sohn@sap.com> | 2022-07-06 17:29:23 +0200 |
---|---|---|
committer | Matthias Sohn <matthias.sohn@sap.com> | 2022-07-06 19:07:45 +0200 |
commit | 3fc0ec18228d392aecf5d15198e001815726b5d5 (patch) | |
tree | eec583d62bdde6f49101024e5f20878f90bde5cd /org.eclipse.jgit.lfs | |
parent | c6a64ecae7ea5519bb6460b38d7ec65a83dc6303 (diff) | |
parent | f6935d8cd2e00d5923917ff869354e443da66014 (diff) | |
download | jgit-3fc0ec18228d392aecf5d15198e001815726b5d5.tar.gz jgit-3fc0ec18228d392aecf5d15198e001815726b5d5.zip |
Merge branch 'master' into next
* master: (193 commits)
Add aarch64 environment to target platform configuration
JGit blame very slow for large merge commits that rename files
UploadPack: don't prematurely terminate timer in case of error
Do not create reflog for remote tracking branches during clone
UploadPack: do not check reachability of visible SHA1s
Fix warnings about non-externalized string literals
[sshd] Correct signature for RSA keys from an SSH agent
Run tests that checks araxis output only on Linux
Add missing package import javax.management to org.eclipse.jgit
Add 4.25 target platform for Eclipse 2022-09
Suppress API errors raised for new API introduced in 5.13.1
Eclipse 4.24 was released, adapt p2 URL accordingly
Fix DefaultCharset bug pattern flagged by error prone
Use SystemReader#getDefaultCharset to read console input
Annotate the exception with the possible failure reason when Bitmaps are not enabled.
Prepare 5.13.2-SNAPSHOT builds
JGit v5.13.1.202206130422-r
AmazonS3: Add support for AWS API signature version 4
Fix typo in DiffTools#compare javadoc
Update jgit-last-release-version to 6.2.0.202206071550-r
...
Change-Id: I561a0178f6bc512e8ce7d75f1870a044cb051fac
Diffstat (limited to 'org.eclipse.jgit.lfs')
9 files changed, 282 insertions, 33 deletions
diff --git a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF index 1d5f76ffa9..d19f613e57 100644 --- a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF @@ -17,6 +17,7 @@ Import-Package: com.google.gson;version="[2.8.2,3.0.0)", org.eclipse.jgit.api.errors;version="[7.0.0,7.1.0)", org.eclipse.jgit.attributes;version="[7.0.0,7.1.0)", org.eclipse.jgit.diff;version="[7.0.0,7.1.0)", + org.eclipse.jgit.dircache;version="[7.0.0,7.1.0)", org.eclipse.jgit.errors;version="[7.0.0,7.1.0)", org.eclipse.jgit.hooks;version="[7.0.0,7.1.0)", org.eclipse.jgit.internal.storage.file;version="[7.0.0,7.1.0)", 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..c4c0dacf42 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,18 @@ 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/LfsPrePushHook.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPrePushHook.java index d6ce855794..9b3d60812a 100644 --- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPrePushHook.java +++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPrePushHook.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017, Markus Duft <markus.duft@ssi-schaefer.com> and others + * Copyright (C) 2017, 2022 Markus Duft <markus.duft@ssi-schaefer.com> and others * * This program and the accompanying materials are made available under the * terms of the Eclipse Distribution License v. 1.0 which is available at @@ -101,8 +101,10 @@ public class LfsPrePushHook extends PrePushHook { } HttpConnection api = LfsConnectionFactory.getLfsConnection( getRepository(), METHOD_POST, OPERATION_UPLOAD); - Map<String, LfsPointer> oid2ptr = requestBatchUpload(api, toPush); - uploadContents(api, oid2ptr); + if (!isDryRun()) { + Map<String, LfsPointer> oid2ptr = requestBatchUpload(api, toPush); + uploadContents(api, oid2ptr); + } return EMPTY; } @@ -113,6 +115,9 @@ public class LfsPrePushHook extends PrePushHook { try (ObjectWalk walk = new ObjectWalk(getRepository())) { for (RemoteRefUpdate up : refs) { + if (up.isDelete()) { + continue; + } walk.setRewriteParents(false); excludeRemoteRefs(walk); walk.markStart(walk.parseCommit(up.getNewObjectId())); 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..857ccbe056 --- /dev/null +++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsConfig.java @@ -0,0 +1,220 @@ +/* + * 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 {@code .lfsconfig}. + * <p> + * According to the git lfs documentation the order to find the + * {@code .lfsconfig} file is: + * </p> + * <ol> + * <li>in the root of the working tree</li> + * <li>in the index</li> + * <li>in the HEAD; for bare repositories this is the only place that is + * searched</li> + * </ol> + * <p> + * Values from the {@code .lfsconfig} are used only if not specified in another + * git config file to allow local override without modifiction of a committed + * file. + * </p> + * + * @see <a href= + * "https://github.com/git-lfs/git-lfs/blob/main/docs/man/git-lfs-config.5.ronn">Configuration + * options for git-lfs</a> + */ +public class LfsConfig { + private Repository db; + private Config delegate; + + /** + * Create a new instance of the LfsConfig. + * + * @param db + * the associated repo + */ + public LfsConfig(Repository db) { + this.db = db; + } + + /** + * Getter for the delegate to allow lazy initialization. + * + * @return the delegate {@link Config} + * @throws IOException + */ + private Config getDelegate() throws IOException { + if (delegate == null) { + delegate = this.load(); + } + return delegate; + } + + /** + * Read the .lfsconfig file from the repository + * + * An empty config is returned be empty if no lfs config exists. + * + * @return The loaded lfs config + * + * @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.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 + * @throws IOException + */ + @Nullable + public String getString(final String section, final String subsection, + final String name) throws IOException { + String result = db.getConfig().getString(section, subsection, name); + if (result == null) { + result = getDelegate().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 e221913bea..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 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017, Markus Duft <markus.duft@ssi-schaefer.com> and others + * Copyright (C) 2017, 2022 Markus Duft <markus.duft@ssi-schaefer.com> and others * * This program and the accompanying materials are made available under the * terms of the Eclipse Distribution License v. 1.0 which is available at @@ -39,12 +39,12 @@ import org.eclipse.jgit.transport.URIish; import org.eclipse.jgit.transport.http.HttpConnection; import org.eclipse.jgit.util.HttpSupport; import org.eclipse.jgit.util.SshSupport; +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$ @@ -64,7 +64,7 @@ public class LfsConnectionFactory { * be used for * @param purpose * the action, e.g. Protocol.OPERATION_DOWNLOAD - * @return the url for the lfs server. e.g. + * @return the connection for the lfs server. e.g. * "https://github.com/github/git-lfs.git/info/lfs" * @throws IOException */ @@ -92,13 +92,30 @@ public class LfsConnectionFactory { return connection; } + /** + * Get LFS Server URL. + * + * @param db + * the repository to work with + * @param purpose + * the action, e.g. Protocol.OPERATION_DOWNLOAD + * @param additionalHeaders + * 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 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> + */ 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; @@ -106,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. @@ -125,8 +143,6 @@ public class LfsConnectionFactory { | CommandFailedException e) { ex = e; } - } else { - lfsUrl = lfsUrl + Protocol.INFO_LFS_ENDPOINT; } } if (lfsUrl == null) { @@ -149,7 +165,8 @@ public class LfsConnectionFactory { additionalHeaders.putAll(action.header); return action.href; } - return remoteUrl + Protocol.INFO_LFS_ENDPOINT; + return StringUtils.nameWithDotGit(remoteUrl) + + Protocol.INFO_LFS_ENDPOINT; } private static Protocol.ExpiringAction getSshAuthentication( 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..8ef8f59f93 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,21 @@ 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. |