* stable-5.4:
Fix NPE in RebaseTodoFile#parseComments
Fix NPE in ObjectIdOwnerMap#get
Fix NPE in CommitOnlyTest#getHead
FileUtils#lastModifiedInstant should not log error if path doesn't exist
Cache user global and system-wide git configurations
Avoid setup and saving FileStoreAttributes compete for ~/.gitconfig lock
Add missing dependencies for running FS_POSIXTest in Eclipse
Fix javadoc for SystemReader#getInstance
Upgrade tycho-extras to 1.4.0
Improve retry handling when saving FileStoreAttributes fails
Ensure FSTest uses MockSystemReader
Make supportsAtomicCreateNewFile return true as default
Update orbit to R20190602212107-2019-06 to enable backports from master
Handle InvalidPathException in FS_POSIX#createNewFileAtomic
Ensure root cause of lock creation failures is logged
Implement toString in MockSystemReader and MockConfig
LocalDiskRefTreeDatabaseTest shall use MockSystemReader
Ensure LocalDiskRepositoryTestCase#setup fully uses MockSystemReader
Ensure we use MockSystemReader in tests
Override FileBasedConfig's save method in MockConfig
Remove FileBasedConfig.load(boolean) introduced in d45219ba
Disable debug log for FS in org.eclipse.jgit.test
Bazel: enable logging for tests in org.eclipse.jgit.test
LockFile: log exception if creation of lock file failed
Stop using deprecated Constants.CHARACTER_ENCODING
Change-Id: I709de5edb626536529a99220aae7751b127c9bff
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
tags/v5.5.0.201908280940-m3
BYTE_BUDDY_VERSION = "1.9.0" | BYTE_BUDDY_VERSION = "1.9.0" | ||||
maven_jar( | maven_jar( | ||||
name = "byte_buddy", | |||||
name = "bytebuddy", | |||||
artifact = "net.bytebuddy:byte-buddy:" + BYTE_BUDDY_VERSION, | artifact = "net.bytebuddy:byte-buddy:" + BYTE_BUDDY_VERSION, | ||||
sha1 = "8cb0d5baae526c9df46ae17693bbba302640538b", | sha1 = "8cb0d5baae526c9df46ae17693bbba302640538b", | ||||
) | ) | ||||
maven_jar( | maven_jar( | ||||
name = "byte_buddy_agent", | |||||
name = "bytebuddy-agent", | |||||
artifact = "net.bytebuddy:byte-buddy-agent:" + BYTE_BUDDY_VERSION, | artifact = "net.bytebuddy:byte-buddy-agent:" + BYTE_BUDDY_VERSION, | ||||
sha1 = "37b5703b4a6290be3fffc63ae9c6bcaaee0ff856", | sha1 = "37b5703b4a6290be3fffc63ae9c6bcaaee0ff856", | ||||
) | ) |
testonly = 1, | testonly = 1, | ||||
visibility = ["//visibility:public"], | visibility = ["//visibility:public"], | ||||
exports = [ | exports = [ | ||||
"@bytebuddy//jar", | |||||
"@bytebuddy-agent//jar", | |||||
"@hamcrest-core//jar", | "@hamcrest-core//jar", | ||||
"@hamcrest-library//jar", | "@hamcrest-library//jar", | ||||
"@junit//jar", | "@junit//jar", | ||||
"@mockito//jar", | |||||
"@objenesis//jar" | |||||
], | ], | ||||
) | ) | ||||
testonly = 1, | testonly = 1, | ||||
visibility = ["//visibility:public"], | visibility = ["//visibility:public"], | ||||
exports = [ | exports = [ | ||||
"@byte_buddy//jar", | |||||
"@byte_buddy_agent//jar", | |||||
"@bytebuddy//jar", | |||||
"@bytebuddy-agent//jar", | |||||
"@mockito//jar", | "@mockito//jar", | ||||
"@objenesis//jar", | "@objenesis//jar", | ||||
], | ], |
import org.eclipse.jgit.revwalk.RevBlob; | import org.eclipse.jgit.revwalk.RevBlob; | ||||
import org.eclipse.jgit.revwalk.RevCommit; | import org.eclipse.jgit.revwalk.RevCommit; | ||||
import org.eclipse.jgit.revwalk.RevWalk; | import org.eclipse.jgit.revwalk.RevWalk; | ||||
import org.eclipse.jgit.storage.file.FileBasedConfig; | |||||
import org.eclipse.jgit.transport.AbstractAdvertiseRefsHook; | import org.eclipse.jgit.transport.AbstractAdvertiseRefsHook; | ||||
import org.eclipse.jgit.transport.AdvertiseRefsHook; | import org.eclipse.jgit.transport.AdvertiseRefsHook; | ||||
import org.eclipse.jgit.transport.CredentialItem; | import org.eclipse.jgit.transport.CredentialItem; | ||||
import org.eclipse.jgit.transport.http.HttpConnectionFactory; | import org.eclipse.jgit.transport.http.HttpConnectionFactory; | ||||
import org.eclipse.jgit.transport.http.JDKHttpConnectionFactory; | import org.eclipse.jgit.transport.http.JDKHttpConnectionFactory; | ||||
import org.eclipse.jgit.transport.http.apache.HttpClientConnectionFactory; | import org.eclipse.jgit.transport.http.apache.HttpClientConnectionFactory; | ||||
import org.eclipse.jgit.util.FS; | |||||
import org.eclipse.jgit.util.HttpSupport; | import org.eclipse.jgit.util.HttpSupport; | ||||
import org.eclipse.jgit.util.SystemReader; | import org.eclipse.jgit.util.SystemReader; | ||||
import org.hamcrest.Matchers; | import org.hamcrest.Matchers; | ||||
@Test | @Test | ||||
public void testInitialClone_RedirectMax() throws Exception { | public void testInitialClone_RedirectMax() throws Exception { | ||||
FileBasedConfig userConfig = SystemReader.getInstance() | |||||
.openUserConfig(null, FS.DETECTED); | |||||
StoredConfig userConfig = SystemReader.getInstance() | |||||
.getUserConfig(); | |||||
userConfig.setInt("http", null, "maxRedirects", 4); | userConfig.setInt("http", null, "maxRedirects", 4); | ||||
userConfig.save(); | userConfig.save(); | ||||
initialClone_Redirect(4, 302); | initialClone_Redirect(4, 302); | ||||
@Test | @Test | ||||
public void testInitialClone_RedirectTooOften() throws Exception { | public void testInitialClone_RedirectTooOften() throws Exception { | ||||
FileBasedConfig userConfig = SystemReader.getInstance() | |||||
.openUserConfig(null, FS.DETECTED); | |||||
StoredConfig userConfig = SystemReader.getInstance() | |||||
.getUserConfig(); | |||||
userConfig.setInt("http", null, "maxRedirects", 3); | userConfig.setInt("http", null, "maxRedirects", 3); | ||||
userConfig.save(); | userConfig.save(); | ||||
@Test | @Test | ||||
public void testInitialClone_RedirectOnPostAllowed() throws Exception { | public void testInitialClone_RedirectOnPostAllowed() throws Exception { | ||||
FileBasedConfig userConfig = SystemReader.getInstance() | |||||
.openUserConfig(null, FS.DETECTED); | |||||
StoredConfig userConfig = SystemReader.getInstance() | |||||
.getUserConfig(); | |||||
userConfig.setString("http", null, "followRedirects", "true"); | userConfig.setString("http", null, "followRedirects", "true"); | ||||
userConfig.save(); | userConfig.save(); | ||||
@Test | @Test | ||||
public void testInitialClone_RedirectForbidden() throws Exception { | public void testInitialClone_RedirectForbidden() throws Exception { | ||||
FileBasedConfig userConfig = SystemReader.getInstance() | |||||
.openUserConfig(null, FS.DETECTED); | |||||
StoredConfig userConfig = SystemReader.getInstance() | |||||
.getUserConfig(); | |||||
userConfig.setString("http", null, "followRedirects", "false"); | userConfig.setString("http", null, "followRedirects", "false"); | ||||
userConfig.save(); | userConfig.save(); | ||||
if (!tmp.delete() || !tmp.mkdir()) | if (!tmp.delete() || !tmp.mkdir()) | ||||
throw new IOException("Cannot create " + tmp); | throw new IOException("Cannot create " + tmp); | ||||
// measure timer resolution before the test to avoid time critical tests | |||||
// are affected by time needed for measurement | |||||
mockSystemReader = new MockSystemReader(); | |||||
SystemReader.setInstance(mockSystemReader); | |||||
// Measure timer resolution before the test to avoid time critical tests | |||||
// are affected by time needed for measurement. | |||||
// The MockSystemReader must be configured first since we need to use | |||||
// the same one here | |||||
FS.getFileStoreAttributes(tmp.toPath().getParent()); | FS.getFileStoreAttributes(tmp.toPath().getParent()); | ||||
mockSystemReader = new MockSystemReader(); | |||||
mockSystemReader.userGitConfig = new FileBasedConfig(new File(tmp, | |||||
"usergitconfig"), FS.DETECTED); | |||||
FileBasedConfig userConfig = new FileBasedConfig( | |||||
new File(tmp, "usergitconfig"), FS.DETECTED); | |||||
// We have to set autoDetach to false for tests, because tests expect to be able | // We have to set autoDetach to false for tests, because tests expect to be able | ||||
// to clean up by recursively removing the repository, and background GC might be | // to clean up by recursively removing the repository, and background GC might be | ||||
// in the middle of writing or deleting files, which would disrupt this. | // in the middle of writing or deleting files, which would disrupt this. | ||||
mockSystemReader.userGitConfig.setBoolean(ConfigConstants.CONFIG_GC_SECTION, | |||||
userConfig.setBoolean(ConfigConstants.CONFIG_GC_SECTION, | |||||
null, ConfigConstants.CONFIG_KEY_AUTODETACH, false); | null, ConfigConstants.CONFIG_KEY_AUTODETACH, false); | ||||
mockSystemReader.userGitConfig.save(); | |||||
userConfig.save(); | |||||
mockSystemReader.setUserGitConfig(userConfig); | |||||
ceilTestDirectories(getCeilings()); | ceilTestDirectories(getCeilings()); | ||||
SystemReader.setInstance(mockSystemReader); | |||||
author = new PersonIdent("J. Author", "jauthor@example.com"); | author = new PersonIdent("J. Author", "jauthor@example.com"); | ||||
committer = new PersonIdent("J. Committer", "jcommitter@example.com"); | committer = new PersonIdent("J. Committer", "jcommitter@example.com"); |
import org.eclipse.jgit.errors.ConfigInvalidException; | import org.eclipse.jgit.errors.ConfigInvalidException; | ||||
import org.eclipse.jgit.lib.Config; | import org.eclipse.jgit.lib.Config; | ||||
import org.eclipse.jgit.lib.Constants; | import org.eclipse.jgit.lib.Constants; | ||||
import org.eclipse.jgit.lib.StoredConfig; | |||||
import org.eclipse.jgit.storage.file.FileBasedConfig; | import org.eclipse.jgit.storage.file.FileBasedConfig; | ||||
import org.eclipse.jgit.util.FS; | import org.eclipse.jgit.util.FS; | ||||
import org.eclipse.jgit.util.SystemReader; | import org.eclipse.jgit.util.SystemReader; | ||||
// Do nothing | // Do nothing | ||||
} | } | ||||
@Override | |||||
public void save() throws IOException { | |||||
// Do nothing | |||||
} | |||||
@Override | @Override | ||||
public boolean isOutdated() { | public boolean isOutdated() { | ||||
return false; | return false; | ||||
} | } | ||||
@Override | |||||
public String toString() { | |||||
return "MockConfig"; | |||||
} | |||||
} | } | ||||
long now = 1250379778668L; // Sat Aug 15 20:12:58 GMT-03:30 2009 | long now = 1250379778668L; // Sat Aug 15 20:12:58 GMT-03:30 2009 | ||||
final Map<String, String> values = new HashMap<>(); | final Map<String, String> values = new HashMap<>(); | ||||
FileBasedConfig userGitConfig; | |||||
private FileBasedConfig userGitConfig; | |||||
FileBasedConfig systemGitConfig; | FileBasedConfig systemGitConfig; | ||||
/** | |||||
* Set the user-level git config | |||||
* | |||||
* @param userGitConfig | |||||
* set another user-level git config | |||||
* @return the old user-level git config | |||||
*/ | |||||
public FileBasedConfig setUserGitConfig(FileBasedConfig userGitConfig) { | |||||
FileBasedConfig old = this.userGitConfig; | |||||
this.userGitConfig = userGitConfig; | |||||
return old; | |||||
} | |||||
/** | |||||
* Set the system-level git config | |||||
* | |||||
* @param systemGitConfig | |||||
* the new system-level git config | |||||
* @return the old system-level config | |||||
*/ | |||||
public FileBasedConfig setSystemGitConfig(FileBasedConfig systemGitConfig) { | |||||
FileBasedConfig old = this.systemGitConfig; | |||||
this.systemGitConfig = systemGitConfig; | |||||
return old; | |||||
} | |||||
/** | /** | ||||
* Constructor for <code>MockSystemReader</code> | * Constructor for <code>MockSystemReader</code> | ||||
*/ | */ | ||||
return systemGitConfig; | return systemGitConfig; | ||||
} | } | ||||
@Override | |||||
public StoredConfig getUserConfig() | |||||
throws IOException, ConfigInvalidException { | |||||
return userGitConfig; | |||||
} | |||||
@Override | |||||
public StoredConfig getSystemConfig() | |||||
throws IOException, ConfigInvalidException { | |||||
return systemGitConfig; | |||||
} | |||||
/** {@inheritDoc} */ | /** {@inheritDoc} */ | ||||
@Override | @Override | ||||
public String getHostname() { | public String getHostname() { | ||||
e.printStackTrace(); | e.printStackTrace(); | ||||
} | } | ||||
} | } | ||||
@Override | |||||
public String toString() { | |||||
return "MockSystemReader"; | |||||
} | |||||
} | } |
import org.apache.http.impl.client.HttpClientBuilder; | import org.apache.http.impl.client.HttpClientBuilder; | ||||
import org.eclipse.jetty.servlet.ServletContextHandler; | import org.eclipse.jetty.servlet.ServletContextHandler; | ||||
import org.eclipse.jetty.servlet.ServletHolder; | import org.eclipse.jetty.servlet.ServletHolder; | ||||
import org.eclipse.jgit.junit.MockSystemReader; | |||||
import org.eclipse.jgit.junit.http.AppServer; | import org.eclipse.jgit.junit.http.AppServer; | ||||
import org.eclipse.jgit.lfs.errors.LfsException; | import org.eclipse.jgit.lfs.errors.LfsException; | ||||
import org.eclipse.jgit.lfs.lib.AnyLongObjectId; | import org.eclipse.jgit.lfs.lib.AnyLongObjectId; | ||||
import org.eclipse.jgit.util.FS; | import org.eclipse.jgit.util.FS; | ||||
import org.eclipse.jgit.util.FileUtils; | import org.eclipse.jgit.util.FileUtils; | ||||
import org.eclipse.jgit.util.IO; | import org.eclipse.jgit.util.IO; | ||||
import org.eclipse.jgit.util.SystemReader; | |||||
import org.junit.After; | import org.junit.After; | ||||
import org.junit.Before; | import org.junit.Before; | ||||
@Before | @Before | ||||
public void setup() throws Exception { | public void setup() throws Exception { | ||||
SystemReader.setInstance(new MockSystemReader()); | |||||
tmp = Files.createTempDirectory("jgit_test_"); | tmp = Files.createTempDirectory("jgit_test_"); | ||||
// measure timer resolution before the test to avoid time critical tests | // measure timer resolution before the test to avoid time critical tests |
package org.eclipse.jgit.lfs; | package org.eclipse.jgit.lfs; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.text.MessageFormat; | |||||
import org.eclipse.jgit.api.errors.InvalidConfigurationException; | |||||
import org.eclipse.jgit.errors.ConfigInvalidException; | import org.eclipse.jgit.errors.ConfigInvalidException; | ||||
import org.eclipse.jgit.lfs.internal.LfsText; | |||||
import org.eclipse.jgit.lib.ConfigConstants; | import org.eclipse.jgit.lib.ConfigConstants; | ||||
import org.eclipse.jgit.lib.Repository; | import org.eclipse.jgit.lib.Repository; | ||||
import org.eclipse.jgit.lib.StoredConfig; | import org.eclipse.jgit.lib.StoredConfig; | ||||
import org.eclipse.jgit.storage.file.FileBasedConfig; | |||||
import org.eclipse.jgit.util.FS; | import org.eclipse.jgit.util.FS; | ||||
import org.eclipse.jgit.util.LfsFactory.LfsInstallCommand; | import org.eclipse.jgit.util.LfsFactory.LfsInstallCommand; | ||||
import org.eclipse.jgit.util.SystemReader; | import org.eclipse.jgit.util.SystemReader; | ||||
private Repository repository; | private Repository repository; | ||||
/** {@inheritDoc} */ | |||||
/** | |||||
* {@inheritDoc} | |||||
* | |||||
* @throws IOException | |||||
* if an I/O error occurs while accessing a git config or | |||||
* executing {@code git lfs install} in an external process | |||||
* @throws InvalidConfigurationException | |||||
* if a git configuration is invalid | |||||
* @throws InterruptedException | |||||
* if the current thread is interrupted while waiting for the | |||||
* {@code git lfs install} executed in an external process | |||||
*/ | |||||
@Override | @Override | ||||
public Void call() throws Exception { | |||||
public Void call() throws IOException, InvalidConfigurationException, | |||||
InterruptedException { | |||||
StoredConfig cfg = null; | StoredConfig cfg = null; | ||||
if (repository == null) { | if (repository == null) { | ||||
cfg = loadUserConfig(); | |||||
try { | |||||
cfg = SystemReader.getInstance().getUserConfig(); | |||||
} catch (ConfigInvalidException e) { | |||||
throw new InvalidConfigurationException(e.getMessage(), e); | |||||
} | |||||
} else { | } else { | ||||
cfg = repository.getConfig(); | cfg = repository.getConfig(); | ||||
} | } | ||||
return this; | return this; | ||||
} | } | ||||
private StoredConfig loadUserConfig() throws IOException { | |||||
FileBasedConfig c = SystemReader.getInstance().openUserConfig(null, | |||||
FS.DETECTED); | |||||
try { | |||||
c.load(); | |||||
} catch (ConfigInvalidException e1) { | |||||
throw new IOException(MessageFormat | |||||
.format(LfsText.get().userConfigInvalid, c.getFile() | |||||
.getAbsolutePath(), e1), | |||||
e1); | |||||
} | |||||
return c; | |||||
} | |||||
} | } |
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
<?pde?> | <?pde?> | ||||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | ||||
<target name="jgit-4.10" sequenceNumber="1560816180"> | |||||
<target name="jgit-4.10" sequenceNumber="1566252827"> | |||||
<locations> | <locations> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/> | <unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/> |
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
<?pde?> | <?pde?> | ||||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | ||||
<target name="jgit-4.11" sequenceNumber="1560816197"> | |||||
<target name="jgit-4.11" sequenceNumber="1566252823"> | |||||
<locations> | <locations> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/> | <unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/> |
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
<?pde?> | <?pde?> | ||||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | ||||
<target name="jgit-4.12-staging" sequenceNumber="1560816219"> | |||||
<target name="jgit-4.12-staging" sequenceNumber="1566252818"> | |||||
<locations> | <locations> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/> | <unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/> |
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
<?pde?> | <?pde?> | ||||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | ||||
<target name="jgit-4.6" sequenceNumber="1560816227"> | |||||
<target name="jgit-4.6" sequenceNumber="1566252830"> | |||||
<locations> | <locations> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/> | <unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/> |
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
<?pde?> | <?pde?> | ||||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | ||||
<target name="jgit-4.7" sequenceNumber="1560816219"> | |||||
<target name="jgit-4.7" sequenceNumber="1566252816"> | |||||
<locations> | <locations> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/> | <unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/> |
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
<?pde?> | <?pde?> | ||||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | ||||
<target name="jgit-4.8" sequenceNumber="1560816217"> | |||||
<target name="jgit-4.8" sequenceNumber="1566252807"> | |||||
<locations> | <locations> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/> | <unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/> |
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
<?pde?> | <?pde?> | ||||
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> | ||||
<target name="jgit-4.9" sequenceNumber="1560816222"> | |||||
<target name="jgit-4.9" sequenceNumber="1566252778"> | |||||
<locations> | <locations> | ||||
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> | ||||
<unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/> | <unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/> |
org.apache.sshd.sftp [2.2.0.v20190425-2127,2.2.0.v20190425-2127] | org.apache.sshd.sftp [2.2.0.v20190425-2127,2.2.0.v20190425-2127] | ||||
org.apache.sshd.sftp.source [2.2.0.v20190425-2127,2.2.0.v20190425-2127] | org.apache.sshd.sftp.source [2.2.0.v20190425-2127,2.2.0.v20190425-2127] | ||||
} | } | ||||
package org.eclipse.jgit.pgm; | package org.eclipse.jgit.pgm; | ||||
import static org.junit.Assert.assertEquals; | import static org.junit.Assert.assertEquals; | ||||
import static org.junit.Assert.assertTrue; | |||||
import java.util.ArrayList; | |||||
import java.util.Arrays; | import java.util.Arrays; | ||||
import java.util.List; | |||||
import java.util.HashMap; | |||||
import java.util.Map; | |||||
import org.eclipse.jgit.api.Git; | import org.eclipse.jgit.api.Git; | ||||
import org.eclipse.jgit.lib.CLIRepositoryTestCase; | import org.eclipse.jgit.lib.CLIRepositoryTestCase; | ||||
import org.eclipse.jgit.util.FS; | |||||
import org.eclipse.jgit.util.SystemReader; | import org.eclipse.jgit.util.SystemReader; | ||||
import org.junit.Before; | import org.junit.Before; | ||||
import org.junit.Test; | import org.junit.Test; | ||||
} | } | ||||
} | } | ||||
@SuppressWarnings("boxing") | |||||
@Test | @Test | ||||
public void testListConfig() throws Exception { | public void testListConfig() throws Exception { | ||||
boolean isWindows = SystemReader.getInstance().getProperty("os.name") | boolean isWindows = SystemReader.getInstance().getProperty("os.name") | ||||
.equals("Mac OS X"); | .equals("Mac OS X"); | ||||
String[] output = execute("git config --list"); | String[] output = execute("git config --list"); | ||||
List<String> expect = new ArrayList<>(); | |||||
expect.add("gc.autoDetach=false"); | |||||
expect.add("core.filemode=" + !isWindows); | |||||
expect.add("core.logallrefupdates=true"); | |||||
if (isMac) | |||||
expect.add("core.precomposeunicode=true"); | |||||
expect.add("core.repositoryformatversion=0"); | |||||
if (!FS.DETECTED.supportsSymlinks()) | |||||
expect.add("core.symlinks=false"); | |||||
expect.add(""); // ends with LF (last line empty) | |||||
assertEquals("expected default configuration", | |||||
Arrays.asList(expect.toArray()).toString(), | |||||
Arrays.asList(output).toString()); | |||||
Map<String, String> options = parseOptions(output); | |||||
assertEquals(!isWindows, Boolean.valueOf(options.get("core.filemode"))); | |||||
assertTrue((Boolean.valueOf(options.get("core.logallrefupdates")))); | |||||
if (isMac) { | |||||
assertTrue( | |||||
(Boolean.valueOf(options.get("core.precomposeunicode")))); | |||||
} | |||||
assertEquals(Integer.valueOf(0), | |||||
Integer.valueOf(options.get("core.repositoryformatversion"))); | |||||
} | |||||
private Map<String, String> parseOptions(String[] output) { | |||||
Map<String, String> options = new HashMap<>(); | |||||
Arrays.stream(output).forEachOrdered(s -> { | |||||
int p = s.indexOf('='); | |||||
if (p == -1) { | |||||
return; | |||||
} | |||||
String key = s.substring(0, p); | |||||
String value = s.substring(p + 1); | |||||
options.put(key, value); | |||||
}); | |||||
return options; | |||||
} | } | ||||
} | } |
deps = [ | deps = [ | ||||
"//lib:jsch", | "//lib:jsch", | ||||
"//lib:junit", | "//lib:junit", | ||||
"//lib:slf4j-simple", | |||||
"//lib:mockito", | "//lib:mockito", | ||||
"//org.eclipse.jgit:jgit", | "//org.eclipse.jgit:jgit", | ||||
"//org.eclipse.jgit.junit:junit", | "//org.eclipse.jgit.junit:junit", |
Bundle-RequiredExecutionEnvironment: JavaSE-1.8 | Bundle-RequiredExecutionEnvironment: JavaSE-1.8 | ||||
Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)", | Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)", | ||||
com.jcraft.jsch;version="[0.1.54,0.2.0)", | com.jcraft.jsch;version="[0.1.54,0.2.0)", | ||||
net.bytebuddy.dynamic.loading;version="[1.7.0,2.0.0)", | |||||
net.bytebuddy.dynamic.loading;version="[1.9.0,2.0.0)", | |||||
org.apache.commons.compress.archivers;version="[1.15.0,2.0)", | org.apache.commons.compress.archivers;version="[1.15.0,2.0)", | ||||
org.apache.commons.compress.archivers.tar;version="[1.15.0,2.0)", | org.apache.commons.compress.archivers.tar;version="[1.15.0,2.0)", | ||||
org.apache.commons.compress.archivers.zip;version="[1.15.0,2.0)", | org.apache.commons.compress.archivers.zip;version="[1.15.0,2.0)", | ||||
org.junit.rules;version="[4.12,5.0.0)", | org.junit.rules;version="[4.12,5.0.0)", | ||||
org.junit.runner;version="[4.12,5.0.0)", | org.junit.runner;version="[4.12,5.0.0)", | ||||
org.junit.runners;version="[4.12,5.0.0)", | org.junit.runners;version="[4.12,5.0.0)", | ||||
org.mockito;version="[2.13.0,3.0.0)", | |||||
org.mockito.invocation;version="[2.13.0,3.0.0)", | |||||
org.mockito.junit;version="[2.13.0,3.0.0)", | |||||
org.mockito.stubbing;version="[2.13.0,3.0.0)", | |||||
org.mockito;version="[2.23.0,3.0.0)", | |||||
org.mockito.invocation;version="[2.23.0,3.0.0)", | |||||
org.mockito.junit;version="[2.23.0,3.0.0)", | |||||
org.mockito.stubbing;version="[2.23.0,3.0.0)", | |||||
org.objenesis;version="[2.6.0,3.0.0)", | org.objenesis;version="[2.6.0,3.0.0)", | ||||
org.slf4j;version="[1.7.0,2.0.0)", | org.slf4j;version="[1.7.0,2.0.0)", | ||||
org.tukaani.xz;version="[1.6.0,2.0)" | org.tukaani.xz;version="[1.6.0,2.0)" |
log4j.appender.stdout.Target=System.out | log4j.appender.stdout.Target=System.out | ||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout | ||||
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n | log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n | ||||
#log4j.appender.fileLogger.bufferedIO = true | |||||
#log4j.appender.fileLogger.bufferSize = 4096 | |||||
log4j.appender.fileLogger.bufferedIO = true | |||||
log4j.appender.fileLogger.bufferSize = 4096 | |||||
#log4j.logger.org.eclipse.jgit.util.FS = DEBUG | #log4j.logger.org.eclipse.jgit.util.FS = DEBUG | ||||
#log4j.logger.org.eclipse.jgit.internal.storage.file.FileSnapshot = DEBUG | #log4j.logger.org.eclipse.jgit.internal.storage.file.FileSnapshot = DEBUG |
org.slf4j.simpleLogger.logFile = System.err | |||||
org.slf4j.simpleLogger.cacheOutputStream = true | |||||
org.slf4j.simpleLogger.defaultLogLevel = info | |||||
org.slf4j.simpleLogger.showDateTime = true | |||||
org.slf4j.simpleLogger.dateTimeFormat = HH:mm:ss.SSSXXX | |||||
org.slf4j.simpleLogger.showThreadName = true | |||||
#org.slf4j.simpleLogger.log.org.eclipse.jgit.util.FS = debug | |||||
#org.slf4j.simpleLogger.log.org.eclipse.jgit.internal.storage.file.FileSnapshot = debug |
import org.eclipse.jgit.lib.ObjectId; | import org.eclipse.jgit.lib.ObjectId; | ||||
import org.eclipse.jgit.lib.Ref; | import org.eclipse.jgit.lib.Ref; | ||||
import org.eclipse.jgit.lib.Repository; | import org.eclipse.jgit.lib.Repository; | ||||
import org.eclipse.jgit.lib.StoredConfig; | |||||
import org.eclipse.jgit.revwalk.RevBlob; | import org.eclipse.jgit.revwalk.RevBlob; | ||||
import org.eclipse.jgit.revwalk.RevCommit; | import org.eclipse.jgit.revwalk.RevCommit; | ||||
import org.eclipse.jgit.storage.file.FileBasedConfig; | |||||
import org.eclipse.jgit.submodule.SubmoduleStatus; | import org.eclipse.jgit.submodule.SubmoduleStatus; | ||||
import org.eclipse.jgit.submodule.SubmoduleStatusType; | import org.eclipse.jgit.submodule.SubmoduleStatusType; | ||||
import org.eclipse.jgit.submodule.SubmoduleWalk; | import org.eclipse.jgit.submodule.SubmoduleWalk; | ||||
ConfigConstants.CONFIG_BRANCH_SECTION, "test", | ConfigConstants.CONFIG_BRANCH_SECTION, "test", | ||||
ConfigConstants.CONFIG_KEY_REBASE, null)); | ConfigConstants.CONFIG_KEY_REBASE, null)); | ||||
FileBasedConfig userConfig = SystemReader.getInstance().openUserConfig( | |||||
null, git.getRepository().getFS()); | |||||
StoredConfig userConfig = SystemReader.getInstance() | |||||
.getUserConfig(); | |||||
userConfig.setString(ConfigConstants.CONFIG_BRANCH_SECTION, null, | userConfig.setString(ConfigConstants.CONFIG_BRANCH_SECTION, null, | ||||
ConfigConstants.CONFIG_KEY_AUTOSETUPREBASE, | ConfigConstants.CONFIG_KEY_AUTOSETUPREBASE, | ||||
ConfigConstants.CONFIG_KEY_ALWAYS); | ConfigConstants.CONFIG_KEY_ALWAYS); |
try { | try { | ||||
final Repository repo = git.getRepository(); | final Repository repo = git.getRepository(); | ||||
final ObjectId headId = repo.resolve(Constants.HEAD + "^{commit}"); | final ObjectId headId = repo.resolve(Constants.HEAD + "^{commit}"); | ||||
if (headId == null) { | |||||
return ""; | |||||
} | |||||
try (RevWalk rw = new RevWalk(repo)) { | try (RevWalk rw = new RevWalk(repo)) { | ||||
final TreeWalk tw = TreeWalk.forPath(repo, path, | final TreeWalk tw = TreeWalk.forPath(repo, path, | ||||
rw.parseTree(headId)); | rw.parseTree(headId)); | ||||
if (tw == null) { | |||||
return ""; | |||||
} | |||||
return new String(tw.getObjectReader().open(tw.getObjectId(0)) | return new String(tw.getObjectReader().open(tw.getObjectId(0)) | ||||
.getBytes(), UTF_8); | .getBytes(), UTF_8); | ||||
} | } |
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.concurrent.TimeUnit; | import java.util.concurrent.TimeUnit; | ||||
import org.eclipse.jgit.junit.MockSystemReader; | |||||
import org.eclipse.jgit.util.FS; | import org.eclipse.jgit.util.FS; | ||||
import org.eclipse.jgit.util.FS.FileStoreAttributes; | import org.eclipse.jgit.util.FS.FileStoreAttributes; | ||||
import org.eclipse.jgit.util.FileUtils; | import org.eclipse.jgit.util.FileUtils; | ||||
@Before | @Before | ||||
public void setUp() throws Exception { | public void setUp() throws Exception { | ||||
SystemReader.setInstance(new MockSystemReader()); | |||||
trash = Files.createTempDirectory("tmp_"); | trash = Files.createTempDirectory("tmp_"); | ||||
// measure timer resolution before the test to avoid time critical tests | // measure timer resolution before the test to avoid time critical tests | ||||
// are affected by time needed for measurement | // are affected by time needed for measurement |
@Override | @Override | ||||
@Before | @Before | ||||
public void setUp() throws Exception { | public void setUp() throws Exception { | ||||
super.setUp(); | |||||
FileRepository init = createWorkRepository(); | FileRepository init = createWorkRepository(); | ||||
FileBasedConfig cfg = init.getConfig(); | FileBasedConfig cfg = init.getConfig(); | ||||
cfg.setInt("core", null, "repositoryformatversion", 1); | cfg.setInt("core", null, "repositoryformatversion", 1); |
import java.util.StringTokenizer; | import java.util.StringTokenizer; | ||||
import org.eclipse.jgit.errors.ConfigInvalidException; | import org.eclipse.jgit.errors.ConfigInvalidException; | ||||
import org.eclipse.jgit.junit.MockSystemReader; | |||||
import org.eclipse.jgit.util.FS; | import org.eclipse.jgit.util.FS; | ||||
import org.eclipse.jgit.util.FileUtils; | import org.eclipse.jgit.util.FileUtils; | ||||
import org.eclipse.jgit.util.IO; | import org.eclipse.jgit.util.IO; | ||||
import org.eclipse.jgit.util.SystemReader; | |||||
import org.junit.After; | import org.junit.After; | ||||
import org.junit.Before; | import org.junit.Before; | ||||
import org.junit.Test; | import org.junit.Test; | ||||
@Before | @Before | ||||
public void setUp() throws Exception { | public void setUp() throws Exception { | ||||
SystemReader.setInstance(new MockSystemReader()); | |||||
trash = Files.createTempDirectory("tmp_"); | trash = Files.createTempDirectory("tmp_"); | ||||
FS.getFileStoreAttributes(trash.getParent()); | FS.getFileStoreAttributes(trash.getParent()); | ||||
} | } |
import java.util.concurrent.TimeUnit; | import java.util.concurrent.TimeUnit; | ||||
import org.eclipse.jgit.errors.CommandFailedException; | import org.eclipse.jgit.errors.CommandFailedException; | ||||
import org.eclipse.jgit.junit.MockSystemReader; | |||||
import org.eclipse.jgit.junit.RepositoryTestCase; | import org.eclipse.jgit.junit.RepositoryTestCase; | ||||
import org.eclipse.jgit.lib.RepositoryCache; | import org.eclipse.jgit.lib.RepositoryCache; | ||||
import org.junit.After; | import org.junit.After; | ||||
@Before | @Before | ||||
public void setUp() throws Exception { | public void setUp() throws Exception { | ||||
SystemReader.setInstance(new MockSystemReader()); | |||||
trash = File.createTempFile("tmp_", ""); | trash = File.createTempFile("tmp_", ""); | ||||
trash.delete(); | trash.delete(); | ||||
assertTrue("mkdir " + trash, trash.mkdir()); | assertTrue("mkdir " + trash, trash.mkdir()); |
/* | |||||
* Copyright (C) 2019, Vishal Devgire <vishaldevgire@gmail.com> | |||||
* and other copyright owners as documented in the project's IP log. | |||||
* | |||||
* This program and the accompanying materials are made available | |||||
* under the terms of the Eclipse Distribution License v1.0 which | |||||
* accompanies this distribution, is reproduced below, and is | |||||
* available at http://www.eclipse.org/org/documents/edl-v10.php | |||||
* | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or | |||||
* without modification, are permitted provided that the following | |||||
* conditions are met: | |||||
* | |||||
* - Redistributions of source code must retain the above copyright | |||||
* notice, this list of conditions and the following disclaimer. | |||||
* | |||||
* - Redistributions in binary form must reproduce the above | |||||
* copyright notice, this list of conditions and the following | |||||
* disclaimer in the documentation and/or other materials provided | |||||
* with the distribution. | |||||
* | |||||
* - Neither the name of the Eclipse Foundation, Inc. nor the | |||||
* names of its contributors may be used to endorse or promote | |||||
* products derived from this software without specific prior | |||||
* written permission. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | |||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, | |||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||||
*/ | |||||
package org.eclipse.jgit.util; | |||||
import static org.junit.Assert.assertFalse; | |||||
import static org.junit.Assert.assertTrue; | |||||
import java.io.File; | |||||
import java.io.IOException; | |||||
import java.nio.file.Files; | |||||
import java.nio.file.Path; | |||||
import org.eclipse.jgit.junit.MockSystemReader; | |||||
import org.eclipse.jgit.lib.ConfigConstants; | |||||
import org.eclipse.jgit.storage.file.FileBasedConfig; | |||||
import org.junit.After; | |||||
import org.junit.Before; | |||||
import org.junit.Test; | |||||
public class FS_POSIXTest { | |||||
private SystemReader originalSystemReaderInstance; | |||||
private FileBasedConfig systemConfig; | |||||
private FileBasedConfig userConfig; | |||||
private Path tmp; | |||||
@Before | |||||
public void setUp() throws Exception { | |||||
tmp = Files.createTempDirectory("jgit_test_"); | |||||
MockSystemReader mockSystemReader = new MockSystemReader(); | |||||
SystemReader.setInstance(mockSystemReader); | |||||
// Measure timer resolution before the test to avoid time critical tests | |||||
// are affected by time needed for measurement. | |||||
// The MockSystemReader must be configured first since we need to use | |||||
// the same one here | |||||
FS.getFileStoreAttributes(tmp.getParent()); | |||||
systemConfig = new FileBasedConfig( | |||||
new File(tmp.toFile(), "systemgitconfig"), FS.DETECTED); | |||||
userConfig = new FileBasedConfig(systemConfig, | |||||
new File(tmp.toFile(), "usergitconfig"), FS.DETECTED); | |||||
// We have to set autoDetach to false for tests, because tests expect to | |||||
// be able to clean up by recursively removing the repository, and | |||||
// background GC might be in the middle of writing or deleting files, | |||||
// which would disrupt this. | |||||
userConfig.setBoolean(ConfigConstants.CONFIG_GC_SECTION, null, | |||||
ConfigConstants.CONFIG_KEY_AUTODETACH, false); | |||||
userConfig.save(); | |||||
mockSystemReader.setSystemGitConfig(systemConfig); | |||||
mockSystemReader.setUserGitConfig(userConfig); | |||||
originalSystemReaderInstance = SystemReader.getInstance(); | |||||
SystemReader.setInstance(mockSystemReader); | |||||
} | |||||
@After | |||||
public void tearDown() throws IOException { | |||||
SystemReader.setInstance(originalSystemReaderInstance); | |||||
FileUtils.delete(tmp.toFile(), FileUtils.RECURSIVE | FileUtils.RETRY); | |||||
} | |||||
@Test | |||||
public void supportsAtomicCreateNewFile_shouldReturnSupportedAsDefault() { | |||||
assertTrue(new FS_POSIX().supportsAtomicCreateNewFile()); | |||||
} | |||||
@Test | |||||
public void supportsAtomicCreateNewFile_shouldReturnTrueIfFlagIsSetInUserConfig() { | |||||
setAtomicCreateCreationFlag(userConfig, "true"); | |||||
assertTrue(new FS_POSIX().supportsAtomicCreateNewFile()); | |||||
} | |||||
@Test | |||||
public void supportsAtomicCreateNewFile_shouldReturnTrueIfFlagIsSetInSystemConfig() { | |||||
setAtomicCreateCreationFlag(systemConfig, "true"); | |||||
assertTrue(new FS_POSIX().supportsAtomicCreateNewFile()); | |||||
} | |||||
@Test | |||||
public void supportsAtomicCreateNewFile_shouldReturnFalseIfFlagUnsetInUserConfig() { | |||||
setAtomicCreateCreationFlag(userConfig, "false"); | |||||
assertFalse(new FS_POSIX().supportsAtomicCreateNewFile()); | |||||
} | |||||
@Test | |||||
public void supportsAtomicCreateNewFile_shouldReturnFalseIfFlagUnsetInSystemConfig() { | |||||
setAtomicCreateCreationFlag(systemConfig, "false"); | |||||
assertFalse(new FS_POSIX().supportsAtomicCreateNewFile()); | |||||
} | |||||
private void setAtomicCreateCreationFlag(FileBasedConfig config, | |||||
String value) { | |||||
config.setString(ConfigConstants.CONFIG_CORE_SECTION, null, | |||||
ConfigConstants.CONFIG_KEY_SUPPORTSATOMICFILECREATION, value); | |||||
} | |||||
} |
</message_arguments> | </message_arguments> | ||||
</filter> | </filter> | ||||
</resource> | </resource> | ||||
<resource path="src/org/eclipse/jgit/storage/file/FileBasedConfig.java" type="org.eclipse.jgit.storage.file.FileBasedConfig"> | |||||
<filter id="1142947843"> | |||||
<message_arguments> | |||||
<message_argument value="5.1.9"/> | |||||
<message_argument value="load(boolean)"/> | |||||
</message_arguments> | |||||
</filter> | |||||
</resource> | |||||
<resource path="src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java" type="org.eclipse.jgit.treewalk.WorkingTreeIterator"> | <resource path="src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java" type="org.eclipse.jgit.treewalk.WorkingTreeIterator"> | ||||
<filter id="1142947843"> | <filter id="1142947843"> | ||||
<message_arguments> | <message_arguments> | ||||
</message_arguments> | </message_arguments> | ||||
</filter> | </filter> | ||||
</resource> | </resource> | ||||
<resource path="src/org/eclipse/jgit/util/SystemReader.java" type="org.eclipse.jgit.util.SystemReader"> | |||||
<filter id="336695337"> | |||||
<message_arguments> | |||||
<message_argument value="org.eclipse.jgit.util.SystemReader"/> | |||||
<message_argument value="getSystemConfig()"/> | |||||
</message_arguments> | |||||
</filter> | |||||
<filter id="336695337"> | |||||
<message_arguments> | |||||
<message_argument value="org.eclipse.jgit.util.SystemReader"/> | |||||
<message_argument value="getUserConfig()"/> | |||||
</message_arguments> | |||||
</filter> | |||||
<filter id="1142947843"> | |||||
<message_arguments> | |||||
<message_argument value="5.1.9"/> | |||||
<message_argument value="getSystemConfig()"/> | |||||
</message_arguments> | |||||
</filter> | |||||
<filter id="1142947843"> | |||||
<message_arguments> | |||||
<message_argument value="5.1.9"/> | |||||
<message_argument value="getUserConfig()"/> | |||||
</message_arguments> | |||||
</filter> | |||||
</resource> | |||||
</component> | </component> |
archiveFormatAlreadyAbsent=Archive format already absent: {0} | archiveFormatAlreadyAbsent=Archive format already absent: {0} | ||||
archiveFormatAlreadyRegistered=Archive format already registered with different implementation: {0} | archiveFormatAlreadyRegistered=Archive format already registered with different implementation: {0} | ||||
argumentIsNotAValidCommentString=Invalid comment: {0} | argumentIsNotAValidCommentString=Invalid comment: {0} | ||||
assumeAtomicCreateNewFile=Reading option "core.supportsAtomicFileCreation" failed, fallback to default assuming atomic file creation is supported | |||||
atLeastOnePathIsRequired=At least one path is required. | atLeastOnePathIsRequired=At least one path is required. | ||||
atLeastOnePatternIsRequired=At least one pattern is required. | atLeastOnePatternIsRequired=At least one pattern is required. | ||||
atLeastTwoFiltersNeeded=At least two filters needed. | atLeastTwoFiltersNeeded=At least two filters needed. | ||||
expectedReceivedContentType=expected Content-Type {0}; received Content-Type {1} | expectedReceivedContentType=expected Content-Type {0}; received Content-Type {1} | ||||
expectedReportForRefNotReceived={0}: expected report for ref {1} not received | expectedReportForRefNotReceived={0}: expected report for ref {1} not received | ||||
failedAtomicFileCreation=Atomic file creation failed, number of hard links to file {0} was not 2 but {1} | failedAtomicFileCreation=Atomic file creation failed, number of hard links to file {0} was not 2 but {1} | ||||
failedCreateLockFile=Creating lock file {} failed | |||||
failedToDetermineFilterDefinition=An exception occurred while determining filter definitions | failedToDetermineFilterDefinition=An exception occurred while determining filter definitions | ||||
failedUpdatingRefs=failed updating refs | failedUpdatingRefs=failed updating refs | ||||
failureDueToOneOfTheFollowing=Failure due to one of the following: | failureDueToOneOfTheFollowing=Failure due to one of the following: | ||||
localRepository=local repository | localRepository=local repository | ||||
lockCountMustBeGreaterOrEqual1=lockCount must be >= 1 | lockCountMustBeGreaterOrEqual1=lockCount must be >= 1 | ||||
lockError=lock error: {0} | lockError=lock error: {0} | ||||
lockFailedRetry=locking {0} failed after {1} retries | |||||
lockOnNotClosed=Lock on {0} not closed. | lockOnNotClosed=Lock on {0} not closed. | ||||
lockOnNotHeld=Lock on {0} not held. | lockOnNotHeld=Lock on {0} not held. | ||||
malformedpersonIdentString=Malformed PersonIdent string (no < was found): {0} | malformedpersonIdentString=Malformed PersonIdent string (no < was found): {0} | ||||
pushOptionsNotSupported=Push options not supported; received {0} | pushOptionsNotSupported=Push options not supported; received {0} | ||||
rawLogMessageDoesNotParseAsLogEntry=Raw log message does not parse as log entry | rawLogMessageDoesNotParseAsLogEntry=Raw log message does not parse as log entry | ||||
readConfigFailed=Reading config file ''{0}'' failed | readConfigFailed=Reading config file ''{0}'' failed | ||||
readFileStoreAttributesFailed=Reading FileStore attributes from user config failed | |||||
readerIsRequired=Reader is required | readerIsRequired=Reader is required | ||||
readingObjectsFromLocalRepositoryFailed=reading objects from local repository failed: {0} | readingObjectsFromLocalRepositoryFailed=reading objects from local repository failed: {0} | ||||
readLastModifiedFailed=Reading lastModified of {0} failed | readLastModifiedFailed=Reading lastModified of {0} failed | ||||
s3ActionReading=Reading | s3ActionReading=Reading | ||||
s3ActionWriting=Writing | s3ActionWriting=Writing | ||||
searchForReachableBranches=Finding reachable branches | searchForReachableBranches=Finding reachable branches | ||||
saveFileStoreAttributesFailed=Saving measured FileStore attributes to user config failed | |||||
searchForReuse=Finding sources | searchForReuse=Finding sources | ||||
searchForSizes=Getting sizes | searchForSizes=Getting sizes | ||||
secondsAgo={0} seconds ago | secondsAgo={0} seconds ago | ||||
uriNotFound={0} not found | uriNotFound={0} not found | ||||
uriNotFoundWithMessage={0} not found: {1} | uriNotFoundWithMessage={0} not found: {1} | ||||
URINotSupported=URI not supported: {0} | URINotSupported=URI not supported: {0} | ||||
userConfigFileInvalid=User config file {0} invalid {1} | |||||
userConfigInvalid=Git config in the user's home directory {0} is invalid {1} | |||||
validatingGitModules=Validating .gitmodules files | validatingGitModules=Validating .gitmodules files | ||||
walkFailure=Walk failure. | walkFailure=Walk failure. | ||||
wantNoSpaceWithCapabilities=No space between oid and first capability in first want line | wantNoSpaceWithCapabilities=No space between oid and first capability in first want line |
/***/ public String archiveFormatAlreadyAbsent; | /***/ public String archiveFormatAlreadyAbsent; | ||||
/***/ public String archiveFormatAlreadyRegistered; | /***/ public String archiveFormatAlreadyRegistered; | ||||
/***/ public String argumentIsNotAValidCommentString; | /***/ public String argumentIsNotAValidCommentString; | ||||
/***/ public String assumeAtomicCreateNewFile; | |||||
/***/ public String atLeastOnePathIsRequired; | /***/ public String atLeastOnePathIsRequired; | ||||
/***/ public String atLeastOnePatternIsRequired; | /***/ public String atLeastOnePatternIsRequired; | ||||
/***/ public String atLeastTwoFiltersNeeded; | /***/ public String atLeastTwoFiltersNeeded; | ||||
/***/ public String expectedReceivedContentType; | /***/ public String expectedReceivedContentType; | ||||
/***/ public String expectedReportForRefNotReceived; | /***/ public String expectedReportForRefNotReceived; | ||||
/***/ public String failedAtomicFileCreation; | /***/ public String failedAtomicFileCreation; | ||||
/***/ public String failedCreateLockFile; | |||||
/***/ public String failedToDetermineFilterDefinition; | /***/ public String failedToDetermineFilterDefinition; | ||||
/***/ public String failedUpdatingRefs; | /***/ public String failedUpdatingRefs; | ||||
/***/ public String failureDueToOneOfTheFollowing; | /***/ public String failureDueToOneOfTheFollowing; | ||||
/***/ public String localRepository; | /***/ public String localRepository; | ||||
/***/ public String lockCountMustBeGreaterOrEqual1; | /***/ public String lockCountMustBeGreaterOrEqual1; | ||||
/***/ public String lockError; | /***/ public String lockError; | ||||
/***/ public String lockFailedRetry; | |||||
/***/ public String lockOnNotClosed; | /***/ public String lockOnNotClosed; | ||||
/***/ public String lockOnNotHeld; | /***/ public String lockOnNotHeld; | ||||
/***/ public String malformedpersonIdentString; | /***/ public String malformedpersonIdentString; | ||||
/***/ public String pushOptionsNotSupported; | /***/ public String pushOptionsNotSupported; | ||||
/***/ public String rawLogMessageDoesNotParseAsLogEntry; | /***/ public String rawLogMessageDoesNotParseAsLogEntry; | ||||
/***/ public String readConfigFailed; | /***/ public String readConfigFailed; | ||||
/***/ public String readFileStoreAttributesFailed; | |||||
/***/ public String readerIsRequired; | /***/ public String readerIsRequired; | ||||
/***/ public String readingObjectsFromLocalRepositoryFailed; | /***/ public String readingObjectsFromLocalRepositoryFailed; | ||||
/***/ public String readLastModifiedFailed; | /***/ public String readLastModifiedFailed; | ||||
/***/ public String s3ActionDeletion; | /***/ public String s3ActionDeletion; | ||||
/***/ public String s3ActionReading; | /***/ public String s3ActionReading; | ||||
/***/ public String s3ActionWriting; | /***/ public String s3ActionWriting; | ||||
/***/ public String saveFileStoreAttributesFailed; | |||||
/***/ public String searchForReachableBranches; | /***/ public String searchForReachableBranches; | ||||
/***/ public String searchForReuse; | /***/ public String searchForReuse; | ||||
/***/ public String searchForSizes; | /***/ public String searchForSizes; | ||||
/***/ public String uriNotFound; | /***/ public String uriNotFound; | ||||
/***/ public String uriNotFoundWithMessage; | /***/ public String uriNotFoundWithMessage; | ||||
/***/ public String URINotSupported; | /***/ public String URINotSupported; | ||||
/***/ public String userConfigFileInvalid; | |||||
/***/ public String userConfigInvalid; | |||||
/***/ public String validatingGitModules; | /***/ public String validatingGitModules; | ||||
/***/ public String walkFailure; | /***/ public String walkFailure; | ||||
/***/ public String wantNoSpaceWithCapabilities; | /***/ public String wantNoSpaceWithCapabilities; |
import org.eclipse.jgit.lib.RefUpdate; | import org.eclipse.jgit.lib.RefUpdate; | ||||
import org.eclipse.jgit.lib.ReflogReader; | import org.eclipse.jgit.lib.ReflogReader; | ||||
import org.eclipse.jgit.lib.Repository; | import org.eclipse.jgit.lib.Repository; | ||||
import org.eclipse.jgit.lib.StoredConfig; | |||||
import org.eclipse.jgit.storage.file.FileBasedConfig; | import org.eclipse.jgit.storage.file.FileBasedConfig; | ||||
import org.eclipse.jgit.storage.file.FileRepositoryBuilder; | import org.eclipse.jgit.storage.file.FileRepositoryBuilder; | ||||
import org.eclipse.jgit.storage.pack.PackConfig; | import org.eclipse.jgit.storage.pack.PackConfig; | ||||
import org.eclipse.jgit.util.FS; | |||||
import org.eclipse.jgit.util.FileUtils; | import org.eclipse.jgit.util.FileUtils; | ||||
import org.eclipse.jgit.util.IO; | import org.eclipse.jgit.util.IO; | ||||
import org.eclipse.jgit.util.RawParseUtils; | import org.eclipse.jgit.util.RawParseUtils; | ||||
import org.eclipse.jgit.util.StringUtils; | import org.eclipse.jgit.util.StringUtils; | ||||
import org.eclipse.jgit.util.SystemReader; | import org.eclipse.jgit.util.SystemReader; | ||||
import org.slf4j.Logger; | |||||
import org.slf4j.LoggerFactory; | |||||
/** | /** | ||||
* Represents a Git repository. A repository holds all objects and refs used for | * Represents a Git repository. A repository holds all objects and refs used for | ||||
* This implementation only handles a subtly undocumented subset of git features. | * This implementation only handles a subtly undocumented subset of git features. | ||||
*/ | */ | ||||
public class FileRepository extends Repository { | public class FileRepository extends Repository { | ||||
private static final Logger LOG = LoggerFactory | |||||
.getLogger(FileRepository.class); | |||||
private static final String UNNAMED = "Unnamed repository; edit this file to name it for gitweb."; //$NON-NLS-1$ | private static final String UNNAMED = "Unnamed repository; edit this file to name it for gitweb."; //$NON-NLS-1$ | ||||
private final FileBasedConfig systemConfig; | |||||
private final FileBasedConfig userConfig; | |||||
private final FileBasedConfig repoConfig; | private final FileBasedConfig repoConfig; | ||||
private final RefDatabase refs; | private final RefDatabase refs; | ||||
private final ObjectDirectory objectDatabase; | private final ObjectDirectory objectDatabase; | ||||
*/ | */ | ||||
public FileRepository(BaseRepositoryBuilder options) throws IOException { | public FileRepository(BaseRepositoryBuilder options) throws IOException { | ||||
super(options); | super(options); | ||||
if (StringUtils.isEmptyOrNull(SystemReader.getInstance().getenv( | |||||
Constants.GIT_CONFIG_NOSYSTEM_KEY))) | |||||
systemConfig = SystemReader.getInstance().openSystemConfig(null, | |||||
getFS()); | |||||
else | |||||
systemConfig = new FileBasedConfig(null, FS.DETECTED) { | |||||
@Override | |||||
public void load() { | |||||
// empty, do not load | |||||
} | |||||
@Override | |||||
public boolean isOutdated() { | |||||
// regular class would bomb here | |||||
return false; | |||||
} | |||||
}; | |||||
userConfig = SystemReader.getInstance().openUserConfig(systemConfig, | |||||
getFS()); | |||||
StoredConfig userConfig = null; | |||||
try { | |||||
userConfig = SystemReader.getInstance().getUserConfig(); | |||||
} catch (ConfigInvalidException e) { | |||||
LOG.error(e.getMessage(), e); | |||||
throw new IOException(e.getMessage(), e); | |||||
} | |||||
repoConfig = new FileBasedConfig(userConfig, getFS().resolve( | repoConfig = new FileBasedConfig(userConfig, getFS().resolve( | ||||
getDirectory(), Constants.CONFIG), | getDirectory(), Constants.CONFIG), | ||||
getFS()); | getFS()); | ||||
loadSystemConfig(); | |||||
loadUserConfig(); | |||||
loadRepoConfig(); | loadRepoConfig(); | ||||
repoConfig.addChangeListener(this::fireEvent); | repoConfig.addChangeListener(this::fireEvent); | ||||
} | } | ||||
} | } | ||||
private void loadSystemConfig() throws IOException { | |||||
try { | |||||
systemConfig.load(); | |||||
} catch (ConfigInvalidException e) { | |||||
throw new IOException(MessageFormat.format(JGitText | |||||
.get().systemConfigFileInvalid, systemConfig.getFile() | |||||
.getAbsolutePath(), | |||||
e), e); | |||||
} | |||||
} | |||||
private void loadUserConfig() throws IOException { | |||||
try { | |||||
userConfig.load(); | |||||
} catch (ConfigInvalidException e) { | |||||
throw new IOException(MessageFormat.format(JGitText | |||||
.get().userConfigFileInvalid, userConfig.getFile() | |||||
.getAbsolutePath(), | |||||
e), e); | |||||
} | |||||
} | |||||
private void loadRepoConfig() throws IOException { | private void loadRepoConfig() throws IOException { | ||||
try { | try { | ||||
repoConfig.load(); | repoConfig.load(); | ||||
/** {@inheritDoc} */ | /** {@inheritDoc} */ | ||||
@Override | @Override | ||||
public FileBasedConfig getConfig() { | public FileBasedConfig getConfig() { | ||||
if (systemConfig.isOutdated()) { | |||||
try { | |||||
loadSystemConfig(); | |||||
} catch (IOException e) { | |||||
throw new RuntimeException(e); | |||||
} | |||||
} | |||||
if (userConfig.isOutdated()) { | |||||
try { | |||||
loadUserConfig(); | |||||
} catch (IOException e) { | |||||
throw new RuntimeException(e); | |||||
try { | |||||
SystemReader.getInstance().getUserConfig(); | |||||
if (repoConfig.isOutdated()) { | |||||
loadRepoConfig(); | |||||
} | } | ||||
} | |||||
if (repoConfig.isOutdated()) { | |||||
try { | |||||
loadRepoConfig(); | |||||
} catch (IOException e) { | |||||
throw new RuntimeException(e); | |||||
} | |||||
} catch (IOException | ConfigInvalidException e) { | |||||
throw new RuntimeException(e); | |||||
} | } | ||||
return repoConfig; | return repoConfig; | ||||
} | } |
*/ | */ | ||||
public boolean lock() throws IOException { | public boolean lock() throws IOException { | ||||
FileUtils.mkdirs(lck.getParentFile(), true); | FileUtils.mkdirs(lck.getParentFile(), true); | ||||
token = FS.DETECTED.createNewFileAtomic(lck); | |||||
try { | |||||
token = FS.DETECTED.createNewFileAtomic(lck); | |||||
} catch (IOException e) { | |||||
LOG.error(JGitText.get().failedCreateLockFile, lck, e); | |||||
throw e; | |||||
} | |||||
if (token.isCreated()) { | if (token.isCreated()) { | ||||
haveLck = true; | haveLck = true; | ||||
try { | try { |
*/ | */ | ||||
@SuppressWarnings("unchecked") | @SuppressWarnings("unchecked") | ||||
public V get(AnyObjectId toFind) { | public V get(AnyObjectId toFind) { | ||||
if (toFind == null) { | |||||
return null; | |||||
} | |||||
int h = toFind.w1; | int h = toFind.w1; | ||||
V obj = directory[h & mask][h >>> SEGMENT_SHIFT]; | V obj = directory[h & mask][h >>> SEGMENT_SHIFT]; | ||||
for (; obj != null; obj = (V) obj.next) | for (; obj != null; obj = (V) obj.next) |
if (skip != -1) { | if (skip != -1) { | ||||
// try to parse the line as non-comment | // try to parse the line as non-comment | ||||
line = parseLine(buf, skip, lineEnd); | line = parseLine(buf, skip, lineEnd); | ||||
// successfully parsed as non-comment line | |||||
// mark this line as a comment explicitly | |||||
line.setAction(Action.COMMENT); | |||||
// use the read line as comment string | |||||
line.setComment(commentString); | |||||
if (line != null) { | |||||
// successfully parsed as non-comment line | |||||
// mark this line as a comment explicitly | |||||
line.setAction(Action.COMMENT); | |||||
// use the read line as comment string | |||||
line.setComment(commentString); | |||||
} | |||||
} | } | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
// parsing as non-comment line failed | // parsing as non-comment line failed |
*/ | */ | ||||
@Override | @Override | ||||
public void load() throws IOException, ConfigInvalidException { | public void load() throws IOException, ConfigInvalidException { | ||||
load(true); | |||||
} | |||||
/** | |||||
* Load the configuration as a Git text style configuration file. | |||||
* <p> | |||||
* If the file does not exist, this configuration is cleared, and thus | |||||
* behaves the same as though the file exists, but is empty. | |||||
* | |||||
* @param useFileSnapshotWithConfig | |||||
* if {@code true} use the FileSnapshot with config, otherwise | |||||
* use it without config | |||||
* @throws IOException | |||||
* if IO failed | |||||
* @throws ConfigInvalidException | |||||
* if config is invalid | |||||
* @since 5.1.9 | |||||
*/ | |||||
public void load(boolean useFileSnapshotWithConfig) | |||||
throws IOException, ConfigInvalidException { | |||||
final int maxRetries = 5; | final int maxRetries = 5; | ||||
int retryDelayMillis = 20; | int retryDelayMillis = 20; | ||||
int retries = 0; | int retries = 0; | ||||
while (true) { | while (true) { | ||||
final FileSnapshot oldSnapshot = snapshot; | final FileSnapshot oldSnapshot = snapshot; | ||||
final FileSnapshot newSnapshot; | final FileSnapshot newSnapshot; | ||||
if (useFileSnapshotWithConfig) { | |||||
newSnapshot = FileSnapshot.save(getFile()); | |||||
} else { | |||||
// don't use config in this snapshot to avoid endless recursion | |||||
newSnapshot = FileSnapshot.saveNoConfig(getFile()); | |||||
} | |||||
// don't use config in this snapshot to avoid endless recursion | |||||
newSnapshot = FileSnapshot.saveNoConfig(getFile()); | |||||
try { | try { | ||||
final byte[] in = IO.readFully(getFile()); | final byte[] in = IO.readFully(getFile()); | ||||
final ObjectId newHash = hash(in); | final ObjectId newHash = hash(in); |
import org.eclipse.jgit.errors.ConfigInvalidException; | import org.eclipse.jgit.errors.ConfigInvalidException; | ||||
import org.eclipse.jgit.internal.JGitText; | import org.eclipse.jgit.internal.JGitText; | ||||
import org.eclipse.jgit.lib.Config; | import org.eclipse.jgit.lib.Config; | ||||
import org.eclipse.jgit.storage.file.FileBasedConfig; | |||||
import org.eclipse.jgit.util.FS; | |||||
import org.eclipse.jgit.lib.StoredConfig; | |||||
import org.eclipse.jgit.util.StringUtils; | import org.eclipse.jgit.util.StringUtils; | ||||
import org.eclipse.jgit.util.SystemReader; | import org.eclipse.jgit.util.SystemReader; | ||||
import org.slf4j.Logger; | import org.slf4j.Logger; | ||||
* to get the configuration values for | * to get the configuration values for | ||||
*/ | */ | ||||
public HttpConfig(URIish uri) { | public HttpConfig(URIish uri) { | ||||
FileBasedConfig userConfig = SystemReader.getInstance() | |||||
.openUserConfig(null, FS.DETECTED); | |||||
StoredConfig userConfig = null; | |||||
try { | try { | ||||
userConfig.load(); | |||||
userConfig = SystemReader.getInstance().getUserConfig(); | |||||
} catch (IOException | ConfigInvalidException e) { | } catch (IOException | ConfigInvalidException e) { | ||||
// Log it and then work with default values. | // Log it and then work with default values. | ||||
LOG.error(MessageFormat.format(JGitText.get().userConfigFileInvalid, | |||||
userConfig.getFile().getAbsolutePath(), e)); | |||||
LOG.error(e.getMessage(), e); | |||||
init(new Config(), uri); | init(new Config(), uri); | ||||
return; | return; | ||||
} | } |
import org.eclipse.jgit.lib.Repository; | import org.eclipse.jgit.lib.Repository; | ||||
import org.eclipse.jgit.lib.StoredConfig; | import org.eclipse.jgit.lib.StoredConfig; | ||||
import org.eclipse.jgit.lib.SymbolicRef; | import org.eclipse.jgit.lib.SymbolicRef; | ||||
import org.eclipse.jgit.storage.file.FileBasedConfig; | |||||
import org.eclipse.jgit.transport.HttpAuthMethod.Type; | import org.eclipse.jgit.transport.HttpAuthMethod.Type; | ||||
import org.eclipse.jgit.transport.HttpConfig.HttpRedirectMode; | import org.eclipse.jgit.transport.HttpConfig.HttpRedirectMode; | ||||
import org.eclipse.jgit.transport.http.HttpConnection; | import org.eclipse.jgit.transport.http.HttpConnection; | ||||
import org.eclipse.jgit.util.FS; | |||||
import org.eclipse.jgit.util.HttpSupport; | import org.eclipse.jgit.util.HttpSupport; | ||||
import org.eclipse.jgit.util.IO; | import org.eclipse.jgit.util.IO; | ||||
import org.eclipse.jgit.util.RawParseUtils; | import org.eclipse.jgit.util.RawParseUtils; | ||||
} | } | ||||
private void updateSslVerifyUser(boolean value) { | private void updateSslVerifyUser(boolean value) { | ||||
FileBasedConfig userConfig = SystemReader.getInstance() | |||||
.openUserConfig(null, FS.DETECTED); | |||||
StoredConfig userConfig = null; | |||||
try { | try { | ||||
userConfig.load(); | |||||
userConfig = SystemReader.getInstance().getUserConfig(); | |||||
updateSslVerify(userConfig, value); | updateSslVerify(userConfig, value); | ||||
} catch (IOException | ConfigInvalidException e) { | } catch (IOException | ConfigInvalidException e) { | ||||
// Log it, but otherwise ignore here. | // Log it, but otherwise ignore here. | ||||
LOG.error(MessageFormat.format(JGitText.get().userConfigFileInvalid, | |||||
userConfig.getFile().getAbsolutePath(), e)); | |||||
LOG.error(e.getMessage(), e); | |||||
} | } | ||||
} | } | ||||
import org.eclipse.jgit.lib.ConfigConstants; | import org.eclipse.jgit.lib.ConfigConstants; | ||||
import org.eclipse.jgit.lib.Constants; | import org.eclipse.jgit.lib.Constants; | ||||
import org.eclipse.jgit.lib.Repository; | import org.eclipse.jgit.lib.Repository; | ||||
import org.eclipse.jgit.storage.file.FileBasedConfig; | |||||
import org.eclipse.jgit.lib.StoredConfig; | |||||
import org.eclipse.jgit.treewalk.FileTreeIterator.FileEntry; | import org.eclipse.jgit.treewalk.FileTreeIterator.FileEntry; | ||||
import org.eclipse.jgit.treewalk.FileTreeIterator.FileModeStrategy; | import org.eclipse.jgit.treewalk.FileTreeIterator.FileModeStrategy; | ||||
import org.eclipse.jgit.treewalk.WorkingTreeIterator.Entry; | import org.eclipse.jgit.treewalk.WorkingTreeIterator.Entry; | ||||
private static Optional<FileStoreAttributes> readFromConfig( | private static Optional<FileStoreAttributes> readFromConfig( | ||||
FileStore s) { | FileStore s) { | ||||
FileBasedConfig userConfig = SystemReader.getInstance() | |||||
.openUserConfig(null, FS.DETECTED); | |||||
StoredConfig userConfig; | |||||
try { | try { | ||||
userConfig.load(false); | |||||
} catch (IOException e) { | |||||
LOG.error(MessageFormat.format(JGitText.get().readConfigFailed, | |||||
userConfig.getFile().getAbsolutePath()), e); | |||||
} catch (ConfigInvalidException e) { | |||||
LOG.error(MessageFormat.format( | |||||
JGitText.get().repositoryConfigFileInvalid, | |||||
userConfig.getFile().getAbsolutePath(), | |||||
e.getMessage())); | |||||
userConfig = SystemReader.getInstance().getUserConfig(); | |||||
} catch (IOException | ConfigInvalidException e) { | |||||
LOG.error(JGitText.get().readFileStoreAttributesFailed, e); | |||||
return Optional.empty(); | |||||
} | } | ||||
String key = getConfigKey(s); | String key = getConfigKey(s); | ||||
Duration resolution = Duration.ofNanos(userConfig.getTimeUnit( | Duration resolution = Duration.ofNanos(userConfig.getTimeUnit( | ||||
private static void saveToConfig(FileStore s, | private static void saveToConfig(FileStore s, | ||||
FileStoreAttributes c) { | FileStoreAttributes c) { | ||||
FileBasedConfig userConfig = SystemReader.getInstance() | |||||
.openUserConfig(null, FS.DETECTED); | |||||
StoredConfig userConfig; | |||||
try { | |||||
userConfig = SystemReader.getInstance().getUserConfig(); | |||||
} catch (IOException | ConfigInvalidException e) { | |||||
LOG.error(JGitText.get().saveFileStoreAttributesFailed, e); | |||||
return; | |||||
} | |||||
long resolution = c.getFsTimestampResolution().toNanos(); | long resolution = c.getFsTimestampResolution().toNanos(); | ||||
TimeUnit resolutionUnit = getUnit(resolution); | TimeUnit resolutionUnit = getUnit(resolution); | ||||
long resolutionValue = resolutionUnit.convert(resolution, | long resolutionValue = resolutionUnit.convert(resolution, | ||||
String key = getConfigKey(s); | String key = getConfigKey(s); | ||||
while (!succeeded && retries < max_retries) { | while (!succeeded && retries < max_retries) { | ||||
try { | try { | ||||
userConfig.load(false); | |||||
userConfig.load(); | |||||
userConfig.setString( | userConfig.setString( | ||||
ConfigConstants.CONFIG_FILESYSTEM_SECTION, key, | ConfigConstants.CONFIG_FILESYSTEM_SECTION, key, | ||||
ConfigConstants.CONFIG_KEY_TIMESTAMP_RESOLUTION, | ConfigConstants.CONFIG_KEY_TIMESTAMP_RESOLUTION, | ||||
} catch (LockFailedException e) { | } catch (LockFailedException e) { | ||||
// race with another thread, wait a bit and try again | // race with another thread, wait a bit and try again | ||||
try { | try { | ||||
LOG.warn(MessageFormat.format(JGitText.get().cannotLock, | |||||
userConfig.getFile().getAbsolutePath())); | |||||
retries++; | retries++; | ||||
Thread.sleep(20); | |||||
if (retries < max_retries) { | |||||
Thread.sleep(100); | |||||
LOG.debug("locking {} failed, retries {}/{}", //$NON-NLS-1$ | |||||
userConfig, Integer.valueOf(retries), | |||||
Integer.valueOf(max_retries)); | |||||
} else { | |||||
LOG.warn(MessageFormat.format( | |||||
JGitText.get().lockFailedRetry, userConfig, | |||||
Integer.valueOf(retries))); | |||||
} | |||||
} catch (InterruptedException e1) { | } catch (InterruptedException e1) { | ||||
Thread.interrupted(); | |||||
Thread.currentThread().interrupt(); | |||||
break; | |||||
} | } | ||||
} catch (IOException e) { | } catch (IOException e) { | ||||
LOG.error(MessageFormat.format( | LOG.error(MessageFormat.format( | ||||
JGitText.get().cannotSaveConfig, | |||||
userConfig.getFile().getAbsolutePath()), e); | |||||
JGitText.get().cannotSaveConfig, userConfig), e); | |||||
break; | |||||
} catch (ConfigInvalidException e) { | } catch (ConfigInvalidException e) { | ||||
LOG.error(MessageFormat.format( | LOG.error(MessageFormat.format( | ||||
JGitText.get().repositoryConfigFileInvalid, | JGitText.get().repositoryConfigFileInvalid, | ||||
userConfig.getFile().getAbsolutePath(), | |||||
e.getMessage())); | |||||
userConfig, e.getMessage())); | |||||
break; | |||||
} | } | ||||
} | } | ||||
} | } |
*/ | */ | ||||
package org.eclipse.jgit.util; | package org.eclipse.jgit.util; | ||||
import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_CORE_SECTION; | |||||
import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_SUPPORTSATOMICFILECREATION; | |||||
import java.io.BufferedReader; | import java.io.BufferedReader; | ||||
import java.io.File; | import java.io.File; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.io.InputStreamReader; | import java.io.InputStreamReader; | ||||
import java.io.PrintStream; | import java.io.PrintStream; | ||||
import java.nio.charset.Charset; | import java.nio.charset.Charset; | ||||
import java.nio.file.FileAlreadyExistsException; | |||||
import java.nio.file.FileStore; | import java.nio.file.FileStore; | ||||
import java.nio.file.FileSystemException; | import java.nio.file.FileSystemException; | ||||
import java.nio.file.Files; | import java.nio.file.Files; | ||||
import java.nio.file.InvalidPathException; | |||||
import java.nio.file.Path; | import java.nio.file.Path; | ||||
import java.nio.file.Paths; | import java.nio.file.Paths; | ||||
import java.nio.file.attribute.PosixFilePermission; | import java.nio.file.attribute.PosixFilePermission; | ||||
import org.eclipse.jgit.errors.CommandFailedException; | import org.eclipse.jgit.errors.CommandFailedException; | ||||
import org.eclipse.jgit.errors.ConfigInvalidException; | import org.eclipse.jgit.errors.ConfigInvalidException; | ||||
import org.eclipse.jgit.internal.JGitText; | import org.eclipse.jgit.internal.JGitText; | ||||
import org.eclipse.jgit.lib.ConfigConstants; | |||||
import org.eclipse.jgit.lib.Constants; | import org.eclipse.jgit.lib.Constants; | ||||
import org.eclipse.jgit.lib.Repository; | import org.eclipse.jgit.lib.Repository; | ||||
import org.eclipse.jgit.storage.file.FileBasedConfig; | |||||
import org.eclipse.jgit.lib.StoredConfig; | |||||
import org.slf4j.Logger; | import org.slf4j.Logger; | ||||
import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||
private static final Map<FileStore, Boolean> CAN_HARD_LINK = new ConcurrentHashMap<>(); | private static final Map<FileStore, Boolean> CAN_HARD_LINK = new ConcurrentHashMap<>(); | ||||
private volatile AtomicFileCreation supportsAtomicCreateNewFile = AtomicFileCreation.UNDEFINED; | |||||
private volatile AtomicFileCreation supportsAtomicFileCreation = AtomicFileCreation.UNDEFINED; | |||||
private enum AtomicFileCreation { | private enum AtomicFileCreation { | ||||
SUPPORTED, NOT_SUPPORTED, UNDEFINED | SUPPORTED, NOT_SUPPORTED, UNDEFINED | ||||
} | } | ||||
} | } | ||||
private void determineAtomicFileCreationSupport() { | |||||
// @TODO: enhance SystemReader to support this without copying code | |||||
AtomicFileCreation ret = getAtomicFileCreationSupportOption( | |||||
SystemReader.getInstance().openUserConfig(null, this)); | |||||
if (ret == AtomicFileCreation.UNDEFINED | |||||
&& StringUtils.isEmptyOrNull(SystemReader.getInstance() | |||||
.getenv(Constants.GIT_CONFIG_NOSYSTEM_KEY))) { | |||||
ret = getAtomicFileCreationSupportOption( | |||||
SystemReader.getInstance().openSystemConfig(null, this)); | |||||
} | |||||
supportsAtomicCreateNewFile = ret; | |||||
} | |||||
private AtomicFileCreation getAtomicFileCreationSupportOption( | |||||
FileBasedConfig config) { | |||||
try { | |||||
config.load(); | |||||
String value = config.getString(ConfigConstants.CONFIG_CORE_SECTION, | |||||
null, | |||||
ConfigConstants.CONFIG_KEY_SUPPORTSATOMICFILECREATION); | |||||
if (value == null) { | |||||
return AtomicFileCreation.UNDEFINED; | |||||
} | |||||
return StringUtils.toBoolean(value) | |||||
? AtomicFileCreation.SUPPORTED | |||||
: AtomicFileCreation.NOT_SUPPORTED; | |||||
} catch (IOException | ConfigInvalidException e) { | |||||
return AtomicFileCreation.SUPPORTED; | |||||
} | |||||
} | |||||
/** {@inheritDoc} */ | /** {@inheritDoc} */ | ||||
@Override | @Override | ||||
public FS newInstance() { | public FS newInstance() { | ||||
/** {@inheritDoc} */ | /** {@inheritDoc} */ | ||||
@Override | @Override | ||||
public boolean supportsAtomicCreateNewFile() { | public boolean supportsAtomicCreateNewFile() { | ||||
if (supportsAtomicCreateNewFile == AtomicFileCreation.UNDEFINED) { | |||||
determineAtomicFileCreationSupport(); | |||||
if (supportsAtomicFileCreation == AtomicFileCreation.UNDEFINED) { | |||||
try { | |||||
StoredConfig config = SystemReader.getInstance().getUserConfig(); | |||||
String value = config.getString(CONFIG_CORE_SECTION, null, | |||||
CONFIG_KEY_SUPPORTSATOMICFILECREATION); | |||||
if (value != null) { | |||||
supportsAtomicFileCreation = StringUtils.toBoolean(value) | |||||
? AtomicFileCreation.SUPPORTED | |||||
: AtomicFileCreation.NOT_SUPPORTED; | |||||
} else { | |||||
supportsAtomicFileCreation = AtomicFileCreation.SUPPORTED; | |||||
} | |||||
} catch (IOException | ConfigInvalidException e) { | |||||
LOG.warn(JGitText.get().assumeAtomicCreateNewFile, e); | |||||
supportsAtomicFileCreation = AtomicFileCreation.SUPPORTED; | |||||
} | |||||
} | } | ||||
return supportsAtomicCreateNewFile == AtomicFileCreation.SUPPORTED; | |||||
return supportsAtomicFileCreation == AtomicFileCreation.SUPPORTED; | |||||
} | } | ||||
@Override | @Override | ||||
* An implementation of the File#createNewFile() semantics which can create | * An implementation of the File#createNewFile() semantics which can create | ||||
* a unique file atomically also on NFS. If the config option | * a unique file atomically also on NFS. If the config option | ||||
* {@code core.supportsAtomicCreateNewFile = true} (which is the default) | * {@code core.supportsAtomicCreateNewFile = true} (which is the default) | ||||
* then simply File#createNewFile() is called. | |||||
* then simply Files#createFile() is called. | |||||
* | * | ||||
* But if {@code core.supportsAtomicCreateNewFile = false} then after | * But if {@code core.supportsAtomicCreateNewFile = false} then after | ||||
* successful creation of the lock file a hard link to that lock file is | * successful creation of the lock file a hard link to that lock file is | ||||
*/ | */ | ||||
@Override | @Override | ||||
public LockToken createNewFileAtomic(File file) throws IOException { | public LockToken createNewFileAtomic(File file) throws IOException { | ||||
if (!file.createNewFile()) { | |||||
Path path; | |||||
try { | |||||
path = file.toPath(); | |||||
Files.createFile(path); | |||||
} catch (FileAlreadyExistsException | InvalidPathException e) { | |||||
return token(false, null); | return token(false, null); | ||||
} | } | ||||
if (supportsAtomicCreateNewFile()) { | if (supportsAtomicCreateNewFile()) { | ||||
return token(true, null); | return token(true, null); | ||||
} | } | ||||
Path link = null; | Path link = null; | ||||
Path path = file.toPath(); | |||||
FileStore store = null; | FileStore store = null; | ||||
try { | try { | ||||
store = Files.getFileStore(path); | store = Files.getFileStore(path); |
import java.nio.file.Files; | import java.nio.file.Files; | ||||
import java.nio.file.InvalidPathException; | import java.nio.file.InvalidPathException; | ||||
import java.nio.file.LinkOption; | import java.nio.file.LinkOption; | ||||
import java.nio.file.NoSuchFileException; | |||||
import java.nio.file.Path; | import java.nio.file.Path; | ||||
import java.nio.file.StandardCopyOption; | import java.nio.file.StandardCopyOption; | ||||
import java.nio.file.StandardOpenOption; | import java.nio.file.StandardOpenOption; | ||||
try { | try { | ||||
return Files.getLastModifiedTime(path, LinkOption.NOFOLLOW_LINKS) | return Files.getLastModifiedTime(path, LinkOption.NOFOLLOW_LINKS) | ||||
.toInstant(); | .toInstant(); | ||||
} catch (NoSuchFileException e) { | |||||
LOG.debug( | |||||
"Cannot read lastModifiedInstant since path {} does not exist", //$NON-NLS-1$ | |||||
path); | |||||
return Instant.EPOCH; | |||||
} catch (IOException e) { | } catch (IOException e) { | ||||
LOG.error(MessageFormat | LOG.error(MessageFormat | ||||
.format(JGitText.get().readLastModifiedFailed, path)); | |||||
.format(JGitText.get().readLastModifiedFailed, path), e); | |||||
return Instant.ofEpochMilli(path.toFile().lastModified()); | return Instant.ofEpochMilli(path.toFile().lastModified()); | ||||
} | } | ||||
} | } |
package org.eclipse.jgit.util; | package org.eclipse.jgit.util; | ||||
import java.io.File; | import java.io.File; | ||||
import java.io.IOException; | |||||
import java.net.InetAddress; | import java.net.InetAddress; | ||||
import java.net.UnknownHostException; | import java.net.UnknownHostException; | ||||
import java.security.AccessController; | import java.security.AccessController; | ||||
import java.util.Locale; | import java.util.Locale; | ||||
import java.util.TimeZone; | import java.util.TimeZone; | ||||
import org.eclipse.jgit.errors.ConfigInvalidException; | |||||
import org.eclipse.jgit.errors.CorruptObjectException; | import org.eclipse.jgit.errors.CorruptObjectException; | ||||
import org.eclipse.jgit.lib.Config; | import org.eclipse.jgit.lib.Config; | ||||
import org.eclipse.jgit.lib.Constants; | |||||
import org.eclipse.jgit.lib.ObjectChecker; | import org.eclipse.jgit.lib.ObjectChecker; | ||||
import org.eclipse.jgit.lib.StoredConfig; | |||||
import org.eclipse.jgit.storage.file.FileBasedConfig; | import org.eclipse.jgit.storage.file.FileBasedConfig; | ||||
import org.eclipse.jgit.util.time.MonotonicClock; | import org.eclipse.jgit.util.time.MonotonicClock; | ||||
import org.eclipse.jgit.util.time.MonotonicSystemClock; | import org.eclipse.jgit.util.time.MonotonicSystemClock; | ||||
import org.slf4j.Logger; | |||||
import org.slf4j.LoggerFactory; | |||||
/** | /** | ||||
* Interface to read values from the system. | * Interface to read values from the system. | ||||
* </p> | * </p> | ||||
*/ | */ | ||||
public abstract class SystemReader { | public abstract class SystemReader { | ||||
private final static Logger LOG = LoggerFactory | |||||
.getLogger(SystemReader.class); | |||||
private static final SystemReader DEFAULT; | private static final SystemReader DEFAULT; | ||||
private static Boolean isMacOS; | private static Boolean isMacOS; | ||||
private static class Default extends SystemReader { | private static class Default extends SystemReader { | ||||
private volatile String hostname; | private volatile String hostname; | ||||
private volatile FileBasedConfig systemConfig; | |||||
private volatile FileBasedConfig userConfig; | |||||
@Override | @Override | ||||
public String getenv(String variable) { | public String getenv(String variable) { | ||||
return System.getenv(variable); | return System.getenv(variable); | ||||
@Override | @Override | ||||
public FileBasedConfig openSystemConfig(Config parent, FS fs) { | public FileBasedConfig openSystemConfig(Config parent, FS fs) { | ||||
File configFile = fs.getGitSystemConfig(); | |||||
if (configFile == null) { | |||||
return new FileBasedConfig(parent, null, fs) { | |||||
@Override | |||||
public void load() { | |||||
// empty, do not load | |||||
} | |||||
@Override | |||||
public boolean isOutdated() { | |||||
// regular class would bomb here | |||||
return false; | |||||
} | |||||
}; | |||||
if (systemConfig == null) { | |||||
systemConfig = createSystemConfig(parent, fs); | |||||
} | } | ||||
return new FileBasedConfig(parent, configFile, fs); | |||||
return systemConfig; | |||||
} | |||||
protected FileBasedConfig createSystemConfig(Config parent, FS fs) { | |||||
if (StringUtils.isEmptyOrNull(getenv(Constants.GIT_CONFIG_NOSYSTEM_KEY))) { | |||||
File configFile = fs.getGitSystemConfig(); | |||||
if (configFile != null) { | |||||
return new FileBasedConfig(parent, configFile, fs); | |||||
} | |||||
} | |||||
return new FileBasedConfig(null, fs) { | |||||
@Override | |||||
public void load() { | |||||
// empty, do not load | |||||
} | |||||
@Override | |||||
public boolean isOutdated() { | |||||
// regular class would bomb here | |||||
return false; | |||||
} | |||||
}; | |||||
} | } | ||||
@Override | @Override | ||||
public FileBasedConfig openUserConfig(Config parent, FS fs) { | public FileBasedConfig openUserConfig(Config parent, FS fs) { | ||||
final File home = fs.userHome(); | |||||
return new FileBasedConfig(parent, new File(home, ".gitconfig"), fs); //$NON-NLS-1$ | |||||
if (userConfig == null) { | |||||
File home = fs.userHome(); | |||||
userConfig = new FileBasedConfig(parent, | |||||
new File(home, ".gitconfig"), fs); //$NON-NLS-1$ | |||||
} | |||||
return userConfig; | |||||
} | |||||
@Override | |||||
public StoredConfig getSystemConfig() | |||||
throws IOException, ConfigInvalidException { | |||||
if (systemConfig == null) { | |||||
systemConfig = createSystemConfig(null, FS.DETECTED); | |||||
} | |||||
if (systemConfig.isOutdated()) { | |||||
LOG.debug("loading system config {}", systemConfig); //$NON-NLS-1$ | |||||
systemConfig.load(); | |||||
} | |||||
return systemConfig; | |||||
} | |||||
@Override | |||||
public StoredConfig getUserConfig() | |||||
throws IOException, ConfigInvalidException { | |||||
if (userConfig == null) { | |||||
userConfig = openUserConfig(getSystemConfig(), FS.DETECTED); | |||||
} else { | |||||
getSystemConfig(); | |||||
} | |||||
if (userConfig.isOutdated()) { | |||||
LOG.debug("loading user config {}", userConfig); //$NON-NLS-1$ | |||||
userConfig.load(); | |||||
} | |||||
return userConfig; | |||||
} | } | ||||
@Override | @Override | ||||
} | } | ||||
} | } | ||||
private static SystemReader INSTANCE = DEFAULT; | |||||
private static volatile SystemReader INSTANCE = DEFAULT; | |||||
/** | /** | ||||
* Get time since epoch, with up to millisecond resolution. | |||||
* Get the current SystemReader instance | |||||
* | * | ||||
* @return time since epoch, with up to millisecond resolution. | |||||
* @return the current SystemReader instance. | |||||
*/ | */ | ||||
public static SystemReader getInstance() { | public static SystemReader getInstance() { | ||||
return INSTANCE; | return INSTANCE; | ||||
} | } | ||||
/** | /** | ||||
* Set the new instance to use when accessing properties. | |||||
* Set a new SystemReader instance to use when accessing properties. | |||||
* | * | ||||
* @param newReader | * @param newReader | ||||
* the new instance to use when accessing properties, or null for | * the new instance to use when accessing properties, or null for | ||||
public abstract String getProperty(String key); | public abstract String getProperty(String key); | ||||
/** | /** | ||||
* Open the git configuration found in the user home | |||||
* Open the git configuration found in the user home. Use | |||||
* {@link #getUserConfig()} to get the current git configuration in the user | |||||
* home since it manages automatic reloading when the gitconfig file was | |||||
* modified and avoids unnecessary reloads. | |||||
* | * | ||||
* @param parent | * @param parent | ||||
* a config with values not found directly in the returned config | * a config with values not found directly in the returned config | ||||
public abstract FileBasedConfig openUserConfig(Config parent, FS fs); | public abstract FileBasedConfig openUserConfig(Config parent, FS fs); | ||||
/** | /** | ||||
* Open the gitconfig configuration found in the system-wide "etc" directory | |||||
* Open the gitconfig configuration found in the system-wide "etc" | |||||
* directory. Use {@link #getSystemConfig()} to get the current system-wide | |||||
* git configuration since it manages automatic reloading when the gitconfig | |||||
* file was modified and avoids unnecessary reloads. | |||||
* | * | ||||
* @param parent | * @param parent | ||||
* a config with values not found directly in the returned | * a config with values not found directly in the returned | ||||
*/ | */ | ||||
public abstract FileBasedConfig openSystemConfig(Config parent, FS fs); | public abstract FileBasedConfig openSystemConfig(Config parent, FS fs); | ||||
/** | |||||
* Get the git configuration found in the user home. The configuration will | |||||
* be reloaded automatically if the configuration file was modified. Also | |||||
* reloads the system config if the system config file was modified. If the | |||||
* configuration file wasn't modified returns the cached configuration. | |||||
* | |||||
* @return the git configuration found in the user home | |||||
* @throws ConfigInvalidException | |||||
* if configuration is invalid | |||||
* @throws IOException | |||||
* if something went wrong when reading files | |||||
* @since 5.1.9 | |||||
*/ | |||||
public abstract StoredConfig getUserConfig() | |||||
throws IOException, ConfigInvalidException; | |||||
/** | |||||
* Get the gitconfig configuration found in the system-wide "etc" directory. | |||||
* The configuration will be reloaded automatically if the configuration | |||||
* file was modified otherwise returns the cached system level config. | |||||
* | |||||
* @return the gitconfig configuration found in the system-wide "etc" | |||||
* directory | |||||
* @throws ConfigInvalidException | |||||
* if configuration is invalid | |||||
* @throws IOException | |||||
* if something went wrong when reading files | |||||
* @since 5.1.9 | |||||
*/ | |||||
public abstract StoredConfig getSystemConfig() | |||||
throws IOException, ConfigInvalidException; | |||||
/** | /** | ||||
* Get the current system time | * Get the current system time | ||||
* | * |
<slf4j-version>1.7.2</slf4j-version> | <slf4j-version>1.7.2</slf4j-version> | ||||
<log4j-version>1.2.15</log4j-version> | <log4j-version>1.2.15</log4j-version> | ||||
<maven-javadoc-plugin-version>3.1.1</maven-javadoc-plugin-version> | <maven-javadoc-plugin-version>3.1.1</maven-javadoc-plugin-version> | ||||
<tycho-extras-version>1.3.0</tycho-extras-version> | |||||
<tycho-extras-version>1.4.0</tycho-extras-version> | |||||
<gson-version>2.8.2</gson-version> | <gson-version>2.8.2</gson-version> | ||||
<bouncycastle-version>1.61</bouncycastle-version> | <bouncycastle-version>1.61</bouncycastle-version> | ||||
<spotbugs-maven-plugin-version>3.1.12.2</spotbugs-maven-plugin-version> | <spotbugs-maven-plugin-version>3.1.12.2</spotbugs-maven-plugin-version> |